Merged in rtree_support branch

git-svn-id: https://hyracks.googlecode.com/svn/trunk@557 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/InsertPipelineExample.java b/hyracks/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/InsertPipelineExample.java
index 7aeaf77..b994ef8 100644
--- a/hyracks/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/InsertPipelineExample.java
+++ b/hyracks/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/InsertPipelineExample.java
@@ -161,7 +161,7 @@
         // create operator descriptor
         TreeIndexInsertUpdateDeleteOperatorDescriptor primaryInsert = new TreeIndexInsertUpdateDeleteOperatorDescriptor(spec,
                 recDesc, storageManager, treeIndexRegistryProvider, primarySplitProvider, primaryInteriorFrameFactory,
-                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, primaryFieldPermutation,
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, null, primaryFieldPermutation,
                 IndexOp.INSERT, opHelperFactory);
         JobHelper.createPartitionConstraint(spec, primaryInsert, splitNCs);
 
@@ -190,7 +190,7 @@
         // create operator descriptor
         TreeIndexInsertUpdateDeleteOperatorDescriptor secondaryInsert = new TreeIndexInsertUpdateDeleteOperatorDescriptor(spec,
                 recDesc, storageManager, treeIndexRegistryProvider, secondarySplitProvider, secondaryInteriorFrameFactory,
-                secondaryLeafFrameFactory, secondaryTypeTraits, secondaryComparatorFactories,
+                secondaryLeafFrameFactory, secondaryTypeTraits, secondaryComparatorFactories, null,
                 secondaryFieldPermutation, IndexOp.INSERT, opHelperFactory);
         JobHelper.createPartitionConstraint(spec, secondaryInsert, splitNCs);
 
diff --git a/hyracks/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexBulkLoadExample.java b/hyracks/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexBulkLoadExample.java
index 1533714..a0b3fba 100644
--- a/hyracks/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexBulkLoadExample.java
+++ b/hyracks/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexBulkLoadExample.java
@@ -160,7 +160,7 @@
         ITreeIndexOpHelperFactory opHelperFactory = new BTreeOpHelperFactory();
         TreeIndexBulkLoadOperatorDescriptor btreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(spec, storageManager,
                 treeIndexRegistryProvider, btreeSplitProvider, interiorFrameFactory, leafFrameFactory, typeTraits,
-                comparatorFactories, fieldPermutation, 0.7f, opHelperFactory);
+                comparatorFactories, null, fieldPermutation, 0.7f, opHelperFactory);
         JobHelper.createPartitionConstraint(spec, btreeBulkLoad, splitNCs);
 
         // distribute the records from the datagen via hashing to the bulk load
diff --git a/hyracks/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexEnlistFilesExample.java b/hyracks/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexEnlistFilesExample.java
index c991a89..fe1fbb6 100644
--- a/hyracks/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexEnlistFilesExample.java
+++ b/hyracks/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexEnlistFilesExample.java
@@ -113,7 +113,7 @@
         ITreeIndexOpHelperFactory opHelperFactory = new BTreeOpHelperFactory();
         TreeIndexFileEnlistmentOperatorDescriptor fileEnlistmentOp = new TreeIndexFileEnlistmentOperatorDescriptor(spec,
                 recDesc, storageManager, treeIndexRegistryProvider, btreeSplitProvider, interiorFrameFactory,
-                leafFrameFactory, typeTraits, comparatorFactories, opHelperFactory);
+                leafFrameFactory, typeTraits, comparatorFactories, null, opHelperFactory);
         JobHelper.createPartitionConstraint(spec, fileEnlistmentOp, splitNCs);
 
         spec.addRoot(fileEnlistmentOp);
diff --git a/hyracks/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/SecondaryIndexBulkLoadExample.java b/hyracks/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/SecondaryIndexBulkLoadExample.java
index b061811..3805c47 100644
--- a/hyracks/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/SecondaryIndexBulkLoadExample.java
+++ b/hyracks/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/SecondaryIndexBulkLoadExample.java
@@ -160,7 +160,7 @@
         IFileSplitProvider btreeSplitProvider = JobHelper.createFileSplitProvider(splitNCs, options.secondaryBTreeName);
         TreeIndexBulkLoadOperatorDescriptor btreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(spec, storageManager,
                 treeIndexRegistryProvider, btreeSplitProvider, secondaryInteriorFrameFactory, secondaryLeafFrameFactory,
-                secondaryTypeTraits, comparatorFactories, fieldPermutation, 0.7f, opHelperFactory);
+                secondaryTypeTraits, comparatorFactories, null, fieldPermutation, 0.7f, opHelperFactory);
         JobHelper.createPartitionConstraint(spec, btreeBulkLoad, splitNCs);
 
         // connect the ops
diff --git a/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeOperatorsTest.java b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeOperatorsTest.java
deleted file mode 100644
index b4a1d60..0000000
--- a/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeOperatorsTest.java
+++ /dev/null
@@ -1,637 +0,0 @@
-/*
- * Copyright 2009-2010 by The Regents of the University of California
- * Licensed 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 from
- * 
- *     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.
- */
-
-package edu.uci.ics.hyracks.tests.btree;
-
-import java.io.DataOutput;
-import java.io.File;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.Test;
-
-import edu.uci.ics.hyracks.api.constraints.PartitionConstraintHelper;
-import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
-import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
-import edu.uci.ics.hyracks.api.dataflow.value.ITypeTrait;
-import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
-import edu.uci.ics.hyracks.api.dataflow.value.TypeTrait;
-import edu.uci.ics.hyracks.api.io.FileReference;
-import edu.uci.ics.hyracks.api.job.JobSpecification;
-import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
-import edu.uci.ics.hyracks.dataflow.common.data.comparators.UTF8StringBinaryComparatorFactory;
-import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
-import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
-import edu.uci.ics.hyracks.dataflow.common.data.parsers.UTF8StringParserFactory;
-import edu.uci.ics.hyracks.dataflow.std.connectors.OneToOneConnectorDescriptor;
-import edu.uci.ics.hyracks.dataflow.std.file.ConstantFileSplitProvider;
-import edu.uci.ics.hyracks.dataflow.std.file.DelimitedDataTupleParserFactory;
-import edu.uci.ics.hyracks.dataflow.std.file.FileScanOperatorDescriptor;
-import edu.uci.ics.hyracks.dataflow.std.file.FileSplit;
-import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
-import edu.uci.ics.hyracks.dataflow.std.misc.ConstantTupleSourceOperatorDescriptor;
-import edu.uci.ics.hyracks.dataflow.std.misc.NullSinkOperatorDescriptor;
-import edu.uci.ics.hyracks.dataflow.std.misc.PrinterOperatorDescriptor;
-import edu.uci.ics.hyracks.dataflow.std.sort.ExternalSortOperatorDescriptor;
-import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeOpHelperFactory;
-import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeSearchOperatorDescriptor;
-import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMInteriorFrameFactory;
-import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMLeafFrameFactory;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
-import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
-import edu.uci.ics.hyracks.storage.am.common.dataflow.ITreeIndexOpHelperFactory;
-import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexBulkLoadOperatorDescriptor;
-import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexInsertUpdateDeleteOperatorDescriptor;
-import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexStatsOperatorDescriptor;
-import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
-import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleWriterFactory;
-import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
-import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
-import edu.uci.ics.hyracks.test.support.TestStorageManagerInterface;
-import edu.uci.ics.hyracks.test.support.TestTreeIndexRegistryProvider;
-import edu.uci.ics.hyracks.tests.integration.AbstractIntegrationTest;
-
-public class BTreeOperatorsTest extends AbstractIntegrationTest {
-	static {
-		TestStorageManagerComponentHolder.init(8192, 20, 20);
-	}
-
-	private IStorageManagerInterface storageManager = new TestStorageManagerInterface();
-	private IIndexRegistryProvider<ITreeIndex> treeIndexRegistryProvider = new TestTreeIndexRegistryProvider();
-	private ITreeIndexOpHelperFactory opHelperFactory = new BTreeOpHelperFactory();
-
-	private final static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
-			"ddMMyy-hhmmssSS");
-	private final static String sep = System.getProperty("file.separator");
-
-	// field, type and key declarations for primary index
-	private int primaryFieldCount = 6;
-	private ITypeTrait[] primaryTypeTraits = new ITypeTrait[primaryFieldCount];
-	private int primaryKeyFieldCount = 1;
-	private IBinaryComparatorFactory[] primaryComparatorFactories = new IBinaryComparatorFactory[primaryKeyFieldCount];
-	private TypeAwareTupleWriterFactory primaryTupleWriterFactory = new TypeAwareTupleWriterFactory(
-			primaryTypeTraits);
-	private ITreeIndexFrameFactory primaryInteriorFrameFactory = new BTreeNSMInteriorFrameFactory(
-			primaryTupleWriterFactory);
-	private ITreeIndexFrameFactory primaryLeafFrameFactory = new BTreeNSMLeafFrameFactory(
-			primaryTupleWriterFactory);
-
-	private static String primaryBtreeName = "primary"
-			+ simpleDateFormat.format(new Date());
-	private static String primaryFileName = System
-			.getProperty("java.io.tmpdir") + sep + primaryBtreeName;
-
-	private IFileSplitProvider primaryBtreeSplitProvider = new ConstantFileSplitProvider(
-			new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(
-					primaryFileName))) });
-
-	private RecordDescriptor primaryRecDesc = new RecordDescriptor(
-			new ISerializerDeserializer[] {
-					UTF8StringSerializerDeserializer.INSTANCE,
-					UTF8StringSerializerDeserializer.INSTANCE,
-					UTF8StringSerializerDeserializer.INSTANCE,
-					UTF8StringSerializerDeserializer.INSTANCE,
-					UTF8StringSerializerDeserializer.INSTANCE,
-					UTF8StringSerializerDeserializer.INSTANCE });
-
-	// field, type and key declarations for secondary indexes
-	private int secondaryFieldCount = 2;
-	private ITypeTrait[] secondaryTypeTraits = new ITypeTrait[secondaryFieldCount];
-	private int secondaryKeyFieldCount = 2;
-	private IBinaryComparatorFactory[] secondaryComparatorFactories = new IBinaryComparatorFactory[secondaryKeyFieldCount];
-	private TypeAwareTupleWriterFactory secondaryTupleWriterFactory = new TypeAwareTupleWriterFactory(
-			secondaryTypeTraits);
-	private ITreeIndexFrameFactory secondaryInteriorFrameFactory = new BTreeNSMInteriorFrameFactory(
-			secondaryTupleWriterFactory);
-	private ITreeIndexFrameFactory secondaryLeafFrameFactory = new BTreeNSMLeafFrameFactory(
-			secondaryTupleWriterFactory);
-
-	private static String secondaryBtreeName = "secondary"
-			+ simpleDateFormat.format(new Date());
-	private static String secondaryFileName = System
-			.getProperty("java.io.tmpdir") + sep + secondaryBtreeName;
-
-	private IFileSplitProvider secondaryBtreeSplitProvider = new ConstantFileSplitProvider(
-			new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(
-					secondaryFileName))) });
-
-	private RecordDescriptor secondaryRecDesc = new RecordDescriptor(
-			new ISerializerDeserializer[] {
-					UTF8StringSerializerDeserializer.INSTANCE,
-					UTF8StringSerializerDeserializer.INSTANCE });
-
-	@Before
-	public void setup() {
-		// field, type and key declarations for primary index
-		primaryTypeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-		primaryTypeTraits[1] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-		primaryTypeTraits[2] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-		primaryTypeTraits[3] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-		primaryTypeTraits[4] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-		primaryTypeTraits[5] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-		primaryComparatorFactories[0] = UTF8StringBinaryComparatorFactory.INSTANCE;
-
-		// field, type and key declarations for secondary indexes
-		secondaryTypeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-		secondaryTypeTraits[1] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-		secondaryComparatorFactories[0] = UTF8StringBinaryComparatorFactory.INSTANCE;
-		secondaryComparatorFactories[1] = UTF8StringBinaryComparatorFactory.INSTANCE;
-	}
-
-	@Test
-	public void loadPrimaryIndexTest() throws Exception {
-		JobSpecification spec = new JobSpecification();
-
-		FileSplit[] ordersSplits = new FileSplit[] { new FileSplit(NC1_ID,
-				new FileReference(new File("data/tpch0.001/orders-part1.tbl"))) };
-		IFileSplitProvider ordersSplitProvider = new ConstantFileSplitProvider(
-				ordersSplits);
-		RecordDescriptor ordersDesc = new RecordDescriptor(
-				new ISerializerDeserializer[] {
-						UTF8StringSerializerDeserializer.INSTANCE,
-						UTF8StringSerializerDeserializer.INSTANCE,
-						UTF8StringSerializerDeserializer.INSTANCE,
-						UTF8StringSerializerDeserializer.INSTANCE,
-						UTF8StringSerializerDeserializer.INSTANCE,
-						UTF8StringSerializerDeserializer.INSTANCE,
-						UTF8StringSerializerDeserializer.INSTANCE,
-						UTF8StringSerializerDeserializer.INSTANCE,
-						UTF8StringSerializerDeserializer.INSTANCE });
-
-		FileScanOperatorDescriptor ordScanner = new FileScanOperatorDescriptor(
-				spec, ordersSplitProvider, new DelimitedDataTupleParserFactory(
-						new IValueParserFactory[] {
-								UTF8StringParserFactory.INSTANCE,
-								UTF8StringParserFactory.INSTANCE,
-								UTF8StringParserFactory.INSTANCE,
-								UTF8StringParserFactory.INSTANCE,
-								UTF8StringParserFactory.INSTANCE,
-								UTF8StringParserFactory.INSTANCE,
-								UTF8StringParserFactory.INSTANCE,
-								UTF8StringParserFactory.INSTANCE,
-								UTF8StringParserFactory.INSTANCE }, '|'),
-				ordersDesc);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				ordScanner, NC1_ID);
-
-		ExternalSortOperatorDescriptor sorter = new ExternalSortOperatorDescriptor(
-				spec,
-				1000,
-				new int[] { 0 },
-				new IBinaryComparatorFactory[] { UTF8StringBinaryComparatorFactory.INSTANCE },
-				ordersDesc);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, sorter,
-				NC1_ID);
-
-		int[] fieldPermutation = { 0, 1, 2, 4, 5, 7 };
-		TreeIndexBulkLoadOperatorDescriptor primaryBtreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(
-				spec, storageManager, treeIndexRegistryProvider,
-				primaryBtreeSplitProvider, primaryInteriorFrameFactory,
-				primaryLeafFrameFactory, primaryTypeTraits,
-				primaryComparatorFactories, fieldPermutation, 0.7f,
-				opHelperFactory);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				primaryBtreeBulkLoad, NC1_ID);
-
-		spec.connect(new OneToOneConnectorDescriptor(spec), ordScanner, 0,
-				sorter, 0);
-
-		spec.connect(new OneToOneConnectorDescriptor(spec), sorter, 0,
-				primaryBtreeBulkLoad, 0);
-
-		spec.addRoot(primaryBtreeBulkLoad);
-		runTest(spec);
-	}
-
-	@Test
-	public void showPrimaryIndexStats() throws Exception {
-		JobSpecification spec = new JobSpecification();
-
-		TreeIndexStatsOperatorDescriptor primaryStatsOp = new TreeIndexStatsOperatorDescriptor(
-				spec, storageManager, treeIndexRegistryProvider,
-				primaryBtreeSplitProvider, primaryInteriorFrameFactory,
-				primaryLeafFrameFactory, primaryTypeTraits,
-				primaryComparatorFactories, opHelperFactory);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				primaryStatsOp, NC1_ID);
-
-		spec.addRoot(primaryStatsOp);
-		runTest(spec);
-	}
-
-	@Test
-	public void scanPrimaryIndexTest() throws Exception {
-		JobSpecification spec = new JobSpecification();
-
-		// build dummy tuple containing nothing
-		ArrayTupleBuilder tb = new ArrayTupleBuilder(primaryKeyFieldCount * 2);
-		DataOutput dos = tb.getDataOutput();
-
-		tb.reset();
-		UTF8StringSerializerDeserializer.INSTANCE.serialize("0", dos);
-		tb.addFieldEndOffset();
-
-		ISerializerDeserializer[] keyRecDescSers = {
-				UTF8StringSerializerDeserializer.INSTANCE,
-				UTF8StringSerializerDeserializer.INSTANCE };
-		RecordDescriptor keyRecDesc = new RecordDescriptor(keyRecDescSers);
-
-		ConstantTupleSourceOperatorDescriptor keyProviderOp = new ConstantTupleSourceOperatorDescriptor(
-				spec, keyRecDesc, tb.getFieldEndOffsets(), tb.getByteArray(),
-				tb.getSize());
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				keyProviderOp, NC1_ID);
-
-		int[] lowKeyFields = null; // - infinity
-		int[] highKeyFields = null; // + infinity
-
-		BTreeSearchOperatorDescriptor primaryBtreeSearchOp = new BTreeSearchOperatorDescriptor(
-				spec, primaryRecDesc, storageManager,
-				treeIndexRegistryProvider, primaryBtreeSplitProvider,
-				primaryInteriorFrameFactory, primaryLeafFrameFactory,
-				primaryTypeTraits, primaryComparatorFactories, true,
-				lowKeyFields, highKeyFields, true, true, opHelperFactory);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				primaryBtreeSearchOp, NC1_ID);
-
-		PrinterOperatorDescriptor printer = new PrinterOperatorDescriptor(spec);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, printer,
-				NC1_ID);
-
-		spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0,
-				primaryBtreeSearchOp, 0);
-		spec.connect(new OneToOneConnectorDescriptor(spec),
-				primaryBtreeSearchOp, 0, printer, 0);
-
-		spec.addRoot(printer);
-		runTest(spec);
-	}
-
-	@Test
-	public void searchPrimaryIndexTest() throws Exception {
-		JobSpecification spec = new JobSpecification();
-
-		// build tuple containing low and high search key
-		// high key and low key
-		ArrayTupleBuilder tb = new ArrayTupleBuilder(primaryKeyFieldCount * 2);
-		DataOutput dos = tb.getDataOutput();
-
-		tb.reset();
-		// low key
-		UTF8StringSerializerDeserializer.INSTANCE.serialize("100", dos);
-		tb.addFieldEndOffset();
-		// high key
-		UTF8StringSerializerDeserializer.INSTANCE.serialize("200", dos);
-		tb.addFieldEndOffset();
-
-		ISerializerDeserializer[] keyRecDescSers = {
-				UTF8StringSerializerDeserializer.INSTANCE,
-				UTF8StringSerializerDeserializer.INSTANCE };
-		RecordDescriptor keyRecDesc = new RecordDescriptor(keyRecDescSers);
-
-		ConstantTupleSourceOperatorDescriptor keyProviderOp = new ConstantTupleSourceOperatorDescriptor(
-				spec, keyRecDesc, tb.getFieldEndOffsets(), tb.getByteArray(),
-				tb.getSize());
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				keyProviderOp, NC1_ID);
-
-		int[] lowKeyFields = { 0 };
-		int[] highKeyFields = { 1 };
-
-		BTreeSearchOperatorDescriptor primaryBtreeSearchOp = new BTreeSearchOperatorDescriptor(
-				spec, primaryRecDesc, storageManager,
-				treeIndexRegistryProvider, primaryBtreeSplitProvider,
-				primaryInteriorFrameFactory, primaryLeafFrameFactory,
-				primaryTypeTraits, primaryComparatorFactories, true,
-				lowKeyFields, highKeyFields, true, true, opHelperFactory);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				primaryBtreeSearchOp, NC1_ID);
-
-		PrinterOperatorDescriptor printer = new PrinterOperatorDescriptor(spec);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, printer,
-				NC1_ID);
-
-		spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0,
-				primaryBtreeSearchOp, 0);
-		spec.connect(new OneToOneConnectorDescriptor(spec),
-				primaryBtreeSearchOp, 0, printer, 0);
-
-		spec.addRoot(printer);
-		runTest(spec);
-	}
-
-	@Test
-	public void loadSecondaryIndexTest() throws Exception {
-		JobSpecification spec = new JobSpecification();
-
-		// build dummy tuple containing nothing
-		ArrayTupleBuilder tb = new ArrayTupleBuilder(primaryKeyFieldCount * 2);
-		DataOutput dos = tb.getDataOutput();
-
-		tb.reset();
-		UTF8StringSerializerDeserializer.INSTANCE.serialize("0", dos);
-		tb.addFieldEndOffset();
-
-		ISerializerDeserializer[] keyRecDescSers = {
-				UTF8StringSerializerDeserializer.INSTANCE,
-				UTF8StringSerializerDeserializer.INSTANCE };
-		RecordDescriptor keyRecDesc = new RecordDescriptor(keyRecDescSers);
-
-		ConstantTupleSourceOperatorDescriptor keyProviderOp = new ConstantTupleSourceOperatorDescriptor(
-				spec, keyRecDesc, tb.getFieldEndOffsets(), tb.getByteArray(),
-				tb.getSize());
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				keyProviderOp, NC1_ID);
-
-		int[] lowKeyFields = null; // - infinity
-		int[] highKeyFields = null; // + infinity
-
-		// scan primary index
-		BTreeSearchOperatorDescriptor primaryBtreeSearchOp = new BTreeSearchOperatorDescriptor(
-				spec, primaryRecDesc, storageManager,
-				treeIndexRegistryProvider, primaryBtreeSplitProvider,
-				primaryInteriorFrameFactory, primaryLeafFrameFactory,
-				primaryTypeTraits, primaryComparatorFactories, true,
-				lowKeyFields, highKeyFields, true, true, opHelperFactory);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				primaryBtreeSearchOp, NC1_ID);
-
-		// sort based on secondary keys
-		ExternalSortOperatorDescriptor sorter = new ExternalSortOperatorDescriptor(
-				spec,
-				1000,
-				new int[] { 3, 0 },
-				new IBinaryComparatorFactory[] { UTF8StringBinaryComparatorFactory.INSTANCE },
-				primaryRecDesc);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, sorter,
-				NC1_ID);
-
-		// load secondary index
-		int[] fieldPermutation = { 3, 0 };
-		TreeIndexBulkLoadOperatorDescriptor secondaryBtreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(
-				spec, storageManager, treeIndexRegistryProvider,
-				secondaryBtreeSplitProvider, secondaryInteriorFrameFactory,
-				secondaryLeafFrameFactory, secondaryTypeTraits,
-				secondaryComparatorFactories, fieldPermutation, 0.7f,
-				opHelperFactory);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				secondaryBtreeBulkLoad, NC1_ID);
-
-		spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0,
-				primaryBtreeSearchOp, 0);
-		spec.connect(new OneToOneConnectorDescriptor(spec),
-				primaryBtreeSearchOp, 0, sorter, 0);
-		spec.connect(new OneToOneConnectorDescriptor(spec), sorter, 0,
-				secondaryBtreeBulkLoad, 0);
-
-		spec.addRoot(secondaryBtreeBulkLoad);
-		runTest(spec);
-	}
-
-	@Test
-	public void searchSecondaryIndexTest() throws Exception {
-		JobSpecification spec = new JobSpecification();
-
-		// build tuple containing search keys (only use the first key as search
-		// key)
-		ArrayTupleBuilder tb = new ArrayTupleBuilder(secondaryKeyFieldCount);
-		DataOutput dos = tb.getDataOutput();
-
-		tb.reset();
-		// low key
-		UTF8StringSerializerDeserializer.INSTANCE.serialize("1998-07-21", dos);
-		tb.addFieldEndOffset();
-		// high key
-		UTF8StringSerializerDeserializer.INSTANCE.serialize("2000-10-18", dos);
-		tb.addFieldEndOffset();
-
-		ISerializerDeserializer[] keyRecDescSers = {
-				UTF8StringSerializerDeserializer.INSTANCE,
-				UTF8StringSerializerDeserializer.INSTANCE };
-		RecordDescriptor keyRecDesc = new RecordDescriptor(keyRecDescSers);
-
-		ConstantTupleSourceOperatorDescriptor keyProviderOp = new ConstantTupleSourceOperatorDescriptor(
-				spec, keyRecDesc, tb.getFieldEndOffsets(), tb.getByteArray(),
-				tb.getSize());
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				keyProviderOp, NC1_ID);
-
-		int[] secondaryLowKeyFields = { 0 };
-		int[] secondaryHighKeyFields = { 1 };
-
-		// search secondary index
-		BTreeSearchOperatorDescriptor secondaryBtreeSearchOp = new BTreeSearchOperatorDescriptor(
-				spec, secondaryRecDesc, storageManager,
-				treeIndexRegistryProvider, secondaryBtreeSplitProvider,
-				secondaryInteriorFrameFactory, secondaryLeafFrameFactory,
-				secondaryTypeTraits, secondaryComparatorFactories, true,
-				secondaryLowKeyFields, secondaryHighKeyFields, true, true,
-				opHelperFactory);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				secondaryBtreeSearchOp, NC1_ID);
-
-		int[] primaryLowKeyFields = { 1 }; // second field from the tuples
-		// coming from secondary index
-		int[] primaryHighKeyFields = { 1 }; // second field from the tuples
-		// coming from secondary index
-
-		// search primary index
-		BTreeSearchOperatorDescriptor primaryBtreeSearchOp = new BTreeSearchOperatorDescriptor(
-				spec, primaryRecDesc, storageManager,
-				treeIndexRegistryProvider, primaryBtreeSplitProvider,
-				primaryInteriorFrameFactory, primaryLeafFrameFactory,
-				primaryTypeTraits, primaryComparatorFactories, true,
-				primaryLowKeyFields, primaryHighKeyFields, true, true,
-				opHelperFactory);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				primaryBtreeSearchOp, NC1_ID);
-
-		PrinterOperatorDescriptor printer = new PrinterOperatorDescriptor(spec);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, printer,
-				NC1_ID);
-
-		spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0,
-				secondaryBtreeSearchOp, 0);
-		spec.connect(new OneToOneConnectorDescriptor(spec),
-				secondaryBtreeSearchOp, 0, primaryBtreeSearchOp, 0);
-		spec.connect(new OneToOneConnectorDescriptor(spec),
-				primaryBtreeSearchOp, 0, printer, 0);
-
-		spec.addRoot(printer);
-		runTest(spec);
-	}
-
-	@Test
-	public void insertPipelineTest() throws Exception {
-
-		JobSpecification spec = new JobSpecification();
-
-		FileSplit[] ordersSplits = new FileSplit[] { new FileSplit(NC1_ID,
-				new FileReference(new File("data/tpch0.001/orders-part2.tbl"))) };
-		IFileSplitProvider ordersSplitProvider = new ConstantFileSplitProvider(
-				ordersSplits);
-		RecordDescriptor ordersDesc = new RecordDescriptor(
-				new ISerializerDeserializer[] {
-						UTF8StringSerializerDeserializer.INSTANCE,
-						UTF8StringSerializerDeserializer.INSTANCE,
-						UTF8StringSerializerDeserializer.INSTANCE,
-						UTF8StringSerializerDeserializer.INSTANCE,
-						UTF8StringSerializerDeserializer.INSTANCE,
-						UTF8StringSerializerDeserializer.INSTANCE,
-						UTF8StringSerializerDeserializer.INSTANCE,
-						UTF8StringSerializerDeserializer.INSTANCE,
-						UTF8StringSerializerDeserializer.INSTANCE });
-
-		FileScanOperatorDescriptor ordScanner = new FileScanOperatorDescriptor(
-				spec, ordersSplitProvider, new DelimitedDataTupleParserFactory(
-						new IValueParserFactory[] {
-								UTF8StringParserFactory.INSTANCE,
-								UTF8StringParserFactory.INSTANCE,
-								UTF8StringParserFactory.INSTANCE,
-								UTF8StringParserFactory.INSTANCE,
-								UTF8StringParserFactory.INSTANCE,
-								UTF8StringParserFactory.INSTANCE,
-								UTF8StringParserFactory.INSTANCE,
-								UTF8StringParserFactory.INSTANCE,
-								UTF8StringParserFactory.INSTANCE }, '|'),
-				ordersDesc);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				ordScanner, NC1_ID);
-
-		// insert into primary index
-		int[] primaryFieldPermutation = { 0, 1, 2, 4, 5, 7 };
-		TreeIndexInsertUpdateDeleteOperatorDescriptor primaryBtreeInsertOp = new TreeIndexInsertUpdateDeleteOperatorDescriptor(
-				spec, ordersDesc, storageManager, treeIndexRegistryProvider,
-				primaryBtreeSplitProvider, primaryInteriorFrameFactory,
-				primaryLeafFrameFactory, primaryTypeTraits,
-				primaryComparatorFactories, primaryFieldPermutation,
-				IndexOp.INSERT, opHelperFactory);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				primaryBtreeInsertOp, NC1_ID);
-
-		// first secondary index
-		int[] fieldPermutationB = { 4, 0 };
-		TreeIndexInsertUpdateDeleteOperatorDescriptor secondaryInsertOp = new TreeIndexInsertUpdateDeleteOperatorDescriptor(
-				spec, ordersDesc, storageManager, treeIndexRegistryProvider,
-				secondaryBtreeSplitProvider, secondaryInteriorFrameFactory,
-				secondaryLeafFrameFactory, secondaryTypeTraits,
-				secondaryComparatorFactories, fieldPermutationB,
-				IndexOp.INSERT, opHelperFactory);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				secondaryInsertOp, NC1_ID);
-
-		NullSinkOperatorDescriptor nullSink = new NullSinkOperatorDescriptor(
-				spec);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, nullSink,
-				NC1_ID);
-
-		spec.connect(new OneToOneConnectorDescriptor(spec), ordScanner, 0,
-				primaryBtreeInsertOp, 0);
-
-		spec.connect(new OneToOneConnectorDescriptor(spec),
-				primaryBtreeInsertOp, 0, secondaryInsertOp, 0);
-
-		spec.connect(new OneToOneConnectorDescriptor(spec), secondaryInsertOp,
-				0, nullSink, 0);
-
-		spec.addRoot(nullSink);
-		runTest(spec);
-	}
-
-	@Test
-	public void searchUpdatedSecondaryIndexTest() throws Exception {
-		JobSpecification spec = new JobSpecification();
-
-		// build tuple containing search keys (only use the first key as search
-		// key)
-		ArrayTupleBuilder tb = new ArrayTupleBuilder(secondaryKeyFieldCount);
-		DataOutput dos = tb.getDataOutput();
-
-		tb.reset();
-		// low key
-		UTF8StringSerializerDeserializer.INSTANCE.serialize("1998-07-21", dos);
-		tb.addFieldEndOffset();
-		// high key
-		UTF8StringSerializerDeserializer.INSTANCE.serialize("2000-10-18", dos);
-		tb.addFieldEndOffset();
-
-		ISerializerDeserializer[] keyRecDescSers = {
-				UTF8StringSerializerDeserializer.INSTANCE,
-				UTF8StringSerializerDeserializer.INSTANCE };
-		RecordDescriptor keyRecDesc = new RecordDescriptor(keyRecDescSers);
-
-		ConstantTupleSourceOperatorDescriptor keyProviderOp = new ConstantTupleSourceOperatorDescriptor(
-				spec, keyRecDesc, tb.getFieldEndOffsets(), tb.getByteArray(),
-				tb.getSize());
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				keyProviderOp, NC1_ID);
-
-		int[] secondaryLowKeyFields = { 0 };
-		int[] secondaryHighKeyFields = { 1 };
-
-		// search secondary index
-		BTreeSearchOperatorDescriptor secondaryBtreeSearchOp = new BTreeSearchOperatorDescriptor(
-				spec, secondaryRecDesc, storageManager,
-				treeIndexRegistryProvider, secondaryBtreeSplitProvider,
-				secondaryInteriorFrameFactory, secondaryLeafFrameFactory,
-				secondaryTypeTraits, secondaryComparatorFactories, true,
-				secondaryLowKeyFields, secondaryHighKeyFields, true, true,
-				opHelperFactory);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				secondaryBtreeSearchOp, NC1_ID);
-
-		// second field from the tuples coming from secondary index
-		int[] primaryLowKeyFields = { 1 };
-		// second field from the tuples coming from secondary index
-		int[] primaryHighKeyFields = { 1 };
-
-		// search primary index
-		BTreeSearchOperatorDescriptor primaryBtreeSearchOp = new BTreeSearchOperatorDescriptor(
-				spec, primaryRecDesc, storageManager,
-				treeIndexRegistryProvider, primaryBtreeSplitProvider,
-				primaryInteriorFrameFactory, primaryLeafFrameFactory,
-				primaryTypeTraits, primaryComparatorFactories, true,
-				primaryLowKeyFields, primaryHighKeyFields, true, true,
-				opHelperFactory);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
-				primaryBtreeSearchOp, NC1_ID);
-
-		PrinterOperatorDescriptor printer = new PrinterOperatorDescriptor(spec);
-		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, printer,
-				NC1_ID);
-
-		spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0,
-				secondaryBtreeSearchOp, 0);
-		spec.connect(new OneToOneConnectorDescriptor(spec),
-				secondaryBtreeSearchOp, 0, primaryBtreeSearchOp, 0);
-		spec.connect(new OneToOneConnectorDescriptor(spec),
-				primaryBtreeSearchOp, 0, printer, 0);
-
-		spec.addRoot(printer);
-		runTest(spec);
-	}
-
-	@AfterClass
-	public static void cleanup() throws Exception {
-		File primary = new File(primaryFileName);
-		primary.deleteOnExit();
-
-		File secondary = new File(secondaryFileName);
-		secondary.deleteOnExit();
-	}
-}
\ No newline at end of file
diff --git a/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreePrimaryIndexScanOperatorTest.java b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreePrimaryIndexScanOperatorTest.java
new file mode 100644
index 0000000..10a6adb
--- /dev/null
+++ b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreePrimaryIndexScanOperatorTest.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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.
+ */
+
+package edu.uci.ics.hyracks.tests.btree;
+
+import java.io.DataOutput;
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+import edu.uci.ics.hyracks.api.constraints.PartitionConstraintHelper;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTrait;
+import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
+import edu.uci.ics.hyracks.api.dataflow.value.TypeTrait;
+import edu.uci.ics.hyracks.api.io.FileReference;
+import edu.uci.ics.hyracks.api.job.JobSpecification;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
+import edu.uci.ics.hyracks.dataflow.common.data.comparators.UTF8StringBinaryComparatorFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.UTF8StringParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.connectors.OneToOneConnectorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.file.ConstantFileSplitProvider;
+import edu.uci.ics.hyracks.dataflow.std.file.DelimitedDataTupleParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.file.FileScanOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.file.FileSplit;
+import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.dataflow.std.misc.ConstantTupleSourceOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.misc.PrinterOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.sort.ExternalSortOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeOpHelperFactory;
+import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeSearchOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMInteriorFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.ITreeIndexOpHelperFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexBulkLoadOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleWriterFactory;
+import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
+import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
+import edu.uci.ics.hyracks.test.support.TestStorageManagerInterface;
+import edu.uci.ics.hyracks.test.support.TestTreeIndexRegistryProvider;
+import edu.uci.ics.hyracks.tests.integration.AbstractIntegrationTest;
+
+public class BTreePrimaryIndexScanOperatorTest extends AbstractIntegrationTest {
+    static {
+        TestStorageManagerComponentHolder.init(8192, 20, 20);
+    }
+
+    private IStorageManagerInterface storageManager = new TestStorageManagerInterface();
+    private IIndexRegistryProvider<ITreeIndex> treeIndexRegistryProvider = new TestTreeIndexRegistryProvider();
+    private ITreeIndexOpHelperFactory opHelperFactory = new BTreeOpHelperFactory();
+
+    private final static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMyy-hhmmssSS");
+    private final static String sep = System.getProperty("file.separator");
+
+    // field, type and key declarations for primary index
+    private int primaryFieldCount = 6;
+    private ITypeTrait[] primaryTypeTraits = new ITypeTrait[primaryFieldCount];
+    private int primaryKeyFieldCount = 1;
+    private IBinaryComparatorFactory[] primaryComparatorFactories = new IBinaryComparatorFactory[primaryKeyFieldCount];
+    private TypeAwareTupleWriterFactory primaryTupleWriterFactory = new TypeAwareTupleWriterFactory(primaryTypeTraits);
+    private ITreeIndexFrameFactory primaryInteriorFrameFactory = new BTreeNSMInteriorFrameFactory(
+            primaryTupleWriterFactory);
+    private ITreeIndexFrameFactory primaryLeafFrameFactory = new BTreeNSMLeafFrameFactory(primaryTupleWriterFactory);
+
+    private static String primaryBtreeName = "primary" + simpleDateFormat.format(new Date());
+    private static String primaryFileName = System.getProperty("java.io.tmpdir") + sep + primaryBtreeName;
+
+    private IFileSplitProvider primaryBtreeSplitProvider = new ConstantFileSplitProvider(
+            new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(primaryFileName))) });
+
+    private RecordDescriptor primaryRecDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE });
+
+    @Before
+    public void setup() throws Exception {
+        // field, type and key declarations for primary index
+        primaryTypeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[1] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[2] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[3] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[4] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[5] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryComparatorFactories[0] = UTF8StringBinaryComparatorFactory.INSTANCE;
+
+        loadPrimaryIndexTest();
+    }
+
+    public void loadPrimaryIndexTest() throws Exception {
+        JobSpecification spec = new JobSpecification();
+
+        FileSplit[] ordersSplits = new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(
+                "data/tpch0.001/orders-part1.tbl"))) };
+        IFileSplitProvider ordersSplitProvider = new ConstantFileSplitProvider(ordersSplits);
+        RecordDescriptor ordersDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE });
+
+        FileScanOperatorDescriptor ordScanner = new FileScanOperatorDescriptor(spec, ordersSplitProvider,
+                new DelimitedDataTupleParserFactory(new IValueParserFactory[] { UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE }, '|'), ordersDesc);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, ordScanner, NC1_ID);
+
+        ExternalSortOperatorDescriptor sorter = new ExternalSortOperatorDescriptor(spec, 1000, new int[] { 0 },
+                new IBinaryComparatorFactory[] { UTF8StringBinaryComparatorFactory.INSTANCE }, ordersDesc);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, sorter, NC1_ID);
+
+        int[] fieldPermutation = { 0, 1, 2, 4, 5, 7 };
+        TreeIndexBulkLoadOperatorDescriptor primaryBtreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(spec,
+                storageManager, treeIndexRegistryProvider, primaryBtreeSplitProvider, primaryInteriorFrameFactory,
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, null, fieldPermutation, 0.7f,
+                opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryBtreeBulkLoad, NC1_ID);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), ordScanner, 0, sorter, 0);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), sorter, 0, primaryBtreeBulkLoad, 0);
+
+        spec.addRoot(primaryBtreeBulkLoad);
+        runTest(spec);
+    }
+
+    @Test
+    public void scanPrimaryIndexTest() throws Exception {
+        JobSpecification spec = new JobSpecification();
+
+        // build dummy tuple containing nothing
+        ArrayTupleBuilder tb = new ArrayTupleBuilder(primaryKeyFieldCount * 2);
+        DataOutput dos = tb.getDataOutput();
+
+        tb.reset();
+        UTF8StringSerializerDeserializer.INSTANCE.serialize("0", dos);
+        tb.addFieldEndOffset();
+
+        ISerializerDeserializer[] keyRecDescSers = { UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE };
+        RecordDescriptor keyRecDesc = new RecordDescriptor(keyRecDescSers);
+
+        ConstantTupleSourceOperatorDescriptor keyProviderOp = new ConstantTupleSourceOperatorDescriptor(spec,
+                keyRecDesc, tb.getFieldEndOffsets(), tb.getByteArray(), tb.getSize());
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, keyProviderOp, NC1_ID);
+
+        int[] lowKeyFields = null; // - infinity
+        int[] highKeyFields = null; // + infinity
+
+        BTreeSearchOperatorDescriptor primaryBtreeSearchOp = new BTreeSearchOperatorDescriptor(spec, primaryRecDesc,
+                storageManager, treeIndexRegistryProvider, primaryBtreeSplitProvider, primaryInteriorFrameFactory,
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, true, lowKeyFields,
+                highKeyFields, true, true, opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryBtreeSearchOp, NC1_ID);
+
+        PrinterOperatorDescriptor printer = new PrinterOperatorDescriptor(spec);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, printer, NC1_ID);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0, primaryBtreeSearchOp, 0);
+        spec.connect(new OneToOneConnectorDescriptor(spec), primaryBtreeSearchOp, 0, printer, 0);
+
+        spec.addRoot(printer);
+        runTest(spec);
+    }
+
+    @AfterClass
+    public static void cleanup() throws Exception {
+        File primary = new File(primaryFileName);
+        primary.deleteOnExit();
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreePrimaryIndexSearchOperatorTest.java b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreePrimaryIndexSearchOperatorTest.java
new file mode 100644
index 0000000..d6871e8
--- /dev/null
+++ b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreePrimaryIndexSearchOperatorTest.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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.
+ */
+
+package edu.uci.ics.hyracks.tests.btree;
+
+import java.io.DataOutput;
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+import edu.uci.ics.hyracks.api.constraints.PartitionConstraintHelper;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTrait;
+import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
+import edu.uci.ics.hyracks.api.dataflow.value.TypeTrait;
+import edu.uci.ics.hyracks.api.io.FileReference;
+import edu.uci.ics.hyracks.api.job.JobSpecification;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
+import edu.uci.ics.hyracks.dataflow.common.data.comparators.UTF8StringBinaryComparatorFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.UTF8StringParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.connectors.OneToOneConnectorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.file.ConstantFileSplitProvider;
+import edu.uci.ics.hyracks.dataflow.std.file.DelimitedDataTupleParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.file.FileScanOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.file.FileSplit;
+import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.dataflow.std.misc.ConstantTupleSourceOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.misc.PrinterOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.sort.ExternalSortOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeOpHelperFactory;
+import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeSearchOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMInteriorFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.ITreeIndexOpHelperFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexBulkLoadOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleWriterFactory;
+import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
+import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
+import edu.uci.ics.hyracks.test.support.TestStorageManagerInterface;
+import edu.uci.ics.hyracks.test.support.TestTreeIndexRegistryProvider;
+import edu.uci.ics.hyracks.tests.integration.AbstractIntegrationTest;
+
+public class BTreePrimaryIndexSearchOperatorTest extends AbstractIntegrationTest {
+    static {
+        TestStorageManagerComponentHolder.init(8192, 20, 20);
+    }
+
+    private IStorageManagerInterface storageManager = new TestStorageManagerInterface();
+    private IIndexRegistryProvider<ITreeIndex> treeIndexRegistryProvider = new TestTreeIndexRegistryProvider();
+    private ITreeIndexOpHelperFactory opHelperFactory = new BTreeOpHelperFactory();
+
+    private final static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMyy-hhmmssSS");
+    private final static String sep = System.getProperty("file.separator");
+
+    // field, type and key declarations for primary index
+    private int primaryFieldCount = 6;
+    private ITypeTrait[] primaryTypeTraits = new ITypeTrait[primaryFieldCount];
+    private int primaryKeyFieldCount = 1;
+    private IBinaryComparatorFactory[] primaryComparatorFactories = new IBinaryComparatorFactory[primaryKeyFieldCount];
+    private TypeAwareTupleWriterFactory primaryTupleWriterFactory = new TypeAwareTupleWriterFactory(primaryTypeTraits);
+    private ITreeIndexFrameFactory primaryInteriorFrameFactory = new BTreeNSMInteriorFrameFactory(
+            primaryTupleWriterFactory);
+    private ITreeIndexFrameFactory primaryLeafFrameFactory = new BTreeNSMLeafFrameFactory(primaryTupleWriterFactory);
+
+    private static String primaryBtreeName = "primary" + simpleDateFormat.format(new Date());
+    private static String primaryFileName = System.getProperty("java.io.tmpdir") + sep + primaryBtreeName;
+
+    private IFileSplitProvider primaryBtreeSplitProvider = new ConstantFileSplitProvider(
+            new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(primaryFileName))) });
+
+    private RecordDescriptor primaryRecDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE });
+
+    @Before
+    public void setup() throws Exception {
+        // field, type and key declarations for primary index
+        primaryTypeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[1] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[2] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[3] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[4] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[5] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryComparatorFactories[0] = UTF8StringBinaryComparatorFactory.INSTANCE;
+
+        loadPrimaryIndexTest();
+    }
+
+    public void loadPrimaryIndexTest() throws Exception {
+        JobSpecification spec = new JobSpecification();
+
+        FileSplit[] ordersSplits = new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(
+                "data/tpch0.001/orders-part1.tbl"))) };
+        IFileSplitProvider ordersSplitProvider = new ConstantFileSplitProvider(ordersSplits);
+        RecordDescriptor ordersDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE });
+
+        FileScanOperatorDescriptor ordScanner = new FileScanOperatorDescriptor(spec, ordersSplitProvider,
+                new DelimitedDataTupleParserFactory(new IValueParserFactory[] { UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE }, '|'), ordersDesc);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, ordScanner, NC1_ID);
+
+        ExternalSortOperatorDescriptor sorter = new ExternalSortOperatorDescriptor(spec, 1000, new int[] { 0 },
+                new IBinaryComparatorFactory[] { UTF8StringBinaryComparatorFactory.INSTANCE }, ordersDesc);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, sorter, NC1_ID);
+
+        int[] fieldPermutation = { 0, 1, 2, 4, 5, 7 };
+        TreeIndexBulkLoadOperatorDescriptor primaryBtreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(spec,
+                storageManager, treeIndexRegistryProvider, primaryBtreeSplitProvider, primaryInteriorFrameFactory,
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, null, fieldPermutation, 0.7f,
+                opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryBtreeBulkLoad, NC1_ID);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), ordScanner, 0, sorter, 0);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), sorter, 0, primaryBtreeBulkLoad, 0);
+
+        spec.addRoot(primaryBtreeBulkLoad);
+        runTest(spec);
+    }
+
+    @Test
+    public void searchPrimaryIndexTest() throws Exception {
+        JobSpecification spec = new JobSpecification();
+
+        // build tuple containing low and high search key
+        // high key and low key
+        ArrayTupleBuilder tb = new ArrayTupleBuilder(primaryKeyFieldCount * 2);
+        DataOutput dos = tb.getDataOutput();
+
+        tb.reset();
+        // low key
+        UTF8StringSerializerDeserializer.INSTANCE.serialize("100", dos);
+        tb.addFieldEndOffset();
+        // high key
+        UTF8StringSerializerDeserializer.INSTANCE.serialize("200", dos);
+        tb.addFieldEndOffset();
+
+        ISerializerDeserializer[] keyRecDescSers = { UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE };
+        RecordDescriptor keyRecDesc = new RecordDescriptor(keyRecDescSers);
+
+        ConstantTupleSourceOperatorDescriptor keyProviderOp = new ConstantTupleSourceOperatorDescriptor(spec,
+                keyRecDesc, tb.getFieldEndOffsets(), tb.getByteArray(), tb.getSize());
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, keyProviderOp, NC1_ID);
+
+        int[] lowKeyFields = { 0 };
+        int[] highKeyFields = { 1 };
+
+        BTreeSearchOperatorDescriptor primaryBtreeSearchOp = new BTreeSearchOperatorDescriptor(spec, primaryRecDesc,
+                storageManager, treeIndexRegistryProvider, primaryBtreeSplitProvider, primaryInteriorFrameFactory,
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, true, lowKeyFields,
+                highKeyFields, true, true, opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryBtreeSearchOp, NC1_ID);
+
+        PrinterOperatorDescriptor printer = new PrinterOperatorDescriptor(spec);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, printer, NC1_ID);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0, primaryBtreeSearchOp, 0);
+        spec.connect(new OneToOneConnectorDescriptor(spec), primaryBtreeSearchOp, 0, printer, 0);
+
+        spec.addRoot(printer);
+        runTest(spec);
+    }
+
+    @AfterClass
+    public static void cleanup() throws Exception {
+        File primary = new File(primaryFileName);
+        primary.deleteOnExit();
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreePrimaryIndexStatsOperatorTest.java b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreePrimaryIndexStatsOperatorTest.java
new file mode 100644
index 0000000..fa66d7b
--- /dev/null
+++ b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreePrimaryIndexStatsOperatorTest.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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.
+ */
+
+package edu.uci.ics.hyracks.tests.btree;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+import edu.uci.ics.hyracks.api.constraints.PartitionConstraintHelper;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTrait;
+import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
+import edu.uci.ics.hyracks.api.dataflow.value.TypeTrait;
+import edu.uci.ics.hyracks.api.io.FileReference;
+import edu.uci.ics.hyracks.api.job.JobSpecification;
+import edu.uci.ics.hyracks.dataflow.common.data.comparators.UTF8StringBinaryComparatorFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.UTF8StringParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.connectors.OneToOneConnectorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.file.ConstantFileSplitProvider;
+import edu.uci.ics.hyracks.dataflow.std.file.DelimitedDataTupleParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.file.FileScanOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.file.FileSplit;
+import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.dataflow.std.sort.ExternalSortOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeOpHelperFactory;
+import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMInteriorFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.ITreeIndexOpHelperFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexBulkLoadOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexStatsOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleWriterFactory;
+import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
+import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
+import edu.uci.ics.hyracks.test.support.TestStorageManagerInterface;
+import edu.uci.ics.hyracks.test.support.TestTreeIndexRegistryProvider;
+import edu.uci.ics.hyracks.tests.integration.AbstractIntegrationTest;
+
+public class BTreePrimaryIndexStatsOperatorTest extends AbstractIntegrationTest {
+    static {
+        TestStorageManagerComponentHolder.init(8192, 20, 20);
+    }
+
+    private IStorageManagerInterface storageManager = new TestStorageManagerInterface();
+    private IIndexRegistryProvider<ITreeIndex> treeIndexRegistryProvider = new TestTreeIndexRegistryProvider();
+    private ITreeIndexOpHelperFactory opHelperFactory = new BTreeOpHelperFactory();
+
+    private final static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMyy-hhmmssSS");
+    private final static String sep = System.getProperty("file.separator");
+
+    // field, type and key declarations for primary index
+    private int primaryFieldCount = 6;
+    private ITypeTrait[] primaryTypeTraits = new ITypeTrait[primaryFieldCount];
+    private int primaryKeyFieldCount = 1;
+    private IBinaryComparatorFactory[] primaryComparatorFactories = new IBinaryComparatorFactory[primaryKeyFieldCount];
+    private TypeAwareTupleWriterFactory primaryTupleWriterFactory = new TypeAwareTupleWriterFactory(primaryTypeTraits);
+    private ITreeIndexFrameFactory primaryInteriorFrameFactory = new BTreeNSMInteriorFrameFactory(
+            primaryTupleWriterFactory);
+    private ITreeIndexFrameFactory primaryLeafFrameFactory = new BTreeNSMLeafFrameFactory(primaryTupleWriterFactory);
+
+    private static String primaryBtreeName = "primary" + simpleDateFormat.format(new Date());
+    private static String primaryFileName = System.getProperty("java.io.tmpdir") + sep + primaryBtreeName;
+
+    private IFileSplitProvider primaryBtreeSplitProvider = new ConstantFileSplitProvider(
+            new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(primaryFileName))) });
+
+    private RecordDescriptor primaryRecDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE });
+
+    @Before
+    public void setup() throws Exception {
+        // field, type and key declarations for primary index
+        primaryTypeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[1] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[2] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[3] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[4] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[5] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryComparatorFactories[0] = UTF8StringBinaryComparatorFactory.INSTANCE;
+
+        loadPrimaryIndexTest();
+    }
+
+    public void loadPrimaryIndexTest() throws Exception {
+        JobSpecification spec = new JobSpecification();
+
+        FileSplit[] ordersSplits = new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(
+                "data/tpch0.001/orders-part1.tbl"))) };
+        IFileSplitProvider ordersSplitProvider = new ConstantFileSplitProvider(ordersSplits);
+        RecordDescriptor ordersDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE });
+
+        FileScanOperatorDescriptor ordScanner = new FileScanOperatorDescriptor(spec, ordersSplitProvider,
+                new DelimitedDataTupleParserFactory(new IValueParserFactory[] { UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE }, '|'), ordersDesc);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, ordScanner, NC1_ID);
+
+        ExternalSortOperatorDescriptor sorter = new ExternalSortOperatorDescriptor(spec, 1000, new int[] { 0 },
+                new IBinaryComparatorFactory[] { UTF8StringBinaryComparatorFactory.INSTANCE }, ordersDesc);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, sorter, NC1_ID);
+
+        int[] fieldPermutation = { 0, 1, 2, 4, 5, 7 };
+        TreeIndexBulkLoadOperatorDescriptor primaryBtreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(spec,
+                storageManager, treeIndexRegistryProvider, primaryBtreeSplitProvider, primaryInteriorFrameFactory,
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, null, fieldPermutation, 0.7f,
+                opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryBtreeBulkLoad, NC1_ID);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), ordScanner, 0, sorter, 0);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), sorter, 0, primaryBtreeBulkLoad, 0);
+
+        spec.addRoot(primaryBtreeBulkLoad);
+        runTest(spec);
+    }
+
+    @Test
+    public void showPrimaryIndexStats() throws Exception {
+        JobSpecification spec = new JobSpecification();
+
+        TreeIndexStatsOperatorDescriptor primaryStatsOp = new TreeIndexStatsOperatorDescriptor(spec, storageManager,
+                treeIndexRegistryProvider, primaryBtreeSplitProvider, primaryInteriorFrameFactory,
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryStatsOp, NC1_ID);
+
+        spec.addRoot(primaryStatsOp);
+        runTest(spec);
+    }
+
+    @AfterClass
+    public static void cleanup() throws Exception {
+        File primary = new File(primaryFileName);
+        primary.deleteOnExit();
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeSecondaryIndexInsertOperatorTest.java b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeSecondaryIndexInsertOperatorTest.java
new file mode 100644
index 0000000..b070952
--- /dev/null
+++ b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeSecondaryIndexInsertOperatorTest.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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.
+ */
+
+package edu.uci.ics.hyracks.tests.btree;
+
+import java.io.DataOutput;
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+import edu.uci.ics.hyracks.api.constraints.PartitionConstraintHelper;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTrait;
+import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
+import edu.uci.ics.hyracks.api.dataflow.value.TypeTrait;
+import edu.uci.ics.hyracks.api.io.FileReference;
+import edu.uci.ics.hyracks.api.job.JobSpecification;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
+import edu.uci.ics.hyracks.dataflow.common.data.comparators.UTF8StringBinaryComparatorFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.UTF8StringParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.connectors.OneToOneConnectorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.file.ConstantFileSplitProvider;
+import edu.uci.ics.hyracks.dataflow.std.file.DelimitedDataTupleParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.file.FileScanOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.file.FileSplit;
+import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.dataflow.std.misc.ConstantTupleSourceOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.misc.NullSinkOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.misc.PrinterOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.sort.ExternalSortOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeOpHelperFactory;
+import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeSearchOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMInteriorFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.ITreeIndexOpHelperFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexBulkLoadOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexInsertUpdateDeleteOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
+import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleWriterFactory;
+import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
+import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
+import edu.uci.ics.hyracks.test.support.TestStorageManagerInterface;
+import edu.uci.ics.hyracks.test.support.TestTreeIndexRegistryProvider;
+import edu.uci.ics.hyracks.tests.integration.AbstractIntegrationTest;
+
+public class BTreeSecondaryIndexInsertOperatorTest extends AbstractIntegrationTest {
+    static {
+        TestStorageManagerComponentHolder.init(8192, 20, 20);
+    }
+
+    private IStorageManagerInterface storageManager = new TestStorageManagerInterface();
+    private IIndexRegistryProvider<ITreeIndex> treeIndexRegistryProvider = new TestTreeIndexRegistryProvider();
+    private ITreeIndexOpHelperFactory opHelperFactory = new BTreeOpHelperFactory();
+
+    private final static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMyy-hhmmssSS");
+    private final static String sep = System.getProperty("file.separator");
+
+    // field, type and key declarations for primary index
+    private int primaryFieldCount = 6;
+    private ITypeTrait[] primaryTypeTraits = new ITypeTrait[primaryFieldCount];
+    private int primaryKeyFieldCount = 1;
+    private IBinaryComparatorFactory[] primaryComparatorFactories = new IBinaryComparatorFactory[primaryKeyFieldCount];
+    private TypeAwareTupleWriterFactory primaryTupleWriterFactory = new TypeAwareTupleWriterFactory(primaryTypeTraits);
+    private ITreeIndexFrameFactory primaryInteriorFrameFactory = new BTreeNSMInteriorFrameFactory(
+            primaryTupleWriterFactory);
+    private ITreeIndexFrameFactory primaryLeafFrameFactory = new BTreeNSMLeafFrameFactory(primaryTupleWriterFactory);
+
+    private static String primaryBtreeName = "primary" + simpleDateFormat.format(new Date());
+    private static String primaryFileName = System.getProperty("java.io.tmpdir") + sep + primaryBtreeName;
+
+    private IFileSplitProvider primaryBtreeSplitProvider = new ConstantFileSplitProvider(
+            new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(primaryFileName))) });
+
+    private RecordDescriptor primaryRecDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE });
+
+    // field, type and key declarations for secondary indexes
+    private int secondaryFieldCount = 2;
+    private ITypeTrait[] secondaryTypeTraits = new ITypeTrait[secondaryFieldCount];
+    private int secondaryKeyFieldCount = 2;
+    private IBinaryComparatorFactory[] secondaryComparatorFactories = new IBinaryComparatorFactory[secondaryKeyFieldCount];
+    private TypeAwareTupleWriterFactory secondaryTupleWriterFactory = new TypeAwareTupleWriterFactory(
+            secondaryTypeTraits);
+    private ITreeIndexFrameFactory secondaryInteriorFrameFactory = new BTreeNSMInteriorFrameFactory(
+            secondaryTupleWriterFactory);
+    private ITreeIndexFrameFactory secondaryLeafFrameFactory = new BTreeNSMLeafFrameFactory(secondaryTupleWriterFactory);
+
+    private static String secondaryBtreeName = "secondary" + simpleDateFormat.format(new Date());
+    private static String secondaryFileName = System.getProperty("java.io.tmpdir") + sep + secondaryBtreeName;
+
+    private IFileSplitProvider secondaryBtreeSplitProvider = new ConstantFileSplitProvider(
+            new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(secondaryFileName))) });
+
+    private RecordDescriptor secondaryRecDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE });
+
+    @Before
+    public void setup() throws Exception {
+        // field, type and key declarations for primary index
+        primaryTypeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[1] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[2] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[3] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[4] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[5] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryComparatorFactories[0] = UTF8StringBinaryComparatorFactory.INSTANCE;
+
+        // field, type and key declarations for secondary indexes
+        secondaryTypeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        secondaryTypeTraits[1] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        secondaryComparatorFactories[0] = UTF8StringBinaryComparatorFactory.INSTANCE;
+        secondaryComparatorFactories[1] = UTF8StringBinaryComparatorFactory.INSTANCE;
+
+        loadPrimaryIndexTest();
+        loadSecondaryIndexTest();
+        insertPipelineTest();
+    }
+
+    public void loadPrimaryIndexTest() throws Exception {
+        JobSpecification spec = new JobSpecification();
+
+        FileSplit[] ordersSplits = new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(
+                "data/tpch0.001/orders-part1.tbl"))) };
+        IFileSplitProvider ordersSplitProvider = new ConstantFileSplitProvider(ordersSplits);
+        RecordDescriptor ordersDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE });
+
+        FileScanOperatorDescriptor ordScanner = new FileScanOperatorDescriptor(spec, ordersSplitProvider,
+                new DelimitedDataTupleParserFactory(new IValueParserFactory[] { UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE }, '|'), ordersDesc);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, ordScanner, NC1_ID);
+
+        ExternalSortOperatorDescriptor sorter = new ExternalSortOperatorDescriptor(spec, 1000, new int[] { 0 },
+                new IBinaryComparatorFactory[] { UTF8StringBinaryComparatorFactory.INSTANCE }, ordersDesc);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, sorter, NC1_ID);
+
+        int[] fieldPermutation = { 0, 1, 2, 4, 5, 7 };
+        TreeIndexBulkLoadOperatorDescriptor primaryBtreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(spec,
+                storageManager, treeIndexRegistryProvider, primaryBtreeSplitProvider, primaryInteriorFrameFactory,
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, null, fieldPermutation, 0.7f,
+                opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryBtreeBulkLoad, NC1_ID);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), ordScanner, 0, sorter, 0);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), sorter, 0, primaryBtreeBulkLoad, 0);
+
+        spec.addRoot(primaryBtreeBulkLoad);
+        runTest(spec);
+    }
+
+    public void loadSecondaryIndexTest() throws Exception {
+        JobSpecification spec = new JobSpecification();
+
+        // build dummy tuple containing nothing
+        ArrayTupleBuilder tb = new ArrayTupleBuilder(primaryKeyFieldCount * 2);
+        DataOutput dos = tb.getDataOutput();
+
+        tb.reset();
+        UTF8StringSerializerDeserializer.INSTANCE.serialize("0", dos);
+        tb.addFieldEndOffset();
+
+        ISerializerDeserializer[] keyRecDescSers = { UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE };
+        RecordDescriptor keyRecDesc = new RecordDescriptor(keyRecDescSers);
+
+        ConstantTupleSourceOperatorDescriptor keyProviderOp = new ConstantTupleSourceOperatorDescriptor(spec,
+                keyRecDesc, tb.getFieldEndOffsets(), tb.getByteArray(), tb.getSize());
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, keyProviderOp, NC1_ID);
+
+        int[] lowKeyFields = null; // - infinity
+        int[] highKeyFields = null; // + infinity
+
+        // scan primary index
+        BTreeSearchOperatorDescriptor primaryBtreeSearchOp = new BTreeSearchOperatorDescriptor(spec, primaryRecDesc,
+                storageManager, treeIndexRegistryProvider, primaryBtreeSplitProvider, primaryInteriorFrameFactory,
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, true, lowKeyFields,
+                highKeyFields, true, true, opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryBtreeSearchOp, NC1_ID);
+
+        // sort based on secondary keys
+        ExternalSortOperatorDescriptor sorter = new ExternalSortOperatorDescriptor(spec, 1000, new int[] { 3, 0 },
+                new IBinaryComparatorFactory[] { UTF8StringBinaryComparatorFactory.INSTANCE }, primaryRecDesc);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, sorter, NC1_ID);
+
+        // load secondary index
+        int[] fieldPermutation = { 3, 0 };
+        TreeIndexBulkLoadOperatorDescriptor secondaryBtreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(spec,
+                storageManager, treeIndexRegistryProvider, secondaryBtreeSplitProvider, secondaryInteriorFrameFactory,
+                secondaryLeafFrameFactory, secondaryTypeTraits, secondaryComparatorFactories, null, fieldPermutation,
+                0.7f, opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, secondaryBtreeBulkLoad, NC1_ID);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0, primaryBtreeSearchOp, 0);
+        spec.connect(new OneToOneConnectorDescriptor(spec), primaryBtreeSearchOp, 0, sorter, 0);
+        spec.connect(new OneToOneConnectorDescriptor(spec), sorter, 0, secondaryBtreeBulkLoad, 0);
+
+        spec.addRoot(secondaryBtreeBulkLoad);
+        runTest(spec);
+    }
+
+    public void insertPipelineTest() throws Exception {
+
+        JobSpecification spec = new JobSpecification();
+
+        FileSplit[] ordersSplits = new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(
+                "data/tpch0.001/orders-part2.tbl"))) };
+        IFileSplitProvider ordersSplitProvider = new ConstantFileSplitProvider(ordersSplits);
+        RecordDescriptor ordersDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE });
+
+        FileScanOperatorDescriptor ordScanner = new FileScanOperatorDescriptor(spec, ordersSplitProvider,
+                new DelimitedDataTupleParserFactory(new IValueParserFactory[] { UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE }, '|'), ordersDesc);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, ordScanner, NC1_ID);
+
+        // insert into primary index
+        int[] primaryFieldPermutation = { 0, 1, 2, 4, 5, 7 };
+        TreeIndexInsertUpdateDeleteOperatorDescriptor primaryBtreeInsertOp = new TreeIndexInsertUpdateDeleteOperatorDescriptor(
+                spec, ordersDesc, storageManager, treeIndexRegistryProvider, primaryBtreeSplitProvider,
+                primaryInteriorFrameFactory, primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories,
+                null, primaryFieldPermutation, IndexOp.INSERT, opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryBtreeInsertOp, NC1_ID);
+
+        // first secondary index
+        int[] fieldPermutationB = { 4, 0 };
+        TreeIndexInsertUpdateDeleteOperatorDescriptor secondaryInsertOp = new TreeIndexInsertUpdateDeleteOperatorDescriptor(
+                spec, ordersDesc, storageManager, treeIndexRegistryProvider, secondaryBtreeSplitProvider,
+                secondaryInteriorFrameFactory, secondaryLeafFrameFactory, secondaryTypeTraits,
+                secondaryComparatorFactories, null, fieldPermutationB, IndexOp.INSERT, opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, secondaryInsertOp, NC1_ID);
+
+        NullSinkOperatorDescriptor nullSink = new NullSinkOperatorDescriptor(spec);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, nullSink, NC1_ID);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), ordScanner, 0, primaryBtreeInsertOp, 0);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), primaryBtreeInsertOp, 0, secondaryInsertOp, 0);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), secondaryInsertOp, 0, nullSink, 0);
+
+        spec.addRoot(nullSink);
+        runTest(spec);
+    }
+
+    @Test
+    public void searchUpdatedSecondaryIndexTest() throws Exception {
+        JobSpecification spec = new JobSpecification();
+
+        // build tuple containing search keys (only use the first key as search
+        // key)
+        ArrayTupleBuilder tb = new ArrayTupleBuilder(secondaryKeyFieldCount);
+        DataOutput dos = tb.getDataOutput();
+
+        tb.reset();
+        // low key
+        UTF8StringSerializerDeserializer.INSTANCE.serialize("1998-07-21", dos);
+        tb.addFieldEndOffset();
+        // high key
+        UTF8StringSerializerDeserializer.INSTANCE.serialize("2000-10-18", dos);
+        tb.addFieldEndOffset();
+
+        ISerializerDeserializer[] keyRecDescSers = { UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE };
+        RecordDescriptor keyRecDesc = new RecordDescriptor(keyRecDescSers);
+
+        ConstantTupleSourceOperatorDescriptor keyProviderOp = new ConstantTupleSourceOperatorDescriptor(spec,
+                keyRecDesc, tb.getFieldEndOffsets(), tb.getByteArray(), tb.getSize());
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, keyProviderOp, NC1_ID);
+
+        int[] secondaryLowKeyFields = { 0 };
+        int[] secondaryHighKeyFields = { 1 };
+
+        // search secondary index
+        BTreeSearchOperatorDescriptor secondaryBtreeSearchOp = new BTreeSearchOperatorDescriptor(spec,
+                secondaryRecDesc, storageManager, treeIndexRegistryProvider, secondaryBtreeSplitProvider,
+                secondaryInteriorFrameFactory, secondaryLeafFrameFactory, secondaryTypeTraits,
+                secondaryComparatorFactories, true, secondaryLowKeyFields, secondaryHighKeyFields, true, true,
+                opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, secondaryBtreeSearchOp, NC1_ID);
+
+        // second field from the tuples coming from secondary index
+        int[] primaryLowKeyFields = { 1 };
+        // second field from the tuples coming from secondary index
+        int[] primaryHighKeyFields = { 1 };
+
+        // search primary index
+        BTreeSearchOperatorDescriptor primaryBtreeSearchOp = new BTreeSearchOperatorDescriptor(spec, primaryRecDesc,
+                storageManager, treeIndexRegistryProvider, primaryBtreeSplitProvider, primaryInteriorFrameFactory,
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, true, primaryLowKeyFields,
+                primaryHighKeyFields, true, true, opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryBtreeSearchOp, NC1_ID);
+
+        PrinterOperatorDescriptor printer = new PrinterOperatorDescriptor(spec);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, printer, NC1_ID);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0, secondaryBtreeSearchOp, 0);
+        spec.connect(new OneToOneConnectorDescriptor(spec), secondaryBtreeSearchOp, 0, primaryBtreeSearchOp, 0);
+        spec.connect(new OneToOneConnectorDescriptor(spec), primaryBtreeSearchOp, 0, printer, 0);
+
+        spec.addRoot(printer);
+        runTest(spec);
+    }
+
+    @AfterClass
+    public static void cleanup() throws Exception {
+        File primary = new File(primaryFileName);
+        primary.deleteOnExit();
+
+        File secondary = new File(secondaryFileName);
+        secondary.deleteOnExit();
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeSecondaryIndexSearchOperatorTest.java b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeSecondaryIndexSearchOperatorTest.java
new file mode 100644
index 0000000..093d737
--- /dev/null
+++ b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeSecondaryIndexSearchOperatorTest.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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.
+ */
+
+package edu.uci.ics.hyracks.tests.btree;
+
+import java.io.DataOutput;
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+import edu.uci.ics.hyracks.api.constraints.PartitionConstraintHelper;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTrait;
+import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
+import edu.uci.ics.hyracks.api.dataflow.value.TypeTrait;
+import edu.uci.ics.hyracks.api.io.FileReference;
+import edu.uci.ics.hyracks.api.job.JobSpecification;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
+import edu.uci.ics.hyracks.dataflow.common.data.comparators.UTF8StringBinaryComparatorFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.UTF8StringParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.connectors.OneToOneConnectorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.file.ConstantFileSplitProvider;
+import edu.uci.ics.hyracks.dataflow.std.file.DelimitedDataTupleParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.file.FileScanOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.file.FileSplit;
+import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.dataflow.std.misc.ConstantTupleSourceOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.misc.PrinterOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.sort.ExternalSortOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeOpHelperFactory;
+import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeSearchOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMInteriorFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.ITreeIndexOpHelperFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexBulkLoadOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleWriterFactory;
+import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
+import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
+import edu.uci.ics.hyracks.test.support.TestStorageManagerInterface;
+import edu.uci.ics.hyracks.test.support.TestTreeIndexRegistryProvider;
+import edu.uci.ics.hyracks.tests.integration.AbstractIntegrationTest;
+
+public class BTreeSecondaryIndexSearchOperatorTest extends AbstractIntegrationTest {
+    static {
+        TestStorageManagerComponentHolder.init(8192, 20, 20);
+    }
+
+    private IStorageManagerInterface storageManager = new TestStorageManagerInterface();
+    private IIndexRegistryProvider<ITreeIndex> treeIndexRegistryProvider = new TestTreeIndexRegistryProvider();
+    private ITreeIndexOpHelperFactory opHelperFactory = new BTreeOpHelperFactory();
+
+    private final static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMyy-hhmmssSS");
+    private final static String sep = System.getProperty("file.separator");
+
+    // field, type and key declarations for primary index
+    private int primaryFieldCount = 6;
+    private ITypeTrait[] primaryTypeTraits = new ITypeTrait[primaryFieldCount];
+    private int primaryKeyFieldCount = 1;
+    private IBinaryComparatorFactory[] primaryComparatorFactories = new IBinaryComparatorFactory[primaryKeyFieldCount];
+    private TypeAwareTupleWriterFactory primaryTupleWriterFactory = new TypeAwareTupleWriterFactory(primaryTypeTraits);
+    private ITreeIndexFrameFactory primaryInteriorFrameFactory = new BTreeNSMInteriorFrameFactory(
+            primaryTupleWriterFactory);
+    private ITreeIndexFrameFactory primaryLeafFrameFactory = new BTreeNSMLeafFrameFactory(primaryTupleWriterFactory);
+
+    private static String primaryBtreeName = "primary" + simpleDateFormat.format(new Date());
+    private static String primaryFileName = System.getProperty("java.io.tmpdir") + sep + primaryBtreeName;
+
+    private IFileSplitProvider primaryBtreeSplitProvider = new ConstantFileSplitProvider(
+            new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(primaryFileName))) });
+
+    private RecordDescriptor primaryRecDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE });
+
+    // field, type and key declarations for secondary indexes
+    private int secondaryFieldCount = 2;
+    private ITypeTrait[] secondaryTypeTraits = new ITypeTrait[secondaryFieldCount];
+    private int secondaryKeyFieldCount = 2;
+    private IBinaryComparatorFactory[] secondaryComparatorFactories = new IBinaryComparatorFactory[secondaryKeyFieldCount];
+    private TypeAwareTupleWriterFactory secondaryTupleWriterFactory = new TypeAwareTupleWriterFactory(
+            secondaryTypeTraits);
+    private ITreeIndexFrameFactory secondaryInteriorFrameFactory = new BTreeNSMInteriorFrameFactory(
+            secondaryTupleWriterFactory);
+    private ITreeIndexFrameFactory secondaryLeafFrameFactory = new BTreeNSMLeafFrameFactory(secondaryTupleWriterFactory);
+
+    private static String secondaryBtreeName = "secondary" + simpleDateFormat.format(new Date());
+    private static String secondaryFileName = System.getProperty("java.io.tmpdir") + sep + secondaryBtreeName;
+
+    private IFileSplitProvider secondaryBtreeSplitProvider = new ConstantFileSplitProvider(
+            new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(secondaryFileName))) });
+
+    private RecordDescriptor secondaryRecDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE });
+
+    @Before
+    public void setup() throws Exception {
+        // field, type and key declarations for primary index
+        primaryTypeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[1] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[2] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[3] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[4] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryTypeTraits[5] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryComparatorFactories[0] = UTF8StringBinaryComparatorFactory.INSTANCE;
+
+        // field, type and key declarations for secondary indexes
+        secondaryTypeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        secondaryTypeTraits[1] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        secondaryComparatorFactories[0] = UTF8StringBinaryComparatorFactory.INSTANCE;
+        secondaryComparatorFactories[1] = UTF8StringBinaryComparatorFactory.INSTANCE;
+
+        loadPrimaryIndexTest();
+        loadSecondaryIndexTest();
+    }
+
+    public void loadPrimaryIndexTest() throws Exception {
+        JobSpecification spec = new JobSpecification();
+
+        FileSplit[] ordersSplits = new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(
+                "data/tpch0.001/orders-part1.tbl"))) };
+        IFileSplitProvider ordersSplitProvider = new ConstantFileSplitProvider(ordersSplits);
+        RecordDescriptor ordersDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE });
+
+        FileScanOperatorDescriptor ordScanner = new FileScanOperatorDescriptor(spec, ordersSplitProvider,
+                new DelimitedDataTupleParserFactory(new IValueParserFactory[] { UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE, UTF8StringParserFactory.INSTANCE }, '|'), ordersDesc);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, ordScanner, NC1_ID);
+
+        ExternalSortOperatorDescriptor sorter = new ExternalSortOperatorDescriptor(spec, 1000, new int[] { 0 },
+                new IBinaryComparatorFactory[] { UTF8StringBinaryComparatorFactory.INSTANCE }, ordersDesc);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, sorter, NC1_ID);
+
+        int[] fieldPermutation = { 0, 1, 2, 4, 5, 7 };
+        TreeIndexBulkLoadOperatorDescriptor primaryBtreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(spec,
+                storageManager, treeIndexRegistryProvider, primaryBtreeSplitProvider, primaryInteriorFrameFactory,
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, null, fieldPermutation, 0.7f,
+                opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryBtreeBulkLoad, NC1_ID);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), ordScanner, 0, sorter, 0);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), sorter, 0, primaryBtreeBulkLoad, 0);
+
+        spec.addRoot(primaryBtreeBulkLoad);
+        runTest(spec);
+    }
+
+    public void loadSecondaryIndexTest() throws Exception {
+        JobSpecification spec = new JobSpecification();
+
+        // build dummy tuple containing nothing
+        ArrayTupleBuilder tb = new ArrayTupleBuilder(primaryKeyFieldCount * 2);
+        DataOutput dos = tb.getDataOutput();
+
+        tb.reset();
+        UTF8StringSerializerDeserializer.INSTANCE.serialize("0", dos);
+        tb.addFieldEndOffset();
+
+        ISerializerDeserializer[] keyRecDescSers = { UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE };
+        RecordDescriptor keyRecDesc = new RecordDescriptor(keyRecDescSers);
+
+        ConstantTupleSourceOperatorDescriptor keyProviderOp = new ConstantTupleSourceOperatorDescriptor(spec,
+                keyRecDesc, tb.getFieldEndOffsets(), tb.getByteArray(), tb.getSize());
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, keyProviderOp, NC1_ID);
+
+        int[] lowKeyFields = null; // - infinity
+        int[] highKeyFields = null; // + infinity
+
+        // scan primary index
+        BTreeSearchOperatorDescriptor primaryBtreeSearchOp = new BTreeSearchOperatorDescriptor(spec, primaryRecDesc,
+                storageManager, treeIndexRegistryProvider, primaryBtreeSplitProvider, primaryInteriorFrameFactory,
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, true, lowKeyFields,
+                highKeyFields, true, true, opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryBtreeSearchOp, NC1_ID);
+
+        // sort based on secondary keys
+        ExternalSortOperatorDescriptor sorter = new ExternalSortOperatorDescriptor(spec, 1000, new int[] { 3, 0 },
+                new IBinaryComparatorFactory[] { UTF8StringBinaryComparatorFactory.INSTANCE }, primaryRecDesc);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, sorter, NC1_ID);
+
+        // load secondary index
+        int[] fieldPermutation = { 3, 0 };
+        TreeIndexBulkLoadOperatorDescriptor secondaryBtreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(spec,
+                storageManager, treeIndexRegistryProvider, secondaryBtreeSplitProvider, secondaryInteriorFrameFactory,
+                secondaryLeafFrameFactory, secondaryTypeTraits, secondaryComparatorFactories, null, fieldPermutation,
+                0.7f, opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, secondaryBtreeBulkLoad, NC1_ID);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0, primaryBtreeSearchOp, 0);
+        spec.connect(new OneToOneConnectorDescriptor(spec), primaryBtreeSearchOp, 0, sorter, 0);
+        spec.connect(new OneToOneConnectorDescriptor(spec), sorter, 0, secondaryBtreeBulkLoad, 0);
+
+        spec.addRoot(secondaryBtreeBulkLoad);
+        runTest(spec);
+    }
+
+    @Test
+    public void searchSecondaryIndexTest() throws Exception {
+        JobSpecification spec = new JobSpecification();
+
+        // build tuple containing search keys (only use the first key as search
+        // key)
+        ArrayTupleBuilder tb = new ArrayTupleBuilder(secondaryKeyFieldCount);
+        DataOutput dos = tb.getDataOutput();
+
+        tb.reset();
+        // low key
+        UTF8StringSerializerDeserializer.INSTANCE.serialize("1998-07-21", dos);
+        tb.addFieldEndOffset();
+        // high key
+        UTF8StringSerializerDeserializer.INSTANCE.serialize("2000-10-18", dos);
+        tb.addFieldEndOffset();
+
+        ISerializerDeserializer[] keyRecDescSers = { UTF8StringSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE };
+        RecordDescriptor keyRecDesc = new RecordDescriptor(keyRecDescSers);
+
+        ConstantTupleSourceOperatorDescriptor keyProviderOp = new ConstantTupleSourceOperatorDescriptor(spec,
+                keyRecDesc, tb.getFieldEndOffsets(), tb.getByteArray(), tb.getSize());
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, keyProviderOp, NC1_ID);
+
+        int[] secondaryLowKeyFields = { 0 };
+        int[] secondaryHighKeyFields = { 1 };
+
+        // search secondary index
+        BTreeSearchOperatorDescriptor secondaryBtreeSearchOp = new BTreeSearchOperatorDescriptor(spec,
+                secondaryRecDesc, storageManager, treeIndexRegistryProvider, secondaryBtreeSplitProvider,
+                secondaryInteriorFrameFactory, secondaryLeafFrameFactory, secondaryTypeTraits,
+                secondaryComparatorFactories, true, secondaryLowKeyFields, secondaryHighKeyFields, true, true,
+                opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, secondaryBtreeSearchOp, NC1_ID);
+
+        int[] primaryLowKeyFields = { 1 }; // second field from the tuples
+        // coming from secondary index
+        int[] primaryHighKeyFields = { 1 }; // second field from the tuples
+        // coming from secondary index
+
+        // search primary index
+        BTreeSearchOperatorDescriptor primaryBtreeSearchOp = new BTreeSearchOperatorDescriptor(spec, primaryRecDesc,
+                storageManager, treeIndexRegistryProvider, primaryBtreeSplitProvider, primaryInteriorFrameFactory,
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, true, primaryLowKeyFields,
+                primaryHighKeyFields, true, true, opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryBtreeSearchOp, NC1_ID);
+
+        PrinterOperatorDescriptor printer = new PrinterOperatorDescriptor(spec);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, printer, NC1_ID);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0, secondaryBtreeSearchOp, 0);
+        spec.connect(new OneToOneConnectorDescriptor(spec), secondaryBtreeSearchOp, 0, primaryBtreeSearchOp, 0);
+        spec.connect(new OneToOneConnectorDescriptor(spec), primaryBtreeSearchOp, 0, printer, 0);
+
+        spec.addRoot(printer);
+        runTest(spec);
+    }
+
+    @AfterClass
+    public static void cleanup() throws Exception {
+        File primary = new File(primaryFileName);
+        primary.deleteOnExit();
+
+        File secondary = new File(secondaryFileName);
+        secondary.deleteOnExit();
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/rtree/RTreePrimaryIndexSearchOperatorTest.java b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/rtree/RTreePrimaryIndexSearchOperatorTest.java
new file mode 100644
index 0000000..67e5934
--- /dev/null
+++ b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/rtree/RTreePrimaryIndexSearchOperatorTest.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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.
+ */
+
+package edu.uci.ics.hyracks.tests.rtree;
+
+import java.io.DataOutput;
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+import edu.uci.ics.hyracks.api.constraints.PartitionConstraintHelper;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTrait;
+import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
+import edu.uci.ics.hyracks.api.dataflow.value.TypeTrait;
+import edu.uci.ics.hyracks.api.io.FileReference;
+import edu.uci.ics.hyracks.api.job.JobSpecification;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
+import edu.uci.ics.hyracks.dataflow.common.data.comparators.DoubleBinaryComparatorFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.DoubleParserFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.UTF8StringParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.connectors.OneToOneConnectorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.file.ConstantFileSplitProvider;
+import edu.uci.ics.hyracks.dataflow.std.file.DelimitedDataTupleParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.file.FileScanOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.file.FileSplit;
+import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.dataflow.std.misc.ConstantTupleSourceOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.misc.PrinterOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.ITreeIndexOpHelperFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexBulkLoadOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.rtree.dataflow.RTreeOpHelperFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.dataflow.RTreeSearchOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMInteriorFrameFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.DoublePrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.tuples.RTreeTypeAwareTupleWriterFactory;
+import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
+import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
+import edu.uci.ics.hyracks.test.support.TestStorageManagerInterface;
+import edu.uci.ics.hyracks.test.support.TestTreeIndexRegistryProvider;
+import edu.uci.ics.hyracks.tests.integration.AbstractIntegrationTest;
+
+public class RTreePrimaryIndexSearchOperatorTest extends AbstractIntegrationTest {
+    static {
+        TestStorageManagerComponentHolder.init(8192, 20, 20);
+    }
+
+    private IStorageManagerInterface storageManager = new TestStorageManagerInterface();
+    private IIndexRegistryProvider<ITreeIndex> treeIndexRegistryProvider = new TestTreeIndexRegistryProvider();
+    private ITreeIndexOpHelperFactory opHelperFactory = new RTreeOpHelperFactory();
+
+    private final static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMyy-hhmmssSS");
+    private final static String sep = System.getProperty("file.separator");
+
+    // field, type and key declarations for primary R-tree index
+    private int primaryFieldCount = 5;
+    private int primaryKeyFieldCount = 4;
+    private ITypeTrait[] primaryTypeTraits = new ITypeTrait[primaryFieldCount];
+    private IBinaryComparatorFactory[] primaryComparatorFactories = new IBinaryComparatorFactory[primaryKeyFieldCount];
+    private IPrimitiveValueProviderFactory[] primaryValueProviderFactories = new IPrimitiveValueProviderFactory[primaryKeyFieldCount];
+
+    private RTreeTypeAwareTupleWriterFactory primaryTupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(
+            primaryTypeTraits);
+
+    private RecordDescriptor primaryRecDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+            DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+            DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+            UTF8StringSerializerDeserializer.INSTANCE });
+
+    private ITreeIndexFrameFactory primaryInteriorFrameFactory = new RTreeNSMInteriorFrameFactory(
+            primaryTupleWriterFactory, primaryKeyFieldCount);
+    private ITreeIndexFrameFactory primaryLeafFrameFactory = new RTreeNSMLeafFrameFactory(primaryTupleWriterFactory,
+            primaryKeyFieldCount);
+
+    private static String primaryRTreeName = "primary" + simpleDateFormat.format(new Date());
+    private static String primaryFileName = System.getProperty("java.io.tmpdir") + sep + primaryRTreeName;
+
+    private IFileSplitProvider primaryRTreeSplitProvider = new ConstantFileSplitProvider(
+            new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(primaryFileName))) });
+
+    @Before
+    public void setup() throws Exception {
+        // field, type and key declarations for primary R-tree index
+        primaryTypeTraits[0] = new TypeTrait(8);
+        primaryTypeTraits[1] = new TypeTrait(8);
+        primaryTypeTraits[2] = new TypeTrait(8);
+        primaryTypeTraits[3] = new TypeTrait(8);
+        primaryTypeTraits[4] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryComparatorFactories[0] = DoubleBinaryComparatorFactory.INSTANCE;
+        primaryComparatorFactories[1] = primaryComparatorFactories[0];
+        primaryComparatorFactories[2] = primaryComparatorFactories[0];
+        primaryComparatorFactories[3] = primaryComparatorFactories[0];
+        primaryValueProviderFactories[0] = DoublePrimitiveValueProviderFactory.INSTANCE;
+        primaryValueProviderFactories[1] = primaryValueProviderFactories[0];
+        primaryValueProviderFactories[2] = primaryValueProviderFactories[0];
+        primaryValueProviderFactories[3] = primaryValueProviderFactories[0];
+
+        loadPrimaryIndexTest();
+    }
+
+    public void loadPrimaryIndexTest() throws Exception {
+        JobSpecification spec = new JobSpecification();
+
+        FileSplit[] objectsSplits = new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(
+                "data/spatial.txt"))) };
+        IFileSplitProvider objectsSplitProvider = new ConstantFileSplitProvider(objectsSplits);
+        RecordDescriptor objectsDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+                DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+                DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE });
+
+        FileScanOperatorDescriptor objScanner = new FileScanOperatorDescriptor(spec, objectsSplitProvider,
+                new DelimitedDataTupleParserFactory(new IValueParserFactory[] { DoubleParserFactory.INSTANCE,
+                        DoubleParserFactory.INSTANCE, DoubleParserFactory.INSTANCE, DoubleParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE }, '|'), objectsDesc);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, objScanner, NC1_ID);
+
+        int[] fieldPermutation = { 0, 1, 2, 3, 4 };
+        TreeIndexBulkLoadOperatorDescriptor primaryRTreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(spec,
+                storageManager, treeIndexRegistryProvider, primaryRTreeSplitProvider, primaryInteriorFrameFactory,
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, primaryValueProviderFactories,
+                fieldPermutation, 0.7f, opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryRTreeBulkLoad, NC1_ID);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), objScanner, 0, primaryRTreeBulkLoad, 0);
+
+        spec.addRoot(primaryRTreeBulkLoad);
+        runTest(spec);
+    }
+
+    @Test
+    public void searchPrimaryIndexTest() throws Exception {
+        JobSpecification spec = new JobSpecification();
+
+        // build tuple
+        ArrayTupleBuilder tb = new ArrayTupleBuilder(primaryKeyFieldCount);
+        DataOutput dos = tb.getDataOutput();
+
+        tb.reset();
+        DoubleSerializerDeserializer.INSTANCE.serialize(61.2894, dos);
+        tb.addFieldEndOffset();
+        DoubleSerializerDeserializer.INSTANCE.serialize(-149.624, dos);
+        tb.addFieldEndOffset();
+        DoubleSerializerDeserializer.INSTANCE.serialize(61.8894, dos);
+        tb.addFieldEndOffset();
+        DoubleSerializerDeserializer.INSTANCE.serialize(-149.024, dos);
+        tb.addFieldEndOffset();
+
+        ISerializerDeserializer[] keyRecDescSers = { DoubleSerializerDeserializer.INSTANCE,
+                DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+                DoubleSerializerDeserializer.INSTANCE };
+        RecordDescriptor keyRecDesc = new RecordDescriptor(keyRecDescSers);
+
+        ConstantTupleSourceOperatorDescriptor keyProviderOp = new ConstantTupleSourceOperatorDescriptor(spec,
+                keyRecDesc, tb.getFieldEndOffsets(), tb.getByteArray(), tb.getSize());
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, keyProviderOp, NC1_ID);
+
+        int[] keyFields = { 0, 1, 2, 3 };
+
+        RTreeSearchOperatorDescriptor primaryRTreeSearchOp = new RTreeSearchOperatorDescriptor(spec, primaryRecDesc,
+                storageManager, treeIndexRegistryProvider, primaryRTreeSplitProvider, primaryInteriorFrameFactory,
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, primaryValueProviderFactories,
+                keyFields, opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryRTreeSearchOp, NC1_ID);
+
+        PrinterOperatorDescriptor printer = new PrinterOperatorDescriptor(spec);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, printer, NC1_ID);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0, primaryRTreeSearchOp, 0);
+        spec.connect(new OneToOneConnectorDescriptor(spec), primaryRTreeSearchOp, 0, printer, 0);
+
+        spec.addRoot(printer);
+        runTest(spec);
+    }
+
+    @AfterClass
+    public static void cleanup() throws Exception {
+        File primary = new File(primaryFileName);
+        primary.deleteOnExit();
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/rtree/RTreePrimaryIndexStatsOperatorTest.java b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/rtree/RTreePrimaryIndexStatsOperatorTest.java
new file mode 100644
index 0000000..b254d53
--- /dev/null
+++ b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/rtree/RTreePrimaryIndexStatsOperatorTest.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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.
+ */
+
+package edu.uci.ics.hyracks.tests.rtree;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+import edu.uci.ics.hyracks.api.constraints.PartitionConstraintHelper;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTrait;
+import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
+import edu.uci.ics.hyracks.api.dataflow.value.TypeTrait;
+import edu.uci.ics.hyracks.api.io.FileReference;
+import edu.uci.ics.hyracks.api.job.JobSpecification;
+import edu.uci.ics.hyracks.dataflow.common.data.comparators.DoubleBinaryComparatorFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.DoubleParserFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.UTF8StringParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.connectors.OneToOneConnectorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.file.ConstantFileSplitProvider;
+import edu.uci.ics.hyracks.dataflow.std.file.DelimitedDataTupleParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.file.FileScanOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.file.FileSplit;
+import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.ITreeIndexOpHelperFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexBulkLoadOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexStatsOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.rtree.dataflow.RTreeOpHelperFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMInteriorFrameFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.DoublePrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.tuples.RTreeTypeAwareTupleWriterFactory;
+import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
+import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
+import edu.uci.ics.hyracks.test.support.TestStorageManagerInterface;
+import edu.uci.ics.hyracks.test.support.TestTreeIndexRegistryProvider;
+import edu.uci.ics.hyracks.tests.integration.AbstractIntegrationTest;
+
+public class RTreePrimaryIndexStatsOperatorTest extends AbstractIntegrationTest {
+    static {
+        TestStorageManagerComponentHolder.init(8192, 20, 20);
+    }
+
+    private IStorageManagerInterface storageManager = new TestStorageManagerInterface();
+    private IIndexRegistryProvider<ITreeIndex> treeIndexRegistryProvider = new TestTreeIndexRegistryProvider();
+    private ITreeIndexOpHelperFactory opHelperFactory = new RTreeOpHelperFactory();
+
+    private final static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMyy-hhmmssSS");
+    private final static String sep = System.getProperty("file.separator");
+
+    // field, type and key declarations for primary R-tree index
+    private int primaryFieldCount = 5;
+    private int primaryKeyFieldCount = 4;
+    private ITypeTrait[] primaryTypeTraits = new ITypeTrait[primaryFieldCount];
+    private IBinaryComparatorFactory[] primaryComparatorFactories = new IBinaryComparatorFactory[primaryKeyFieldCount];
+    private IPrimitiveValueProviderFactory[] primaryValueProviderFactories = new IPrimitiveValueProviderFactory[primaryKeyFieldCount];
+
+    private RTreeTypeAwareTupleWriterFactory primaryTupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(
+            primaryTypeTraits);
+
+    private RecordDescriptor primaryRecDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+            DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+            DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+            UTF8StringSerializerDeserializer.INSTANCE });
+
+    private ITreeIndexFrameFactory primaryInteriorFrameFactory = new RTreeNSMInteriorFrameFactory(
+            primaryTupleWriterFactory, primaryKeyFieldCount);
+    private ITreeIndexFrameFactory primaryLeafFrameFactory = new RTreeNSMLeafFrameFactory(primaryTupleWriterFactory,
+            primaryKeyFieldCount);
+
+    private static String primaryRTreeName = "primary" + simpleDateFormat.format(new Date());
+    private static String primaryFileName = System.getProperty("java.io.tmpdir") + sep + primaryRTreeName;
+
+    private IFileSplitProvider primaryRTreeSplitProvider = new ConstantFileSplitProvider(
+            new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(primaryFileName))) });
+
+    @Before
+    public void setup() throws Exception {
+        // field, type and key declarations for primary R-tree index
+        primaryTypeTraits[0] = new TypeTrait(8);
+        primaryTypeTraits[1] = new TypeTrait(8);
+        primaryTypeTraits[2] = new TypeTrait(8);
+        primaryTypeTraits[3] = new TypeTrait(8);
+        primaryTypeTraits[4] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        primaryComparatorFactories[0] = DoubleBinaryComparatorFactory.INSTANCE;
+        primaryComparatorFactories[1] = primaryComparatorFactories[0];
+        primaryComparatorFactories[2] = primaryComparatorFactories[0];
+        primaryComparatorFactories[3] = primaryComparatorFactories[0];
+        primaryValueProviderFactories[0] = DoublePrimitiveValueProviderFactory.INSTANCE;
+        primaryValueProviderFactories[1] = primaryValueProviderFactories[0];
+        primaryValueProviderFactories[2] = primaryValueProviderFactories[0];
+        primaryValueProviderFactories[3] = primaryValueProviderFactories[0];
+
+        loadPrimaryIndexTest();
+    }
+
+    public void loadPrimaryIndexTest() throws Exception {
+        JobSpecification spec = new JobSpecification();
+
+        FileSplit[] objectsSplits = new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(
+                "data/spatial.txt"))) };
+        IFileSplitProvider objectsSplitProvider = new ConstantFileSplitProvider(objectsSplits);
+        RecordDescriptor objectsDesc = new RecordDescriptor(new ISerializerDeserializer[] {
+                DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+                DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+                UTF8StringSerializerDeserializer.INSTANCE });
+
+        FileScanOperatorDescriptor objScanner = new FileScanOperatorDescriptor(spec, objectsSplitProvider,
+                new DelimitedDataTupleParserFactory(new IValueParserFactory[] { DoubleParserFactory.INSTANCE,
+                        DoubleParserFactory.INSTANCE, DoubleParserFactory.INSTANCE, DoubleParserFactory.INSTANCE,
+                        UTF8StringParserFactory.INSTANCE }, '|'), objectsDesc);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, objScanner, NC1_ID);
+
+        int[] fieldPermutation = { 0, 1, 2, 3, 4 };
+        TreeIndexBulkLoadOperatorDescriptor primaryRTreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(spec,
+                storageManager, treeIndexRegistryProvider, primaryRTreeSplitProvider, primaryInteriorFrameFactory,
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, primaryValueProviderFactories,
+                fieldPermutation, 0.7f, opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryRTreeBulkLoad, NC1_ID);
+
+        spec.connect(new OneToOneConnectorDescriptor(spec), objScanner, 0, primaryRTreeBulkLoad, 0);
+
+        spec.addRoot(primaryRTreeBulkLoad);
+        runTest(spec);
+    }
+
+    @Test
+    public void showPrimaryIndexStats() throws Exception {
+        JobSpecification spec = new JobSpecification();
+
+        TreeIndexStatsOperatorDescriptor primaryStatsOp = new TreeIndexStatsOperatorDescriptor(spec, storageManager,
+                treeIndexRegistryProvider, primaryRTreeSplitProvider, primaryInteriorFrameFactory,
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, opHelperFactory);
+        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryStatsOp, NC1_ID);
+
+        spec.addRoot(primaryStatsOp);
+        runTest(spec);
+    }
+
+    @AfterClass
+    public static void cleanup() throws Exception {
+        File primary = new File(primaryFileName);
+        primary.deleteOnExit();
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/rtree/RTreeOperatorsTest.java b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/rtree/RTreeSecondaryIndexSearchOperatorTest.java
similarity index 86%
rename from hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/rtree/RTreeOperatorsTest.java
rename to hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/rtree/RTreeSecondaryIndexSearchOperatorTest.java
index 5f6eb3a..dc318a9 100644
--- a/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/rtree/RTreeOperatorsTest.java
+++ b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/rtree/RTreeSecondaryIndexSearchOperatorTest.java
@@ -53,17 +53,18 @@
 import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeSearchOperatorDescriptor;
 import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.ITreeIndexOpHelperFactory;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexBulkLoadOperatorDescriptor;
-import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexStatsOperatorDescriptor;
 import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleWriterFactory;
 import edu.uci.ics.hyracks.storage.am.rtree.dataflow.RTreeOpHelperFactory;
 import edu.uci.ics.hyracks.storage.am.rtree.dataflow.RTreeSearchOperatorDescriptor;
 import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.DoublePrimitiveValueProviderFactory;
 import edu.uci.ics.hyracks.storage.am.rtree.tuples.RTreeTypeAwareTupleWriterFactory;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
@@ -71,7 +72,7 @@
 import edu.uci.ics.hyracks.test.support.TestTreeIndexRegistryProvider;
 import edu.uci.ics.hyracks.tests.integration.AbstractIntegrationTest;
 
-public class RTreeOperatorsTest extends AbstractIntegrationTest {
+public class RTreeSecondaryIndexSearchOperatorTest extends AbstractIntegrationTest {
     static {
         TestStorageManagerComponentHolder.init(8192, 20, 20);
     }
@@ -89,9 +90,11 @@
     private int primaryKeyFieldCount = 4;
     private ITypeTrait[] primaryTypeTraits = new ITypeTrait[primaryFieldCount];
     private IBinaryComparatorFactory[] primaryComparatorFactories = new IBinaryComparatorFactory[primaryKeyFieldCount];
+    private IPrimitiveValueProviderFactory[] primaryValueProviderFactories = new IPrimitiveValueProviderFactory[primaryKeyFieldCount];
 
     private RTreeTypeAwareTupleWriterFactory primaryTupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(
             primaryTypeTraits);
+
     private ITreeIndexFrameFactory primaryInteriorFrameFactory = new RTreeNSMInteriorFrameFactory(
             primaryTupleWriterFactory, primaryKeyFieldCount);
     private ITreeIndexFrameFactory primaryLeafFrameFactory = new RTreeNSMLeafFrameFactory(primaryTupleWriterFactory,
@@ -138,8 +141,11 @@
     private ITypeTrait[] secondaryTypeTraits = new ITypeTrait[secondaryFieldCount];
     private int secondaryKeyFieldCount = 4;
     private IBinaryComparatorFactory[] secondaryComparatorFactories = new IBinaryComparatorFactory[secondaryKeyFieldCount];
+    private IPrimitiveValueProviderFactory[] secondaryValueProviderFactories = new IPrimitiveValueProviderFactory[secondaryKeyFieldCount];
+
     private RTreeTypeAwareTupleWriterFactory secondaryTupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(
             secondaryTypeTraits);
+
     private ITreeIndexFrameFactory secondaryInteriorFrameFactory = new RTreeNSMInteriorFrameFactory(
             secondaryTupleWriterFactory, secondaryKeyFieldCount);
     private ITreeIndexFrameFactory secondaryLeafFrameFactory = new RTreeNSMLeafFrameFactory(
@@ -157,7 +163,7 @@
             UTF8StringSerializerDeserializer.INSTANCE });
 
     @Before
-    public void setup() {
+    public void setup() throws Exception {
         // field, type and key declarations for primary R-tree index
         primaryTypeTraits[0] = new TypeTrait(8);
         primaryTypeTraits[1] = new TypeTrait(8);
@@ -168,6 +174,10 @@
         primaryComparatorFactories[1] = primaryComparatorFactories[0];
         primaryComparatorFactories[2] = primaryComparatorFactories[0];
         primaryComparatorFactories[3] = primaryComparatorFactories[0];
+        primaryValueProviderFactories[0] = DoublePrimitiveValueProviderFactory.INSTANCE;
+        primaryValueProviderFactories[1] = primaryValueProviderFactories[0];
+        primaryValueProviderFactories[2] = primaryValueProviderFactories[0];
+        primaryValueProviderFactories[3] = primaryValueProviderFactories[0];
 
         // field, type and key declarations for primary B-tree index
         primaryBTreeTypeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
@@ -192,9 +202,16 @@
         secondaryComparatorFactories[1] = secondaryComparatorFactories[0];
         secondaryComparatorFactories[2] = secondaryComparatorFactories[0];
         secondaryComparatorFactories[3] = secondaryComparatorFactories[0];
+        secondaryValueProviderFactories[0] = DoublePrimitiveValueProviderFactory.INSTANCE;
+        secondaryValueProviderFactories[1] = secondaryValueProviderFactories[0];
+        secondaryValueProviderFactories[2] = secondaryValueProviderFactories[0];
+        secondaryValueProviderFactories[3] = secondaryValueProviderFactories[0];
+
+        loadPrimaryIndexTest();
+        loadPrimaryBTreeIndexTest();
+        loadSecondaryIndexTest();
     }
 
-    @Test
     public void loadPrimaryBTreeIndexTest() throws Exception {
         JobSpecification spec = new JobSpecification();
 
@@ -227,7 +244,7 @@
         int[] fieldPermutation = { 0, 1, 2, 4, 5, 7, 9, 10, 11, 12 };
         TreeIndexBulkLoadOperatorDescriptor primaryBTreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(spec,
                 storageManager, treeIndexRegistryProvider, primaryBTreeSplitProvider, primaryBTreeInteriorFrameFactory,
-                primaryBTreeLeafFrameFactory, primaryBTreeTypeTraits, primaryBTreeComparatorFactories,
+                primaryBTreeLeafFrameFactory, primaryBTreeTypeTraits, primaryBTreeComparatorFactories, null,
                 fieldPermutation, 0.7f, bTreeopHelperFactory);
         PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryBTreeBulkLoad, NC1_ID);
 
@@ -239,7 +256,6 @@
         runTest(spec);
     }
 
-    @Test
     public void loadPrimaryIndexTest() throws Exception {
         JobSpecification spec = new JobSpecification();
 
@@ -260,8 +276,8 @@
         int[] fieldPermutation = { 0, 1, 2, 3, 4 };
         TreeIndexBulkLoadOperatorDescriptor primaryRTreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(spec,
                 storageManager, treeIndexRegistryProvider, primaryRTreeSplitProvider, primaryInteriorFrameFactory,
-                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, fieldPermutation, 0.7f,
-                opHelperFactory);
+                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories,
+                secondaryValueProviderFactories, fieldPermutation, 0.7f, opHelperFactory);
         PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryRTreeBulkLoad, NC1_ID);
 
         spec.connect(new OneToOneConnectorDescriptor(spec), objScanner, 0, primaryRTreeBulkLoad, 0);
@@ -270,7 +286,6 @@
         runTest(spec);
     }
 
-    @Test
     public void loadSecondaryIndexTest() throws Exception {
         JobSpecification spec = new JobSpecification();
 
@@ -304,8 +319,8 @@
         int[] fieldPermutation = { 6, 7, 8, 9, 0 };
         TreeIndexBulkLoadOperatorDescriptor secondaryRTreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(spec,
                 storageManager, treeIndexRegistryProvider, secondaryRTreeSplitProvider, secondaryInteriorFrameFactory,
-                secondaryLeafFrameFactory, secondaryTypeTraits, secondaryComparatorFactories, fieldPermutation, 0.7f,
-                opHelperFactory);
+                secondaryLeafFrameFactory, secondaryTypeTraits, secondaryComparatorFactories,
+                secondaryValueProviderFactories, fieldPermutation, 0.7f, opHelperFactory);
         PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, secondaryRTreeBulkLoad, NC1_ID);
 
         spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0, primaryBTreeSearchOp, 0);
@@ -316,63 +331,6 @@
     }
 
     @Test
-    public void showPrimaryIndexStats() throws Exception {
-        JobSpecification spec = new JobSpecification();
-
-        TreeIndexStatsOperatorDescriptor primaryStatsOp = new TreeIndexStatsOperatorDescriptor(spec, storageManager,
-                treeIndexRegistryProvider, primaryRTreeSplitProvider, primaryInteriorFrameFactory,
-                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, opHelperFactory);
-        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryStatsOp, NC1_ID);
-
-        spec.addRoot(primaryStatsOp);
-        runTest(spec);
-    }
-
-    @Test
-    public void searchPrimaryIndexTest() throws Exception {
-        JobSpecification spec = new JobSpecification();
-
-        // build tuple
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(primaryKeyFieldCount);
-        DataOutput dos = tb.getDataOutput();
-
-        tb.reset();
-        DoubleSerializerDeserializer.INSTANCE.serialize(61.2894, dos);
-        tb.addFieldEndOffset();
-        DoubleSerializerDeserializer.INSTANCE.serialize(-149.624, dos);
-        tb.addFieldEndOffset();
-        DoubleSerializerDeserializer.INSTANCE.serialize(61.8894, dos);
-        tb.addFieldEndOffset();
-        DoubleSerializerDeserializer.INSTANCE.serialize(-149.024, dos);
-        tb.addFieldEndOffset();
-
-        ISerializerDeserializer[] keyRecDescSers = { DoubleSerializerDeserializer.INSTANCE,
-                DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
-                DoubleSerializerDeserializer.INSTANCE };
-        RecordDescriptor keyRecDesc = new RecordDescriptor(keyRecDescSers);
-
-        ConstantTupleSourceOperatorDescriptor keyProviderOp = new ConstantTupleSourceOperatorDescriptor(spec,
-                keyRecDesc, tb.getFieldEndOffsets(), tb.getByteArray(), tb.getSize());
-        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, keyProviderOp, NC1_ID);
-
-        int[] keyFields = { 0, 1, 2, 3 };
-
-        RTreeSearchOperatorDescriptor primaryRTreeSearchOp = new RTreeSearchOperatorDescriptor(spec, primaryRecDesc,
-                storageManager, treeIndexRegistryProvider, primaryRTreeSplitProvider, primaryInteriorFrameFactory,
-                primaryLeafFrameFactory, primaryTypeTraits, primaryComparatorFactories, keyFields, opHelperFactory);
-        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryRTreeSearchOp, NC1_ID);
-
-        PrinterOperatorDescriptor printer = new PrinterOperatorDescriptor(spec);
-        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, printer, NC1_ID);
-
-        spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0, primaryRTreeSearchOp, 0);
-        spec.connect(new OneToOneConnectorDescriptor(spec), primaryRTreeSearchOp, 0, printer, 0);
-
-        spec.addRoot(printer);
-        runTest(spec);
-    }
-
-    @Test
     public void searchSecondaryIndexTest() throws Exception {
         JobSpecification spec = new JobSpecification();
 
@@ -404,7 +362,7 @@
         RTreeSearchOperatorDescriptor secondaryRTreeSearchOp = new RTreeSearchOperatorDescriptor(spec,
                 secondaryRecDesc, storageManager, treeIndexRegistryProvider, secondaryRTreeSplitProvider,
                 secondaryInteriorFrameFactory, secondaryLeafFrameFactory, secondaryTypeTraits,
-                secondaryComparatorFactories, keyFields, opHelperFactory);
+                secondaryComparatorFactories, secondaryValueProviderFactories, keyFields, opHelperFactory);
         PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, secondaryRTreeSearchOp, NC1_ID);
 
         PrinterOperatorDescriptor printer = new PrinterOperatorDescriptor(spec);
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IBTreeInteriorFrame.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IBTreeInteriorFrame.java
index 25ab167..6d33ac2 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IBTreeInteriorFrame.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IBTreeInteriorFrame.java
@@ -23,7 +23,7 @@
 
 public interface IBTreeInteriorFrame extends ITreeIndexFrame {
     public void insertSorted(ITupleReference tuple, MultiComparator cmp) throws HyracksDataException;
-    
+
     public int getChildPageId(RangePredicate pred, MultiComparator srcCmp);
 
     public int getLeftmostChildPageId(MultiComparator cmp);
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IBTreeLeafFrame.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IBTreeLeafFrame.java
index 53d892e..045dd08 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IBTreeLeafFrame.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/api/IBTreeLeafFrame.java
@@ -25,7 +25,7 @@
 
 public interface IBTreeLeafFrame extends ITreeIndexFrame {
     public void insertSorted(ITupleReference tuple, MultiComparator cmp) throws HyracksDataException;
-    
+
     public void setNextLeaf(int nextPage);
 
     public int getNextLeaf();
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/compressors/FieldPrefixCompressor.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/compressors/FieldPrefixCompressor.java
index 1292ff2..96ab583 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/compressors/FieldPrefixCompressor.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/compressors/FieldPrefixCompressor.java
@@ -182,8 +182,8 @@
                     // + " " + keyPartitions.get(kpIndex).lastRecSlotNum +
                     // " FIELDSTOCOMPRESS: " + numFieldsToCompress);
 
-                    FieldPrefixTupleReference prevTuple = new FieldPrefixTupleReference(tupleWriter
-                            .createTupleReference());
+                    FieldPrefixTupleReference prevTuple = new FieldPrefixTupleReference(
+                            tupleWriter.createTupleReference());
                     prevTuple.setFieldCount(fieldCount);
 
                     FieldPrefixTupleReference tuple = new FieldPrefixTupleReference(tupleWriter.createTupleReference());
@@ -312,9 +312,7 @@
 
         // copy new tuple and new slots into original page
         int freeSpaceAfterInit = frame.getOrigFreeSpaceOff();
-        System
-                .arraycopy(buffer, freeSpaceAfterInit, pageArray, freeSpaceAfterInit, tupleFreeSpace
-                        - freeSpaceAfterInit);
+        System.arraycopy(buffer, freeSpaceAfterInit, pageArray, freeSpaceAfterInit, tupleFreeSpace - freeSpaceAfterInit);
 
         // copy prefix slots
         int slotOffRunner = buf.capacity() - slotManager.getSlotSize();
@@ -338,7 +336,7 @@
         // System.out.println("PREFIXSLOTS BEF: " +
         // frame.getNumPrefixRecords());
         // System.out.println("PREFIXSLOTS AFT: " + newPrefixSlots.length);
-        //        
+        //
         // System.out.println("FREESPACE BEF: " + frame.getFreeSpaceOff());
         // System.out.println("FREESPACE AFT: " + recordFreeSpace);
         // System.out.println("PREFIXES: " + newPrefixSlots.length + " / " +
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeOpHelper.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeOpHelper.java
index c85c6a0..6a9e965 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeOpHelper.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeOpHelper.java
@@ -1,6 +1,7 @@
 package edu.uci.ics.hyracks.storage.am.btree.dataflow;
 
 import edu.uci.ics.hyracks.api.context.IHyracksStageletContext;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
 import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
@@ -11,22 +12,29 @@
 import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexOpHelper;
 import edu.uci.ics.hyracks.storage.am.common.frames.LIFOMetaDataFrameFactory;
 import edu.uci.ics.hyracks.storage.am.common.freepage.LinkedListFreePageManager;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
 import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
 
 public class BTreeOpHelper extends TreeIndexOpHelper {
 
+    protected ITreeIndexOperatorDescriptorHelper opDesc;
+
     public BTreeOpHelper(ITreeIndexOperatorDescriptorHelper opDesc, IHyracksStageletContext ctx, int partition,
             IndexHelperOpenMode mode) {
         super(opDesc, ctx, partition, mode);
+        this.opDesc = opDesc;
     }
-    
+
     public ITreeIndex createTreeIndex() throws HyracksDataException {
         IBufferCache bufferCache = opDesc.getStorageManager().getBufferCache(ctx);
         ITreeIndexMetaDataFrameFactory metaDataFrameFactory = new LIFOMetaDataFrameFactory();
-        IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, indexFileId, 0, metaDataFrameFactory);
+        IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, indexFileId, 0,
+                metaDataFrameFactory);
         return new BTree(bufferCache, freePageManager, opDesc.getTreeIndexInteriorFactory(),
                 opDesc.getTreeIndexLeafFactory(), cmp);
     }
-    
-    
+
+    public MultiComparator createMultiComparator(IBinaryComparator[] comparators) throws HyracksDataException {
+        return new MultiComparator(opDesc.getTreeIndexTypeTraits(), comparators);
+    }
 }
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorDescriptor.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorDescriptor.java
index 254935b..f9b30ca 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorDescriptor.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorDescriptor.java
@@ -49,7 +49,7 @@
             IBinaryComparatorFactory[] comparatorFactories, boolean isForward, int[] lowKeyFields, int[] highKeyFields,
             boolean lowKeyInclusive, boolean highKeyInclusive, ITreeIndexOpHelperFactory opHelperFactory) {
         super(spec, 1, 1, recDesc, storageManager, treeIndexRegistryProvider, fileSplitProvider, interiorFrameFactory,
-                leafFrameFactory, typeTraits, comparatorFactories, opHelperFactory);
+                leafFrameFactory, typeTraits, comparatorFactories, null, opHelperFactory);
         this.isForward = isForward;
         this.lowKeyFields = lowKeyFields;
         this.highKeyFields = highKeyFields;
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorNodePushable.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorNodePushable.java
index 9d33bb2..4dc41c6 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorNodePushable.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorNodePushable.java
@@ -69,7 +69,8 @@
     public BTreeSearchOperatorNodePushable(AbstractTreeIndexOperatorDescriptor opDesc, IHyracksStageletContext ctx,
             int partition, IRecordDescriptorProvider recordDescProvider, boolean isForward, int[] lowKeyFields,
             int[] highKeyFields, boolean lowKeyInclusive, boolean highKeyInclusive) {
-        treeIndexOpHelper = opDesc.getTreeIndexOpHelperFactory().createTreeIndexOpHelper(opDesc, ctx, partition, IndexHelperOpenMode.OPEN);
+        treeIndexOpHelper = opDesc.getTreeIndexOpHelperFactory().createTreeIndexOpHelper(opDesc, ctx, partition,
+                IndexHelperOpenMode.OPEN);
         this.isForward = isForward;
         this.lowKeyInclusive = lowKeyInclusive;
         this.highKeyInclusive = highKeyInclusive;
@@ -91,12 +92,12 @@
         accessor = new FrameTupleAccessor(treeIndexOpHelper.getHyracksStageletContext().getFrameSize(), recDesc);
 
         cursorFrame = opDesc.getTreeIndexLeafFactory().createFrame();
-        cursor = new BTreeRangeSearchCursor((IBTreeLeafFrame)cursorFrame);
+        cursor = new BTreeRangeSearchCursor((IBTreeLeafFrame) cursorFrame);
 
         try {
 
             treeIndexOpHelper.init();
-            btree = (BTree)treeIndexOpHelper.getTreeIndex();
+            btree = (BTree) treeIndexOpHelper.getTreeIndex();
 
             // construct range predicate
 
@@ -136,8 +137,8 @@
             appender = new FrameTupleAppender(treeIndexOpHelper.getHyracksStageletContext().getFrameSize());
             appender.reset(writeBuffer, true);
 
-            opCtx = btree.createOpContext(IndexOp.SEARCH, treeIndexOpHelper.getLeafFrame(), treeIndexOpHelper
-                    .getInteriorFrame(), null);
+            opCtx = btree.createOpContext(IndexOp.SEARCH, treeIndexOpHelper.getLeafFrame(),
+                    treeIndexOpHelper.getInteriorFrame(), null);
 
         } catch (Exception e) {
             treeIndexOpHelper.deinit();
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeFieldPrefixNSMLeafFrame.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeFieldPrefixNSMLeafFrame.java
index bd4947c..c0c6d49 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeFieldPrefixNSMLeafFrame.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeFieldPrefixNSMLeafFrame.java
@@ -168,12 +168,12 @@
             slotManager.setSlot(sortedTupleOffs.get(i).slotOff, slotManager.encodeSlotFields(prefixSlotNum, freeSpace));
             freeSpace += tupleLength;
         }
-        
+
         buf.putInt(freeSpaceOff, freeSpace);
         int totalFreeSpace = buf.capacity() - buf.getInt(freeSpaceOff)
                 - ((buf.getInt(tupleCountOff) + buf.getInt(prefixTupleCountOff)) * slotManager.getSlotSize());
         buf.putInt(totalFreeSpaceOff, totalFreeSpace);
-        
+
         return false;
     }
 
@@ -192,9 +192,8 @@
                 frameTuple.setFieldCount(cmp.getFieldCount());
                 frameTuple.resetByTupleIndex(this, tupleIndex);
 
-                int comparison = cmp.fieldRangeCompare(tuple, frameTuple, cmp.getKeyFieldCount() - 1, cmp
-                        .getFieldCount()
-                        - cmp.getKeyFieldCount());
+                int comparison = cmp.fieldRangeCompare(tuple, frameTuple, cmp.getKeyFieldCount() - 1,
+                        cmp.getFieldCount() - cmp.getKeyFieldCount());
                 if (comparison != 0) {
                     throw new BTreeException("Cannot delete tuple. Byte-by-byte comparison failed to prove equality.");
                 }
@@ -293,12 +292,12 @@
 
     @Override
     public int findTupleIndex(ITupleReference tuple, MultiComparator cmp) throws Exception {
-    	return slotManager.findSlot(tuple, frameTuple, framePrefixTuple, cmp, FindTupleMode.FTM_INCLUSIVE,
-    			FindTupleNoExactMatchPolicy.FTP_HIGHER_KEY);
+        return slotManager.findSlot(tuple, frameTuple, framePrefixTuple, cmp, FindTupleMode.FTM_INCLUSIVE,
+                FindTupleNoExactMatchPolicy.FTP_HIGHER_KEY);
     }
-    
+
     @Override
-    public void insert(ITupleReference tuple, MultiComparator cmp, int tupleIndex) throws Exception {        
+    public void insert(ITupleReference tuple, MultiComparator cmp, int tupleIndex) throws Exception {
         int slot = slotManager.insertSlot(tupleIndex, buf.getInt(freeSpaceOff));
         int prefixSlotNum = slotManager.decodeFirstSlotField(slot);
         int numPrefixFields = 0;
@@ -348,8 +347,8 @@
         for (int i = 0; i < tupleCount; i++) {
             frameTuple.resetByTupleIndex(this, i);
             for (int j = 0; j < cmp.getKeyFieldCount(); j++) {
-                ByteArrayInputStream inStream = new ByteArrayInputStream(frameTuple.getFieldData(j), frameTuple
-                        .getFieldStart(j), frameTuple.getFieldLength(j));
+                ByteArrayInputStream inStream = new ByteArrayInputStream(frameTuple.getFieldData(j),
+                        frameTuple.getFieldStart(j), frameTuple.getFieldLength(j));
                 DataInput dataIn = new DataInputStream(inStream);
                 Object o = fields[j].deserialize(dataIn);
                 strBuilder.append(o.toString() + " ");
@@ -386,7 +385,7 @@
     public boolean isLeaf() {
         return buf.get(levelOff) == 0;
     }
-    
+
     @Override
     public boolean isInterior() {
         return buf.get(levelOff) > 0;
@@ -461,7 +460,7 @@
         BTreeFieldPrefixNSMLeafFrame rf = (BTreeFieldPrefixNSMLeafFrame) rightFrame;
 
         frameTuple.setFieldCount(cmp.getFieldCount());
-        
+
         ByteBuffer right = rf.getBuffer();
         int tupleCount = getTupleCount();
         int prefixTupleCount = getPrefixTupleCount();
@@ -658,7 +657,7 @@
     }
 
     @Override
-	public int getPageHeaderSize() {
-		return nextLeafOff;
-	}
+    public int getPageHeaderSize() {
+        return nextLeafOff;
+    }
 }
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeNSMInteriorFrame.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeNSMInteriorFrame.java
index 6025003..5ddb43a 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeNSMInteriorFrame.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeNSMInteriorFrame.java
@@ -44,7 +44,7 @@
     private static final int rightLeafOff = smFlagOff + 1;
 
     private static final int childPtrSize = 4;
-    
+
     // private SimpleTupleReference cmpFrameTuple = new SimpleTupleReference();
     private ITreeIndexTupleReference cmpFrameTuple;
 
@@ -78,7 +78,7 @@
     }
 
     public int findTupleIndex(ITupleReference tuple, MultiComparator cmp) throws Exception {
-    	frameTuple.setFieldCount(cmp.getKeyFieldCount());
+        frameTuple.setFieldCount(cmp.getKeyFieldCount());
         int tupleIndex = slotManager.findTupleIndex(tuple, frameTuple, cmp, FindTupleMode.FTM_INCLUSIVE,
                 FindTupleNoExactMatchPolicy.FTP_HIGHER_KEY);
         int slotOff = slotManager.getSlotOff(tupleIndex);
@@ -96,41 +96,40 @@
         }
         return tupleIndex;
     }
-    
+
     @Override
     public void insert(ITupleReference tuple, MultiComparator cmp, int tupleIndex) throws Exception {
-    	int slotOff = slotManager.insertSlot(tupleIndex, buf.getInt(freeSpaceOff));
-    	int freeSpace = buf.getInt(freeSpaceOff);
-    	int bytesWritten = tupleWriter.writeTupleFields(tuple, 0, cmp.getKeyFieldCount(), buf, freeSpace);
-    	System.arraycopy(tuple.getFieldData(cmp.getKeyFieldCount() - 1), getLeftChildPageOff(tuple, cmp), buf
-    			.array(), freeSpace + bytesWritten, childPtrSize);
-    	int tupleSize = bytesWritten + childPtrSize;
+        int slotOff = slotManager.insertSlot(tupleIndex, buf.getInt(freeSpaceOff));
+        int freeSpace = buf.getInt(freeSpaceOff);
+        int bytesWritten = tupleWriter.writeTupleFields(tuple, 0, cmp.getKeyFieldCount(), buf, freeSpace);
+        System.arraycopy(tuple.getFieldData(cmp.getKeyFieldCount() - 1), getLeftChildPageOff(tuple, cmp), buf.array(),
+                freeSpace + bytesWritten, childPtrSize);
+        int tupleSize = bytesWritten + childPtrSize;
 
-    	buf.putInt(tupleCountOff, buf.getInt(tupleCountOff) + 1);
-    	buf.putInt(freeSpaceOff, buf.getInt(freeSpaceOff) + tupleSize);
-    	buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) - tupleSize - slotManager.getSlotSize());
+        buf.putInt(tupleCountOff, buf.getInt(tupleCountOff) + 1);
+        buf.putInt(freeSpaceOff, buf.getInt(freeSpaceOff) + tupleSize);
+        buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) - tupleSize - slotManager.getSlotSize());
 
-    	// did insert into the rightmost slot?
-    	if (slotOff == slotManager.getSlotEndOff()) {
-    		System.arraycopy(tuple.getFieldData(cmp.getKeyFieldCount() - 1), getLeftChildPageOff(tuple, cmp)
-    				+ childPtrSize, buf.array(), rightLeafOff, childPtrSize);
-    	} else {
-    		// if slotOff has a right (slot-)neighbor then update its child
-    		// pointer
-    		// the only time when this is NOT the case, is when this is the
-    		// first tuple
-    		// (or when the splitkey goes into the rightmost slot but that
-    		// case was handled in the if above)
-    		if (buf.getInt(tupleCountOff) > 1) {
-    			int rightNeighborOff = slotOff - slotManager.getSlotSize();
-    			frameTuple.resetByTupleOffset(buf, slotManager.getTupleOff(rightNeighborOff));
-    			System.arraycopy(tuple.getFieldData(0), getLeftChildPageOff(tuple, cmp) + childPtrSize,
-    					buf.array(), getLeftChildPageOff(frameTuple, cmp), childPtrSize);
-    		}
-    	}
+        // did insert into the rightmost slot?
+        if (slotOff == slotManager.getSlotEndOff()) {
+            System.arraycopy(tuple.getFieldData(cmp.getKeyFieldCount() - 1), getLeftChildPageOff(tuple, cmp)
+                    + childPtrSize, buf.array(), rightLeafOff, childPtrSize);
+        } else {
+            // if slotOff has a right (slot-)neighbor then update its child
+            // pointer
+            // the only time when this is NOT the case, is when this is the
+            // first tuple
+            // (or when the splitkey goes into the rightmost slot but that
+            // case was handled in the if above)
+            if (buf.getInt(tupleCountOff) > 1) {
+                int rightNeighborOff = slotOff - slotManager.getSlotSize();
+                frameTuple.resetByTupleOffset(buf, slotManager.getTupleOff(rightNeighborOff));
+                System.arraycopy(tuple.getFieldData(0), getLeftChildPageOff(tuple, cmp) + childPtrSize, buf.array(),
+                        getLeftChildPageOff(frameTuple, cmp), childPtrSize);
+            }
+        }
     }
 
-
     @Override
     public void insertSorted(ITupleReference tuple, MultiComparator cmp) throws HyracksDataException {
         int freeSpace = buf.getInt(freeSpaceOff);
@@ -151,7 +150,7 @@
             throws Exception {
         // before doing anything check if key already exists
         frameTuple.setFieldCount(cmp.getKeyFieldCount());
-        
+
         ByteBuffer right = rightFrame.getBuffer();
         int tupleCount = buf.getInt(tupleCountOff);
 
@@ -205,7 +204,7 @@
         // insert key
         int targetTupleIndex = targetFrame.findTupleIndex(savedSplitKey.getTuple(), cmp);
         targetFrame.insert(savedSplitKey.getTuple(), cmp, targetTupleIndex);
-        
+
         return 0;
     }
 
@@ -242,7 +241,7 @@
 
         buf.putInt(freeSpaceOff, freeSpace);
         buf.putInt(totalFreeSpaceOff, buf.capacity() - freeSpace - tupleCount * slotManager.getSlotSize());
-        
+
         return false;
     }
 
@@ -316,7 +315,7 @@
                 }
                 slotOff += slotManager.getSlotSize();
             }
-            
+
             frameTuple.resetByTupleOffset(buf, slotManager.getTupleOff(slotOff));
             int childPageOff = getLeftChildPageOff(frameTuple, srcCmp);
             return buf.getInt(childPageOff);
@@ -351,8 +350,8 @@
 
         // maintain space information
         buf.putInt(tupleCountOff, buf.getInt(tupleCountOff) - 1);
-        buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) + keySize + childPtrSize
-                + slotManager.getSlotSize());
+        buf.putInt(totalFreeSpaceOff,
+                buf.getInt(totalFreeSpaceOff) + keySize + childPtrSize + slotManager.getSlotSize());
     }
 
     @Override
@@ -388,8 +387,10 @@
         for (int i = 0; i < tupleCount; i++) {
             int tupleOff = slotManager.getTupleOff(slotManager.getSlotOff(i));
             frameTuple.resetByTupleOffset(buf, tupleOff);
-            int intVal = getInt(buf.array(), frameTuple.getFieldStart(frameTuple.getFieldCount() - 1)
-                    + frameTuple.getFieldLength(frameTuple.getFieldCount() - 1));
+            int intVal = getInt(
+                    buf.array(),
+                    frameTuple.getFieldStart(frameTuple.getFieldCount() - 1)
+                            + frameTuple.getFieldLength(frameTuple.getFieldCount() - 1));
             ret.add(intVal);
         }
         if (!isLeaf()) {
@@ -411,8 +412,8 @@
 
         // maintain space information
         buf.putInt(tupleCountOff, buf.getInt(tupleCountOff) - 1);
-        buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) + keySize + childPtrSize
-                + slotManager.getSlotSize());
+        buf.putInt(totalFreeSpaceOff,
+                buf.getInt(totalFreeSpaceOff) + keySize + childPtrSize + slotManager.getSlotSize());
 
         int freeSpace = buf.getInt(freeSpaceOff);
         if (freeSpace == tupleOff + keySize + childPtrSize) {
@@ -433,8 +434,8 @@
         for (int i = 0; i < tupleCount; i++) {
             frameTuple.resetByTupleIndex(this, i);
             for (int j = 0; j < cmp.getKeyFieldCount(); j++) {
-                ByteArrayInputStream inStream = new ByteArrayInputStream(frameTuple.getFieldData(j), frameTuple
-                        .getFieldStart(j), frameTuple.getFieldLength(j));
+                ByteArrayInputStream inStream = new ByteArrayInputStream(frameTuple.getFieldData(j),
+                        frameTuple.getFieldStart(j), frameTuple.getFieldLength(j));
                 DataInput dataIn = new DataInputStream(inStream);
                 Object o = fields[j].deserialize(dataIn);
                 strBuilder.append(o.toString() + " ");
@@ -444,9 +445,9 @@
         strBuilder.append("\n");
         return strBuilder.toString();
     }
-    
+
     @Override
-	public int getPageHeaderSize() {
-		return rightLeafOff;
-	}
+    public int getPageHeaderSize() {
+        return rightLeafOff;
+    }
 }
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeNSMLeafFrame.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeNSMLeafFrame.java
index 85fbec9..ebb85a9 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeNSMLeafFrame.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/BTreeNSMLeafFrame.java
@@ -67,7 +67,7 @@
 
     @Override
     public int findTupleIndex(ITupleReference tuple, MultiComparator cmp) throws Exception {
-    	frameTuple.setFieldCount(cmp.getFieldCount());
+        frameTuple.setFieldCount(cmp.getFieldCount());
         int tupleIndex = slotManager.findTupleIndex(tuple, frameTuple, cmp, FindTupleMode.FTM_INCLUSIVE,
                 FindTupleNoExactMatchPolicy.FTP_HIGHER_KEY);
         int slotOff = slotManager.getSlotOff(tupleIndex);
@@ -83,18 +83,18 @@
         if (isDuplicate) {
             throw new BTreeException("Trying to insert duplicate value into leaf of unique index");
         }
-        
+
         return tupleIndex;
     }
-    
+
     @Override
-    public void insert(ITupleReference tuple, MultiComparator cmp, int tupleIndex) throws Exception {    	
-    	slotManager.insertSlot(tupleIndex, buf.getInt(freeSpaceOff));
-    	int freeSpace = buf.getInt(freeSpaceOff);
-    	int bytesWritten = tupleWriter.writeTuple(tuple, buf, freeSpace);
-    	buf.putInt(tupleCountOff, buf.getInt(tupleCountOff) + 1);
-    	buf.putInt(freeSpaceOff, buf.getInt(freeSpaceOff) + bytesWritten);
-    	buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) - bytesWritten - slotManager.getSlotSize());
+    public void insert(ITupleReference tuple, MultiComparator cmp, int tupleIndex) throws Exception {
+        slotManager.insertSlot(tupleIndex, buf.getInt(freeSpaceOff));
+        int freeSpace = buf.getInt(freeSpaceOff);
+        int bytesWritten = tupleWriter.writeTuple(tuple, buf, freeSpace);
+        buf.putInt(tupleCountOff, buf.getInt(tupleCountOff) + 1);
+        buf.putInt(freeSpaceOff, buf.getInt(freeSpaceOff) + bytesWritten);
+        buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) - bytesWritten - slotManager.getSlotSize());
     }
 
     @Override
@@ -112,7 +112,7 @@
             throws Exception {
 
         frameTuple.setFieldCount(cmp.getFieldCount());
-        
+
         ByteBuffer right = rightFrame.getBuffer();
         int tupleCount = getTupleCount();
 
@@ -160,7 +160,7 @@
         splitKey.initData(splitKeySize);
         tupleWriter.writeTupleFields(frameTuple, 0, cmp.getKeyFieldCount(), splitKey.getBuffer(), 0);
         splitKey.getTuple().resetByTupleOffset(splitKey.getBuffer(), 0);
-        
+
         return 0;
     }
 
@@ -181,8 +181,8 @@
         return slotManager.findTupleIndex(searchKey, pageTuple, cmp, ftm, ftp);
     }
 
-	@Override
-	public int getPageHeaderSize() {
-		return nextLeafOff;
-	}
+    @Override
+    public int getPageHeaderSize() {
+        return nextLeafOff;
+    }
 }
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/OrderedSlotManager.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/OrderedSlotManager.java
index 89a70e0..a042c3a 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/OrderedSlotManager.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/frames/OrderedSlotManager.java
@@ -28,8 +28,8 @@
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
 
 public class OrderedSlotManager extends AbstractSlotManager {
-    
-	@Override
+
+    @Override
     public int findTupleIndex(ITupleReference searchKey, ITreeIndexTupleReference frameTuple, MultiComparator multiCmp,
             FindTupleMode mode, FindTupleNoExactMatchPolicy matchPolicy) {
         if (frame.getTupleCount() <= 0)
@@ -38,12 +38,12 @@
         int mid;
         int begin = 0;
         int end = frame.getTupleCount() - 1;
-        
+
         while (begin <= end) {
             mid = (begin + end) / 2;
-            frameTuple.resetByTupleIndex(frame, mid);            
-            
-            int cmp = multiCmp.compare(searchKey, frameTuple);            
+            frameTuple.resetByTupleIndex(frame, mid);
+
+            int cmp = multiCmp.compare(searchKey, frameTuple);
             if (cmp < 0) {
                 end = mid - 1;
             } else if (cmp > 0) {
@@ -81,7 +81,7 @@
                 return -1;
         }
     }
-    
+
     @Override
     public int insertSlot(int tupleIndex, int tupleOff) {
         int slotOff = getSlotOff(tupleIndex);
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTree.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTree.java
index 2831ff6..bb5ee5e 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTree.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTree.java
@@ -1151,7 +1151,7 @@
             ITreeIndexFrame interiorFrame, ITreeIndexMetaDataFrame metaFrame) throws HyracksDataException {
 
         if (loaded)
-            throw new HyracksDataException("Trying to bulk-load BTree but has BTree already been loaded.");
+            throw new HyracksDataException("Trying to bulk-load BTree but BTree has already been loaded.");
 
         BulkLoadContext ctx = new BulkLoadContext(fillFactor, (IBTreeLeafFrame) leafFrame,
                 (IBTreeInteriorFrame) interiorFrame, metaFrame);
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java
index 4c7503d..c7d43df 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java
@@ -66,8 +66,8 @@
             bufferCache.unpin(page);
         }
         tupleIndex = 0;
-		page = null;
-		pred = null;
+        page = null;
+        pred = null;
     }
 
     public ITupleReference getTuple() {
@@ -87,7 +87,7 @@
         bufferCache.unpin(page);
 
         page = nextLeaf;
-        frame.setPage(page);       
+        frame.setPage(page);
     }
 
     @Override
@@ -224,10 +224,10 @@
     @Override
     public void reset() {
         try {
-			close();
-		} catch (Exception e) {
-			e.printStackTrace();
-		}		
+            close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
     }
 
     @Override
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeSplitKey.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeSplitKey.java
index e664e5b..24a1c13 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeSplitKey.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTreeSplitKey.java
@@ -29,7 +29,7 @@
     public BTreeSplitKey(ITreeIndexTupleReference tuple) {
         this.tuple = tuple;
     }
-    
+
     public void initData(int keySize) {
         // try to reuse existing memory from a lower-level split if possible
         this.keySize = keySize;
diff --git a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IPrimitiveValueProvider.java b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IPrimitiveValueProvider.java
new file mode 100644
index 0000000..ee2f9f7
--- /dev/null
+++ b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IPrimitiveValueProvider.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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.
+ */
+
+package edu.uci.ics.hyracks.storage.am.common.api;
+
+public interface IPrimitiveValueProvider {
+    public double getValue(byte[] bytes, int offset);
+}
diff --git a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IPrimitiveValueProviderFactory.java b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IPrimitiveValueProviderFactory.java
new file mode 100644
index 0000000..3953d63
--- /dev/null
+++ b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IPrimitiveValueProviderFactory.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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.
+ */
+
+package edu.uci.ics.hyracks.storage.am.common.api;
+
+import java.io.Serializable;
+
+public interface IPrimitiveValueProviderFactory extends Serializable {
+    public IPrimitiveValueProvider createPrimitiveValueProvider();
+}
diff --git a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/AbstractTreeIndexOperatorDescriptor.java b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/AbstractTreeIndexOperatorDescriptor.java
index c905eb2..8230e19 100644
--- a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/AbstractTreeIndexOperatorDescriptor.java
+++ b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/AbstractTreeIndexOperatorDescriptor.java
@@ -21,6 +21,7 @@
 import edu.uci.ics.hyracks.api.job.JobSpecification;
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractSingleActivityOperatorDescriptor;
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
@@ -33,6 +34,7 @@
     protected final IFileSplitProvider fileSplitProvider;
 
     protected final IBinaryComparatorFactory[] comparatorFactories;
+    protected final IPrimitiveValueProviderFactory[] valueProviderFactories;
 
     protected final ITreeIndexFrameFactory interiorFrameFactory;
     protected final ITreeIndexFrameFactory leafFrameFactory;
@@ -49,7 +51,7 @@
             IIndexRegistryProvider<ITreeIndex> treeIndexRegistryProvider, IFileSplitProvider fileSplitProvider,
             ITreeIndexFrameFactory interiorFrameFactory, ITreeIndexFrameFactory leafFrameFactory,
             ITypeTrait[] typeTraits, IBinaryComparatorFactory[] comparatorFactories,
-            ITreeIndexOpHelperFactory opHelperFactory) {
+            IPrimitiveValueProviderFactory[] valueProviderFactories, ITreeIndexOpHelperFactory opHelperFactory) {
         super(spec, inputArity, outputArity);
         this.fileSplitProvider = fileSplitProvider;
         this.storageManager = storageManager;
@@ -58,6 +60,7 @@
         this.leafFrameFactory = leafFrameFactory;
         this.typeTraits = typeTraits;
         this.comparatorFactories = comparatorFactories;
+        this.valueProviderFactories = valueProviderFactories;
         this.opHelperFactory = opHelperFactory;
         if (outputArity > 0)
             recordDescriptors[0] = recDesc;
@@ -79,6 +82,11 @@
     }
 
     @Override
+    public IPrimitiveValueProviderFactory[] getTreeIndexValueProviderFactories() {
+        return valueProviderFactories;
+    }
+
+    @Override
     public ITreeIndexFrameFactory getTreeIndexInteriorFactory() {
         return interiorFrameFactory;
     }
diff --git a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/ITreeIndexOperatorDescriptorHelper.java b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/ITreeIndexOperatorDescriptorHelper.java
index 6ca4529..98806ae 100644
--- a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/ITreeIndexOperatorDescriptorHelper.java
+++ b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/ITreeIndexOperatorDescriptorHelper.java
@@ -5,6 +5,7 @@
 import edu.uci.ics.hyracks.api.dataflow.value.ITypeTrait;
 import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
@@ -14,6 +15,8 @@
 
     public IBinaryComparatorFactory[] getTreeIndexComparatorFactories();
 
+    public IPrimitiveValueProviderFactory[] getTreeIndexValueProviderFactories();
+
     public ITypeTrait[] getTreeIndexTypeTraits();
 
     public ITreeIndexFrameFactory getTreeIndexInteriorFactory();
diff --git a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexBulkLoadOperatorDescriptor.java b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexBulkLoadOperatorDescriptor.java
index 7d585b3..30fd976 100644
--- a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexBulkLoadOperatorDescriptor.java
+++ b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexBulkLoadOperatorDescriptor.java
@@ -23,6 +23,7 @@
 import edu.uci.ics.hyracks.api.job.IOperatorEnvironment;
 import edu.uci.ics.hyracks.api.job.JobSpecification;
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
@@ -37,10 +38,11 @@
     public TreeIndexBulkLoadOperatorDescriptor(JobSpecification spec, IStorageManagerInterface storageManager,
             IIndexRegistryProvider<ITreeIndex> treeIndexRegistryProvider, IFileSplitProvider fileSplitProvider,
             ITreeIndexFrameFactory interiorFrameFactory, ITreeIndexFrameFactory leafFrameFactory,
-            ITypeTrait[] typeTraits, IBinaryComparatorFactory[] comparatorFactories, int[] fieldPermutation,
-            float fillFactor, ITreeIndexOpHelperFactory opHelperFactory) {
+            ITypeTrait[] typeTraits, IBinaryComparatorFactory[] comparatorFactories,
+            IPrimitiveValueProviderFactory[] valueProviderFactories, int[] fieldPermutation, float fillFactor,
+            ITreeIndexOpHelperFactory opHelperFactory) {
         super(spec, 1, 0, null, storageManager, treeIndexRegistryProvider, fileSplitProvider, interiorFrameFactory,
-                leafFrameFactory, typeTraits, comparatorFactories, opHelperFactory);
+                leafFrameFactory, typeTraits, comparatorFactories, valueProviderFactories, opHelperFactory);
         this.fieldPermutation = fieldPermutation;
         this.fillFactor = fillFactor;
     }
diff --git a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDiskOrderScanOperatorDescriptor.java b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDiskOrderScanOperatorDescriptor.java
index 73b5323..9e18efb 100644
--- a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDiskOrderScanOperatorDescriptor.java
+++ b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDiskOrderScanOperatorDescriptor.java
@@ -36,7 +36,7 @@
             IFileSplitProvider fileSplitProvider, ITreeIndexFrameFactory interiorFrameFactory,
             ITreeIndexFrameFactory leafFrameFactory, ITypeTrait[] typeTraits, ITreeIndexOpHelperFactory opHelperFactory) {
         super(spec, 0, 1, recDesc, storageManager, treeIndexRegistryProvider, fileSplitProvider, interiorFrameFactory,
-                leafFrameFactory, typeTraits, null, opHelperFactory);
+                leafFrameFactory, typeTraits, null, null, opHelperFactory);
     }
 
     @Override
diff --git a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexFileEnlistmentOperatorDescriptor.java b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexFileEnlistmentOperatorDescriptor.java
index 0961a4f..65069b8 100644
--- a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexFileEnlistmentOperatorDescriptor.java
+++ b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexFileEnlistmentOperatorDescriptor.java
@@ -25,6 +25,7 @@
 import edu.uci.ics.hyracks.api.job.IOperatorEnvironment;
 import edu.uci.ics.hyracks.api.job.JobSpecification;
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
@@ -42,9 +43,10 @@
             IStorageManagerInterface storageManager, IIndexRegistryProvider<ITreeIndex> treeIndexRegistryProvider,
             IFileSplitProvider fileSplitProvider, ITreeIndexFrameFactory interiorFrameFactory,
             ITreeIndexFrameFactory leafFrameFactory, ITypeTrait[] typeTraits,
-            IBinaryComparatorFactory[] comparatorFactories, ITreeIndexOpHelperFactory opHelperFactory) {
+            IBinaryComparatorFactory[] comparatorFactories, IPrimitiveValueProviderFactory[] valueProviderFactories,
+            ITreeIndexOpHelperFactory opHelperFactory) {
         super(spec, 0, 0, recDesc, storageManager, treeIndexRegistryProvider, fileSplitProvider, interiorFrameFactory,
-                leafFrameFactory, typeTraits, comparatorFactories, opHelperFactory);
+                leafFrameFactory, typeTraits, comparatorFactories, valueProviderFactories, opHelperFactory);
     }
 
     @Override
diff --git a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexInsertUpdateDeleteOperatorDescriptor.java b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexInsertUpdateDeleteOperatorDescriptor.java
index c8141b9..7f242bd 100644
--- a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexInsertUpdateDeleteOperatorDescriptor.java
+++ b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexInsertUpdateDeleteOperatorDescriptor.java
@@ -24,6 +24,7 @@
 import edu.uci.ics.hyracks.api.job.IOperatorEnvironment;
 import edu.uci.ics.hyracks.api.job.JobSpecification;
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
@@ -41,10 +42,10 @@
             IStorageManagerInterface storageManager, IIndexRegistryProvider<ITreeIndex> treeIndexRegistryProvider,
             IFileSplitProvider fileSplitProvider, ITreeIndexFrameFactory interiorFrameFactory,
             ITreeIndexFrameFactory leafFrameFactory, ITypeTrait[] typeTraits,
-            IBinaryComparatorFactory[] comparatorFactories, int[] fieldPermutation, IndexOp op,
-            ITreeIndexOpHelperFactory opHelperFactory) {
+            IBinaryComparatorFactory[] comparatorFactories, IPrimitiveValueProviderFactory[] valueProviderFactories,
+            int[] fieldPermutation, IndexOp op, ITreeIndexOpHelperFactory opHelperFactory) {
         super(spec, 1, 1, recDesc, storageManager, treeIndexRegistryProvider, fileSplitProvider, interiorFrameFactory,
-                leafFrameFactory, typeTraits, comparatorFactories, opHelperFactory);
+                leafFrameFactory, typeTraits, comparatorFactories, valueProviderFactories, opHelperFactory);
         this.fieldPermutation = fieldPermutation;
         this.op = op;
     }
diff --git a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexOpHelper.java b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexOpHelper.java
index fca6d8d..281693d 100644
--- a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexOpHelper.java
+++ b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexOpHelper.java
@@ -113,7 +113,7 @@
                         comparators[i] = opDesc.getTreeIndexComparatorFactories()[i].createBinaryComparator();
                     }
 
-                    cmp = new MultiComparator(opDesc.getTreeIndexTypeTraits(), comparators);
+                    cmp = createMultiComparator(comparators);
 
                     treeIndex = createTreeIndex();
                     if (mode == IndexHelperOpenMode.CREATE) {
@@ -139,6 +139,11 @@
         throw new HyracksDataException("createTreeIndex Operation not implemented.");
     }
 
+    // MUST be overridden
+    public MultiComparator createMultiComparator(IBinaryComparator[] comparators) throws HyracksDataException {
+        throw new HyracksDataException("createComparator Operation not implemented.");
+    }
+
     public ITreeIndexCursor createDiskOrderScanCursor(ITreeIndexFrame leafFrame) throws HyracksDataException {
         return new TreeDiskOrderScanCursor(leafFrame);
     }
diff --git a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexStatsOperatorDescriptor.java b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexStatsOperatorDescriptor.java
index 574e727..5dce449 100644
--- a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexStatsOperatorDescriptor.java
+++ b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexStatsOperatorDescriptor.java
@@ -8,6 +8,7 @@
 import edu.uci.ics.hyracks.api.job.IOperatorEnvironment;
 import edu.uci.ics.hyracks.api.job.JobSpecification;
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
@@ -22,7 +23,7 @@
             ITypeTrait[] typeTraits, IBinaryComparatorFactory[] comparatorFactories,
             ITreeIndexOpHelperFactory opHelperFactory) {
         super(spec, 0, 0, null, storageManager, treeIndexRegistryProvider, fileSplitProvider, interiorFrameFactory,
-                leafFrameFactory, typeTraits, comparatorFactories, opHelperFactory);
+                leafFrameFactory, typeTraits, comparatorFactories, null, opHelperFactory);
     }
 
     @Override
diff --git a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/ophelpers/MultiComparator.java b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/ophelpers/MultiComparator.java
index 1842bf8..07e3dfe 100644
--- a/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/ophelpers/MultiComparator.java
+++ b/hyracks/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/ophelpers/MultiComparator.java
@@ -25,6 +25,7 @@
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
 import edu.uci.ics.hyracks.dataflow.common.data.comparators.IntegerBinaryComparatorFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProvider;
 
 public class MultiComparator {
 
@@ -32,6 +33,7 @@
 
     private IBinaryComparator[] cmps = null;
     private ITypeTrait[] typeTraits;
+    private IPrimitiveValueProvider[] valueProviders = null;
 
     private IBinaryComparator intCmp = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
 
@@ -44,6 +46,12 @@
         this.cmps = cmps;
     }
 
+    public MultiComparator(ITypeTrait[] typeTraits, IBinaryComparator[] cmps, IPrimitiveValueProvider[] valueProviders) {
+        this.typeTraits = typeTraits;
+        this.cmps = cmps;
+        this.valueProviders = valueProviders;
+    }
+
     public int compare(ITupleReference tupleA, ITupleReference tupleB) {
         for (int i = 0; i < cmps.length; i++) {
             int cmp = cmps[i].compare(tupleA.getFieldData(i), tupleA.getFieldStart(i), tupleA.getFieldLength(i),
@@ -99,4 +107,9 @@
     public ITypeTrait[] getTypeTraits() {
         return typeTraits;
     }
+
+    public IPrimitiveValueProvider[] getValueProviders() {
+        return valueProviders;
+    }
+
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/AbstractInvertedIndexOperatorDescriptor.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/AbstractInvertedIndexOperatorDescriptor.java
index 0d0c5bf..554f0d0 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/AbstractInvertedIndexOperatorDescriptor.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/AbstractInvertedIndexOperatorDescriptor.java
@@ -21,6 +21,7 @@
 import edu.uci.ics.hyracks.api.job.JobSpecification;
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractSingleActivityOperatorDescriptor;
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
@@ -95,6 +96,11 @@
     }
 
     @Override
+    public IPrimitiveValueProviderFactory[] getTreeIndexValueProviderFactories() {
+        return null;
+    }
+
+    @Override
     public ITypeTrait[] getTreeIndexTypeTraits() {
         return btreeTypeTraits;
     }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/AbstractUTF8StringBinaryTokenizer.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/AbstractUTF8StringBinaryTokenizer.java
index bbb32d6..02142dc 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/AbstractUTF8StringBinaryTokenizer.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/AbstractUTF8StringBinaryTokenizer.java
@@ -21,58 +21,57 @@
 
 import edu.uci.ics.hyracks.dataflow.common.data.util.StringUtils;
 
-public abstract class AbstractUTF8StringBinaryTokenizer implements
-		IBinaryTokenizer {
+public abstract class AbstractUTF8StringBinaryTokenizer implements IBinaryTokenizer {
 
-	protected byte[] data;
-	protected int start;
-	protected int length;
-	protected int tokenLength;
-	protected int index;
-	protected int utf8Length;
+    protected byte[] data;
+    protected int start;
+    protected int length;
+    protected int tokenLength;
+    protected int index;
+    protected int utf8Length;
 
-	protected final IntArray tokensStart;
-	protected final IntArray tokensLength;
-	protected final IToken token;
+    protected final IntArray tokensStart;
+    protected final IntArray tokensLength;
+    protected final IToken token;
 
-	protected final boolean ignoreTokenCount;
-	protected final boolean sourceHasTypeTag;
+    protected final boolean ignoreTokenCount;
+    protected final boolean sourceHasTypeTag;
 
-	public AbstractUTF8StringBinaryTokenizer(boolean ignoreTokenCount,
-			boolean sourceHasTypeTag, ITokenFactory tokenFactory) {
-		this.ignoreTokenCount = ignoreTokenCount;
-		this.sourceHasTypeTag = sourceHasTypeTag;
-		if (!ignoreTokenCount) {
-			tokensStart = new IntArray();
-			tokensLength = new IntArray();
-		} else {
-			tokensStart = null;
-			tokensLength = null;
-		}
-		token = tokenFactory.createToken();
-	}
+    public AbstractUTF8StringBinaryTokenizer(boolean ignoreTokenCount, boolean sourceHasTypeTag,
+            ITokenFactory tokenFactory) {
+        this.ignoreTokenCount = ignoreTokenCount;
+        this.sourceHasTypeTag = sourceHasTypeTag;
+        if (!ignoreTokenCount) {
+            tokensStart = new IntArray();
+            tokensLength = new IntArray();
+        } else {
+            tokensStart = null;
+            tokensLength = null;
+        }
+        token = tokenFactory.createToken();
+    }
 
-	@Override
-	public IToken getToken() {
-		return token;
-	}
+    @Override
+    public IToken getToken() {
+        return token;
+    }
 
-	@Override
-	public void reset(byte[] data, int start, int length) {
-		this.start = start;
-		index = this.start;
-		if (sourceHasTypeTag) {
-			index++; // skip type tag
-		}
-		utf8Length = StringUtils.getUTFLen(data, index);
-		index += 2; // skip utf8 length indicator
-		this.data = data;
-		this.length = length + start;
+    @Override
+    public void reset(byte[] data, int start, int length) {
+        this.start = start;
+        index = this.start;
+        if (sourceHasTypeTag) {
+            index++; // skip type tag
+        }
+        utf8Length = StringUtils.getUTFLen(data, index);
+        index += 2; // skip utf8 length indicator
+        this.data = data;
+        this.length = length + start;
 
-		tokenLength = 0;
-		if (!ignoreTokenCount) {
-			tokensStart.reset();
-			tokensLength.reset();
-		}
-	}
+        tokenLength = 0;
+        if (!ignoreTokenCount) {
+            tokensStart.reset();
+            tokensLength.reset();
+        }
+    }
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/AbstractUTF8Token.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/AbstractUTF8Token.java
index 92d6ac2..a15540e 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/AbstractUTF8Token.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/AbstractUTF8Token.java
@@ -25,82 +25,81 @@
 import edu.uci.ics.hyracks.dataflow.common.data.util.StringUtils;
 
 public abstract class AbstractUTF8Token implements IToken {
-	public static final int GOLDEN_RATIO_32 = 0x09e3779b9;
+    public static final int GOLDEN_RATIO_32 = 0x09e3779b9;
 
-	protected int length;
-	protected int tokenLength;
-	protected int start;
-	protected int tokenCount;
-	protected byte[] data;
-	protected final byte tokenTypeTag;
-	protected final byte countTypeTag;
+    protected int length;
+    protected int tokenLength;
+    protected int start;
+    protected int tokenCount;
+    protected byte[] data;
+    protected final byte tokenTypeTag;
+    protected final byte countTypeTag;
 
-	public AbstractUTF8Token() {
-		tokenTypeTag = -1;
-		countTypeTag = -1;
-	}
+    public AbstractUTF8Token() {
+        tokenTypeTag = -1;
+        countTypeTag = -1;
+    }
 
-	public AbstractUTF8Token(byte tokenTypeTag, byte countTypeTag) {
-		this.tokenTypeTag = tokenTypeTag;
-		this.countTypeTag = countTypeTag;
-	}
+    public AbstractUTF8Token(byte tokenTypeTag, byte countTypeTag) {
+        this.tokenTypeTag = tokenTypeTag;
+        this.countTypeTag = countTypeTag;
+    }
 
-	@Override
-	public byte[] getData() {
-		return data;
-	}
+    @Override
+    public byte[] getData() {
+        return data;
+    }
 
-	@Override
-	public int getLength() {
-		return length;
-	}
+    @Override
+    public int getLength() {
+        return length;
+    }
 
-	public int getLowerCaseUTF8Len(int size) {
-		int lowerCaseUTF8Len = 0;
-		int pos = start;
-		for (int i = 0; i < size; i++) {
-			char c = StringUtils.toLowerCase(StringUtils.charAt(data, pos));
-			lowerCaseUTF8Len += StringUtils.getModifiedUTF8Len(c);
-			pos += StringUtils.charSize(data, pos);
-		}
-		return lowerCaseUTF8Len;
-	}
+    public int getLowerCaseUTF8Len(int size) {
+        int lowerCaseUTF8Len = 0;
+        int pos = start;
+        for (int i = 0; i < size; i++) {
+            char c = StringUtils.toLowerCase(StringUtils.charAt(data, pos));
+            lowerCaseUTF8Len += StringUtils.getModifiedUTF8Len(c);
+            pos += StringUtils.charSize(data, pos);
+        }
+        return lowerCaseUTF8Len;
+    }
 
-	@Override
-	public int getStart() {
-		return start;
-	}
+    @Override
+    public int getStart() {
+        return start;
+    }
 
-	@Override
-	public int getTokenLength() {
-		return tokenLength;
-	}
+    @Override
+    public int getTokenLength() {
+        return tokenLength;
+    }
 
-	public void handleCountTypeTag(DataOutput dos) throws IOException {
-		if (countTypeTag > 0) {
-			dos.write(countTypeTag);
-		}
-	}
+    public void handleCountTypeTag(DataOutput dos) throws IOException {
+        if (countTypeTag > 0) {
+            dos.write(countTypeTag);
+        }
+    }
 
-	public void handleTokenTypeTag(DataOutput dos) throws IOException {
-		if (tokenTypeTag > 0) {
-			dos.write(tokenTypeTag);
-		}
-	}
+    public void handleTokenTypeTag(DataOutput dos) throws IOException {
+        if (tokenTypeTag > 0) {
+            dos.write(tokenTypeTag);
+        }
+    }
 
-	@Override
-	public void reset(byte[] data, int start, int length, int tokenLength,
-			int tokenCount) {
-		this.data = data;
-		this.start = start;
-		this.length = length;
-		this.tokenLength = tokenLength;
-		this.tokenCount = tokenCount;
-	}
+    @Override
+    public void reset(byte[] data, int start, int length, int tokenLength, int tokenCount) {
+        this.data = data;
+        this.start = start;
+        this.length = length;
+        this.tokenLength = tokenLength;
+        this.tokenCount = tokenCount;
+    }
 
-	@Override
-	public void serializeTokenCount(DataOutput dos) throws IOException {
-		handleCountTypeTag(dos);
-		dos.writeInt(tokenCount);
-	}
+    @Override
+    public void serializeTokenCount(DataOutput dos) throws IOException {
+        handleCountTypeTag(dos);
+        dos.writeInt(tokenCount);
+    }
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/AbstractUTF8TokenFactory.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/AbstractUTF8TokenFactory.java
index 3b0b82d..b883c9a 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/AbstractUTF8TokenFactory.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/AbstractUTF8TokenFactory.java
@@ -20,17 +20,17 @@
 package edu.uci.ics.hyracks.storage.am.invertedindex.tokenizers;
 
 public abstract class AbstractUTF8TokenFactory implements ITokenFactory {
-	private static final long serialVersionUID = 1L;
-	protected final byte tokenTypeTag;
-	protected final byte countTypeTag;
+    private static final long serialVersionUID = 1L;
+    protected final byte tokenTypeTag;
+    protected final byte countTypeTag;
 
-	public AbstractUTF8TokenFactory() {
-		tokenTypeTag = -1;
-		countTypeTag = -1;
-	}
+    public AbstractUTF8TokenFactory() {
+        tokenTypeTag = -1;
+        countTypeTag = -1;
+    }
 
-	public AbstractUTF8TokenFactory(byte tokenTypeTag, byte countTypeTag) {
-		this.tokenTypeTag = tokenTypeTag;
-		this.countTypeTag = countTypeTag;
-	}
+    public AbstractUTF8TokenFactory(byte tokenTypeTag, byte countTypeTag) {
+        this.tokenTypeTag = tokenTypeTag;
+        this.countTypeTag = countTypeTag;
+    }
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/DelimitedUTF8StringBinaryTokenizer.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/DelimitedUTF8StringBinaryTokenizer.java
index de9ad2c..f01622b 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/DelimitedUTF8StringBinaryTokenizer.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/DelimitedUTF8StringBinaryTokenizer.java
@@ -21,67 +21,61 @@
 
 import edu.uci.ics.hyracks.dataflow.common.data.util.StringUtils;
 
-public class DelimitedUTF8StringBinaryTokenizer extends
-		AbstractUTF8StringBinaryTokenizer {
+public class DelimitedUTF8StringBinaryTokenizer extends AbstractUTF8StringBinaryTokenizer {
 
-	public DelimitedUTF8StringBinaryTokenizer(boolean ignoreTokenCount,
-			boolean sourceHasTypeTag, ITokenFactory tokenFactory) {
-		super(ignoreTokenCount, sourceHasTypeTag, tokenFactory);
-	}
+    public DelimitedUTF8StringBinaryTokenizer(boolean ignoreTokenCount, boolean sourceHasTypeTag,
+            ITokenFactory tokenFactory) {
+        super(ignoreTokenCount, sourceHasTypeTag, tokenFactory);
+    }
 
-	@Override
-	public boolean hasNext() {
-		// skip delimiters
-		while (index < length && isSeparator(StringUtils.charAt(data, index))) {
-			index += StringUtils.charSize(data, index);
-		}
-		return index < length;
-	}
+    @Override
+    public boolean hasNext() {
+        // skip delimiters
+        while (index < length && isSeparator(StringUtils.charAt(data, index))) {
+            index += StringUtils.charSize(data, index);
+        }
+        return index < length;
+    }
 
-	private boolean isSeparator(char c) {
-		return !(Character.isLetterOrDigit(c)
-				|| Character.getType(c) == Character.OTHER_LETTER || Character
-				.getType(c) == Character.OTHER_NUMBER);
-	}
+    private boolean isSeparator(char c) {
+        return !(Character.isLetterOrDigit(c) || Character.getType(c) == Character.OTHER_LETTER || Character.getType(c) == Character.OTHER_NUMBER);
+    }
 
-	@Override
-	public void next() {
-		tokenLength = 0;
-		int currentTokenStart = index;
-		while (index < length && !isSeparator(StringUtils.charAt(data, index))) {
-			index += StringUtils.charSize(data, index);
-			tokenLength++;
-		}
-		int tokenCount = 1;
-		if (tokenLength > 0 && !ignoreTokenCount) {
-			// search if we got the same token before
-			for (int i = 0; i < tokensStart.length(); ++i) {
-				if (tokenLength == tokensLength.get(i)) {
-					int tokenStart = tokensStart.get(i);
-					tokenCount++; // assume we found it
-					int offset = 0;
-					int currLength = 0;
-					while (currLength < tokenLength) {
-						// case insensitive comparison
-						if (StringUtils.toLowerCase(StringUtils.charAt(data,
-								currentTokenStart + offset)) != StringUtils
-								.toLowerCase(StringUtils.charAt(data,
-										tokenStart + offset))) {
-							tokenCount--;
-							break;
-						}
-						offset += StringUtils.charSize(data, currentTokenStart
-								+ offset);
-						currLength++;
-					}
-				}
-			}
-			// add the new token to the list of seen tokens
-			tokensStart.add(currentTokenStart);
-			tokensLength.add(tokenLength);
-		}
+    @Override
+    public void next() {
+        tokenLength = 0;
+        int currentTokenStart = index;
+        while (index < length && !isSeparator(StringUtils.charAt(data, index))) {
+            index += StringUtils.charSize(data, index);
+            tokenLength++;
+        }
+        int tokenCount = 1;
+        if (tokenLength > 0 && !ignoreTokenCount) {
+            // search if we got the same token before
+            for (int i = 0; i < tokensStart.length(); ++i) {
+                if (tokenLength == tokensLength.get(i)) {
+                    int tokenStart = tokensStart.get(i);
+                    tokenCount++; // assume we found it
+                    int offset = 0;
+                    int currLength = 0;
+                    while (currLength < tokenLength) {
+                        // case insensitive comparison
+                        if (StringUtils.toLowerCase(StringUtils.charAt(data, currentTokenStart + offset)) != StringUtils
+                                .toLowerCase(StringUtils.charAt(data, tokenStart + offset))) {
+                            tokenCount--;
+                            break;
+                        }
+                        offset += StringUtils.charSize(data, currentTokenStart + offset);
+                        currLength++;
+                    }
+                }
+            }
+            // add the new token to the list of seen tokens
+            tokensStart.add(currentTokenStart);
+            tokensLength.add(tokenLength);
+        }
 
-		// set token
-		token.reset(data, currentTokenStart, index, tokenLength, tokenCount);
-	}
+        // set token
+        token.reset(data, currentTokenStart, index, tokenLength, tokenCount);
+    }
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/DelimitedUTF8StringBinaryTokenizerFactory.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/DelimitedUTF8StringBinaryTokenizerFactory.java
index 4a350b3..894501d 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/DelimitedUTF8StringBinaryTokenizerFactory.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/DelimitedUTF8StringBinaryTokenizerFactory.java
@@ -19,24 +19,22 @@
 
 package edu.uci.ics.hyracks.storage.am.invertedindex.tokenizers;
 
-public class DelimitedUTF8StringBinaryTokenizerFactory implements
-		IBinaryTokenizerFactory {
+public class DelimitedUTF8StringBinaryTokenizerFactory implements IBinaryTokenizerFactory {
 
-	private static final long serialVersionUID = 1L;
-	private final boolean ignoreTokenCount;
-	private final boolean sourceHasTypeTag;
-	private final ITokenFactory tokenFactory;
+    private static final long serialVersionUID = 1L;
+    private final boolean ignoreTokenCount;
+    private final boolean sourceHasTypeTag;
+    private final ITokenFactory tokenFactory;
 
-	public DelimitedUTF8StringBinaryTokenizerFactory(boolean ignoreTokenCount,
-			boolean sourceHasTypeTag, ITokenFactory tokenFactory) {
-		this.ignoreTokenCount = ignoreTokenCount;
-		this.sourceHasTypeTag = sourceHasTypeTag;
-		this.tokenFactory = tokenFactory;
-	}
+    public DelimitedUTF8StringBinaryTokenizerFactory(boolean ignoreTokenCount, boolean sourceHasTypeTag,
+            ITokenFactory tokenFactory) {
+        this.ignoreTokenCount = ignoreTokenCount;
+        this.sourceHasTypeTag = sourceHasTypeTag;
+        this.tokenFactory = tokenFactory;
+    }
 
-	@Override
-	public IBinaryTokenizer createTokenizer() {
-		return new DelimitedUTF8StringBinaryTokenizer(ignoreTokenCount,
-				sourceHasTypeTag, tokenFactory);
-	}
+    @Override
+    public IBinaryTokenizer createTokenizer() {
+        return new DelimitedUTF8StringBinaryTokenizer(ignoreTokenCount, sourceHasTypeTag, tokenFactory);
+    }
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/HashedUTF8NGramToken.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/HashedUTF8NGramToken.java
index 25d1a2c..8817fba 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/HashedUTF8NGramToken.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/HashedUTF8NGramToken.java
@@ -25,40 +25,40 @@
 import edu.uci.ics.hyracks.dataflow.common.data.util.StringUtils;
 
 public class HashedUTF8NGramToken extends UTF8NGramToken {
-	public HashedUTF8NGramToken(byte tokenTypeTag, byte countTypeTag) {
-		super(tokenTypeTag, countTypeTag);
-	}
+    public HashedUTF8NGramToken(byte tokenTypeTag, byte countTypeTag) {
+        super(tokenTypeTag, countTypeTag);
+    }
 
-	@Override
-	public void serializeToken(DataOutput dos) throws IOException {
-		handleTokenTypeTag(dos);
+    @Override
+    public void serializeToken(DataOutput dos) throws IOException {
+        handleTokenTypeTag(dos);
 
-		int hash = GOLDEN_RATIO_32;
+        int hash = GOLDEN_RATIO_32;
 
-		// pre chars
-		for (int i = 0; i < numPreChars; i++) {
-			hash ^= PRECHAR;
-			hash *= GOLDEN_RATIO_32;
-		}
+        // pre chars
+        for (int i = 0; i < numPreChars; i++) {
+            hash ^= PRECHAR;
+            hash *= GOLDEN_RATIO_32;
+        }
 
-		// regular chars
-		int numRegGrams = tokenLength - numPreChars - numPostChars;
-		int pos = start;
-		for (int i = 0; i < numRegGrams; i++) {
-			hash ^= StringUtils.toLowerCase(StringUtils.charAt(data, pos));
-			hash *= GOLDEN_RATIO_32;
-			pos += StringUtils.charSize(data, pos);
-		}
+        // regular chars
+        int numRegGrams = tokenLength - numPreChars - numPostChars;
+        int pos = start;
+        for (int i = 0; i < numRegGrams; i++) {
+            hash ^= StringUtils.toLowerCase(StringUtils.charAt(data, pos));
+            hash *= GOLDEN_RATIO_32;
+            pos += StringUtils.charSize(data, pos);
+        }
 
-		// post chars
-		for (int i = 0; i < numPostChars; i++) {
-			hash ^= POSTCHAR;
-			hash *= GOLDEN_RATIO_32;
-		}
+        // post chars
+        for (int i = 0; i < numPostChars; i++) {
+            hash ^= POSTCHAR;
+            hash *= GOLDEN_RATIO_32;
+        }
 
-		// token count
-		hash += tokenCount;
+        // token count
+        hash += tokenCount;
 
-		dos.writeInt(hash);
-	}
+        dos.writeInt(hash);
+    }
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/HashedUTF8NGramTokenFactory.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/HashedUTF8NGramTokenFactory.java
index 4a87793..f04594a 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/HashedUTF8NGramTokenFactory.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/HashedUTF8NGramTokenFactory.java
@@ -21,18 +21,18 @@
 
 public class HashedUTF8NGramTokenFactory extends AbstractUTF8TokenFactory {
 
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
-	public HashedUTF8NGramTokenFactory() {
-		super();
-	}
+    public HashedUTF8NGramTokenFactory() {
+        super();
+    }
 
-	public HashedUTF8NGramTokenFactory(byte tokenTypeTag, byte countTypeTag) {
-		super(tokenTypeTag, countTypeTag);
-	}
+    public HashedUTF8NGramTokenFactory(byte tokenTypeTag, byte countTypeTag) {
+        super(tokenTypeTag, countTypeTag);
+    }
 
-	@Override
-	public IToken createToken() {
-		return new HashedUTF8NGramToken(tokenTypeTag, countTypeTag);
-	}
+    @Override
+    public IToken createToken() {
+        return new HashedUTF8NGramToken(tokenTypeTag, countTypeTag);
+    }
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/HashedUTF8WordToken.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/HashedUTF8WordToken.java
index 55237ce..cb5d6f6 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/HashedUTF8WordToken.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/HashedUTF8WordToken.java
@@ -26,63 +26,61 @@
 
 public class HashedUTF8WordToken extends UTF8WordToken {
 
-	private int hash = 0;
+    private int hash = 0;
 
-	public HashedUTF8WordToken(byte tokenTypeTag, byte countTypeTag) {
-		super(tokenTypeTag, countTypeTag);
-	}
+    public HashedUTF8WordToken(byte tokenTypeTag, byte countTypeTag) {
+        super(tokenTypeTag, countTypeTag);
+    }
 
-	@Override
-	public boolean equals(Object o) {
-		if (o == null) {
-			return false;
-		}
-		if (!(o instanceof IToken)) {
-			return false;
-		}
-		IToken t = (IToken) o;
-		if (t.getTokenLength() != tokenLength) {
-			return false;
-		}
-		int offset = 0;
-		for (int i = 0; i < tokenLength; i++) {
-			if (StringUtils.charAt(t.getData(), t.getStart() + offset) != StringUtils
-					.charAt(data, start + offset)) {
-				return false;
-			}
-			offset += StringUtils.charSize(data, start + offset);
-		}
-		return true;
-	}
+    @Override
+    public boolean equals(Object o) {
+        if (o == null) {
+            return false;
+        }
+        if (!(o instanceof IToken)) {
+            return false;
+        }
+        IToken t = (IToken) o;
+        if (t.getTokenLength() != tokenLength) {
+            return false;
+        }
+        int offset = 0;
+        for (int i = 0; i < tokenLength; i++) {
+            if (StringUtils.charAt(t.getData(), t.getStart() + offset) != StringUtils.charAt(data, start + offset)) {
+                return false;
+            }
+            offset += StringUtils.charSize(data, start + offset);
+        }
+        return true;
+    }
 
-	@Override
-	public int hashCode() {
-		return hash;
-	}
+    @Override
+    public int hashCode() {
+        return hash;
+    }
 
-	@Override
-	public void reset(byte[] data, int start, int length, int tokenLength,
-			int tokenCount) {
-		super.reset(data, start, length, tokenLength, tokenCount);
+    @Override
+    public void reset(byte[] data, int start, int length, int tokenLength, int tokenCount) {
+        super.reset(data, start, length, tokenLength, tokenCount);
 
-		// pre-compute hash value using JAQL-like string hashing
-		int pos = start;
-		hash = GOLDEN_RATIO_32;
-		for (int i = 0; i < tokenLength; i++) {
-			hash ^= StringUtils.toLowerCase(StringUtils.charAt(data, pos));
-			hash *= GOLDEN_RATIO_32;
-			pos += StringUtils.charSize(data, pos);
-		}
-		hash += tokenCount;
-	}
+        // pre-compute hash value using JAQL-like string hashing
+        int pos = start;
+        hash = GOLDEN_RATIO_32;
+        for (int i = 0; i < tokenLength; i++) {
+            hash ^= StringUtils.toLowerCase(StringUtils.charAt(data, pos));
+            hash *= GOLDEN_RATIO_32;
+            pos += StringUtils.charSize(data, pos);
+        }
+        hash += tokenCount;
+    }
 
-	@Override
-	public void serializeToken(DataOutput dos) throws IOException {
-		if (tokenTypeTag > 0) {
-			dos.write(tokenTypeTag);
-		}
+    @Override
+    public void serializeToken(DataOutput dos) throws IOException {
+        if (tokenTypeTag > 0) {
+            dos.write(tokenTypeTag);
+        }
 
-		// serialize hash value
-		dos.writeInt(hash);
-	}
+        // serialize hash value
+        dos.writeInt(hash);
+    }
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/HashedUTF8WordTokenFactory.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/HashedUTF8WordTokenFactory.java
index 318f041..e8bbde8 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/HashedUTF8WordTokenFactory.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/HashedUTF8WordTokenFactory.java
@@ -21,18 +21,18 @@
 
 public class HashedUTF8WordTokenFactory extends AbstractUTF8TokenFactory {
 
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
-	public HashedUTF8WordTokenFactory() {
-		super();
-	}
+    public HashedUTF8WordTokenFactory() {
+        super();
+    }
 
-	public HashedUTF8WordTokenFactory(byte tokenTypeTag, byte countTypeTag) {
-		super(tokenTypeTag, countTypeTag);
-	}
+    public HashedUTF8WordTokenFactory(byte tokenTypeTag, byte countTypeTag) {
+        super(tokenTypeTag, countTypeTag);
+    }
 
-	@Override
-	public IToken createToken() {
-		return new HashedUTF8WordToken(tokenTypeTag, countTypeTag);
-	}
+    @Override
+    public IToken createToken() {
+        return new HashedUTF8WordToken(tokenTypeTag, countTypeTag);
+    }
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/IBinaryTokenizer.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/IBinaryTokenizer.java
index 05c6d0b..c9087d7 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/IBinaryTokenizer.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/IBinaryTokenizer.java
@@ -20,11 +20,11 @@
 package edu.uci.ics.hyracks.storage.am.invertedindex.tokenizers;
 
 public interface IBinaryTokenizer {
-	public IToken getToken();
+    public IToken getToken();
 
-	public boolean hasNext();
+    public boolean hasNext();
 
-	public void next();
+    public void next();
 
-	public void reset(byte[] data, int start, int length);
+    public void reset(byte[] data, int start, int length);
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/IBinaryTokenizerFactory.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/IBinaryTokenizerFactory.java
index bfe78ee..e6b9286 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/IBinaryTokenizerFactory.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/IBinaryTokenizerFactory.java
@@ -22,5 +22,5 @@
 import java.io.Serializable;
 
 public interface IBinaryTokenizerFactory extends Serializable {
-	public IBinaryTokenizer createTokenizer();
+    public IBinaryTokenizer createTokenizer();
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/INGramToken.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/INGramToken.java
index befc6d2..183c421 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/INGramToken.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/INGramToken.java
@@ -20,9 +20,9 @@
 package edu.uci.ics.hyracks.storage.am.invertedindex.tokenizers;
 
 public interface INGramToken {
-	public int getNumPostChars();
+    public int getNumPostChars();
 
-	public int getNumPreChars();
+    public int getNumPreChars();
 
-	public void setNumPrePostChars(int numPreChars, int numPostChars);
+    public void setNumPrePostChars(int numPreChars, int numPostChars);
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/IToken.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/IToken.java
index c1840d7..0f6e34a 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/IToken.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/IToken.java
@@ -23,18 +23,17 @@
 import java.io.IOException;
 
 public interface IToken {
-	public byte[] getData();
+    public byte[] getData();
 
-	public int getLength();
+    public int getLength();
 
-	public int getStart();
+    public int getStart();
 
-	public int getTokenLength();
+    public int getTokenLength();
 
-	public void reset(byte[] data, int start, int length, int tokenLength,
-			int tokenCount);
+    public void reset(byte[] data, int start, int length, int tokenLength, int tokenCount);
 
-	public void serializeToken(DataOutput dos) throws IOException;
+    public void serializeToken(DataOutput dos) throws IOException;
 
-	public void serializeTokenCount(DataOutput dos) throws IOException;
+    public void serializeTokenCount(DataOutput dos) throws IOException;
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/NGramUTF8StringBinaryTokenizer.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/NGramUTF8StringBinaryTokenizer.java
index 2a13f83..82a0275 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/NGramUTF8StringBinaryTokenizer.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/NGramUTF8StringBinaryTokenizer.java
@@ -21,103 +21,98 @@
 
 import edu.uci.ics.hyracks.dataflow.common.data.util.StringUtils;
 
-public class NGramUTF8StringBinaryTokenizer extends
-		AbstractUTF8StringBinaryTokenizer {
+public class NGramUTF8StringBinaryTokenizer extends AbstractUTF8StringBinaryTokenizer {
 
-	private int gramLength;
-	private boolean usePrePost;
+    private int gramLength;
+    private boolean usePrePost;
 
-	private int gramNum;
-	private int totalGrams;
+    private int gramNum;
+    private int totalGrams;
 
-	private final INGramToken concreteToken;
+    private final INGramToken concreteToken;
 
-	public NGramUTF8StringBinaryTokenizer(int gramLength, boolean usePrePost,
-			boolean ignoreTokenCount, boolean sourceHasTypeTag,
-			ITokenFactory tokenFactory) {
-		super(ignoreTokenCount, sourceHasTypeTag, tokenFactory);
-		this.gramLength = gramLength;
-		this.usePrePost = usePrePost;
-		concreteToken = (INGramToken) token;
-	}
+    public NGramUTF8StringBinaryTokenizer(int gramLength, boolean usePrePost, boolean ignoreTokenCount,
+            boolean sourceHasTypeTag, ITokenFactory tokenFactory) {
+        super(ignoreTokenCount, sourceHasTypeTag, tokenFactory);
+        this.gramLength = gramLength;
+        this.usePrePost = usePrePost;
+        concreteToken = (INGramToken) token;
+    }
 
-	@Override
-	public boolean hasNext() {
-		if (gramNum < totalGrams) {
-			return true;
-		} else {
-			return false;
-		}
-	}
+    @Override
+    public boolean hasNext() {
+        if (gramNum < totalGrams) {
+            return true;
+        } else {
+            return false;
+        }
+    }
 
-	@Override
-	public void next() {
-		int currentTokenStart = index;
-		int tokenCount = 1;
-		int numPreChars = 0;
-		int numPostChars = 0;
-		if (usePrePost) {
-			numPreChars = Math.max(gramLength - gramNum - 1, 0);
-			numPostChars = (gramNum > totalGrams - gramLength) ? gramLength
-					- totalGrams + gramNum : 0;
-		}
-		gramNum++;
+    @Override
+    public void next() {
+        int currentTokenStart = index;
+        int tokenCount = 1;
+        int numPreChars = 0;
+        int numPostChars = 0;
+        if (usePrePost) {
+            numPreChars = Math.max(gramLength - gramNum - 1, 0);
+            numPostChars = (gramNum > totalGrams - gramLength) ? gramLength - totalGrams + gramNum : 0;
+        }
+        gramNum++;
 
-		concreteToken.setNumPrePostChars(numPreChars, numPostChars);
-		if (numPreChars == 0) {
-			index += StringUtils.charSize(data, index);
-		}
+        concreteToken.setNumPrePostChars(numPreChars, numPostChars);
+        if (numPreChars == 0) {
+            index += StringUtils.charSize(data, index);
+        }
 
-		// compute token count
-		// ignore pre and post grams for duplicate detection
-		if (!ignoreTokenCount && numPreChars == 0 && numPostChars == 0) {
-			int tmpIndex = start;
-			while (tmpIndex < currentTokenStart) {
-				tokenCount++; // assume found
-				int offset = 0;
-				for (int j = 0; j < gramLength; j++) {
-					if (StringUtils.toLowerCase(StringUtils.charAt(data,
-							currentTokenStart + offset)) != StringUtils
-							.toLowerCase(StringUtils.charAt(data, tmpIndex
-									+ offset))) {
-						tokenCount--;
-						break;
-					}
-					offset += StringUtils.charSize(data, tmpIndex + offset);
-				}
-				tmpIndex += StringUtils.charSize(data, tmpIndex);
-			}
-		}
+        // compute token count
+        // ignore pre and post grams for duplicate detection
+        if (!ignoreTokenCount && numPreChars == 0 && numPostChars == 0) {
+            int tmpIndex = start;
+            while (tmpIndex < currentTokenStart) {
+                tokenCount++; // assume found
+                int offset = 0;
+                for (int j = 0; j < gramLength; j++) {
+                    if (StringUtils.toLowerCase(StringUtils.charAt(data, currentTokenStart + offset)) != StringUtils
+                            .toLowerCase(StringUtils.charAt(data, tmpIndex + offset))) {
+                        tokenCount--;
+                        break;
+                    }
+                    offset += StringUtils.charSize(data, tmpIndex + offset);
+                }
+                tmpIndex += StringUtils.charSize(data, tmpIndex);
+            }
+        }
 
-		// set token
-		token.reset(data, currentTokenStart, length, gramLength, tokenCount);
-	}
+        // set token
+        token.reset(data, currentTokenStart, length, gramLength, tokenCount);
+    }
 
-	@Override
-	public void reset(byte[] data, int start, int length) {
-		super.reset(data, start, length);
-		gramNum = 0;
+    @Override
+    public void reset(byte[] data, int start, int length) {
+        super.reset(data, start, length);
+        gramNum = 0;
 
-		int numChars = 0;
-		int pos = index;
-		int end = pos + utf8Length;
-		while (pos < end) {
-			numChars++;
-			pos += StringUtils.charSize(data, pos);
-		}
+        int numChars = 0;
+        int pos = index;
+        int end = pos + utf8Length;
+        while (pos < end) {
+            numChars++;
+            pos += StringUtils.charSize(data, pos);
+        }
 
-		if (usePrePost) {
-			totalGrams = numChars + gramLength - 1;
-		} else {
-			totalGrams = numChars - gramLength + 1;
-		}
-	}
+        if (usePrePost) {
+            totalGrams = numChars + gramLength - 1;
+        } else {
+            totalGrams = numChars - gramLength + 1;
+        }
+    }
 
-	public void setGramlength(int gramLength) {
-		this.gramLength = gramLength;
-	}
+    public void setGramlength(int gramLength) {
+        this.gramLength = gramLength;
+    }
 
-	public void setPrePost(boolean usePrePost) {
-		this.usePrePost = usePrePost;
-	}
+    public void setPrePost(boolean usePrePost) {
+        this.usePrePost = usePrePost;
+    }
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/UTF8NGramToken.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/UTF8NGramToken.java
index 6b6406f..589cf6a 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/UTF8NGramToken.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/UTF8NGramToken.java
@@ -26,61 +26,60 @@
 
 public class UTF8NGramToken extends AbstractUTF8Token implements INGramToken {
 
-	public final static char PRECHAR = '#';
+    public final static char PRECHAR = '#';
 
-	public final static char POSTCHAR = '$';
+    public final static char POSTCHAR = '$';
 
-	protected int numPreChars;
-	protected int numPostChars;
+    protected int numPreChars;
+    protected int numPostChars;
 
-	public UTF8NGramToken(byte tokenTypeTag, byte countTypeTag) {
-		super(tokenTypeTag, countTypeTag);
-	}
+    public UTF8NGramToken(byte tokenTypeTag, byte countTypeTag) {
+        super(tokenTypeTag, countTypeTag);
+    }
 
-	@Override
-	public int getNumPostChars() {
-		return numPreChars;
-	}
+    @Override
+    public int getNumPostChars() {
+        return numPreChars;
+    }
 
-	@Override
-	public int getNumPreChars() {
-		return numPostChars;
-	}
+    @Override
+    public int getNumPreChars() {
+        return numPostChars;
+    }
 
-	@Override
-	public void serializeToken(DataOutput dos) throws IOException {
-		handleTokenTypeTag(dos);
+    @Override
+    public void serializeToken(DataOutput dos) throws IOException {
+        handleTokenTypeTag(dos);
 
-		// regular chars
-		int numRegChars = tokenLength - numPreChars - numPostChars;
+        // regular chars
+        int numRegChars = tokenLength - numPreChars - numPostChars;
 
-		// assuming pre and post char need 1-byte each in utf8
-		int tokenUTF8Len = getLowerCaseUTF8Len(numRegChars) + numPreChars
-				+ numPostChars;
+        // assuming pre and post char need 1-byte each in utf8
+        int tokenUTF8Len = getLowerCaseUTF8Len(numRegChars) + numPreChars + numPostChars;
 
-		// write utf8 length indicator
-		StringUtils.writeUTF8Len(tokenUTF8Len, dos);
+        // write utf8 length indicator
+        StringUtils.writeUTF8Len(tokenUTF8Len, dos);
 
-		// pre chars
-		for (int i = 0; i < numPreChars; i++) {
-			StringUtils.writeCharAsModifiedUTF8(PRECHAR, dos);
-		}
+        // pre chars
+        for (int i = 0; i < numPreChars; i++) {
+            StringUtils.writeCharAsModifiedUTF8(PRECHAR, dos);
+        }
 
-		int pos = start;
-		for (int i = 0; i < numRegChars; i++) {
-			char c = StringUtils.toLowerCase(StringUtils.charAt(data, pos));
-			StringUtils.writeCharAsModifiedUTF8(c, dos);
-			pos += StringUtils.charSize(data, pos);
-		}
+        int pos = start;
+        for (int i = 0; i < numRegChars; i++) {
+            char c = StringUtils.toLowerCase(StringUtils.charAt(data, pos));
+            StringUtils.writeCharAsModifiedUTF8(c, dos);
+            pos += StringUtils.charSize(data, pos);
+        }
 
-		// post chars
-		for (int i = 0; i < numPostChars; i++) {
-			StringUtils.writeCharAsModifiedUTF8(POSTCHAR, dos);
-		}
-	}
+        // post chars
+        for (int i = 0; i < numPostChars; i++) {
+            StringUtils.writeCharAsModifiedUTF8(POSTCHAR, dos);
+        }
+    }
 
-	public void setNumPrePostChars(int numPreChars, int numPostChars) {
-		this.numPreChars = numPreChars;
-		this.numPostChars = numPostChars;
-	}
+    public void setNumPrePostChars(int numPreChars, int numPostChars) {
+        this.numPreChars = numPreChars;
+        this.numPostChars = numPostChars;
+    }
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/UTF8NGramTokenFactory.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/UTF8NGramTokenFactory.java
index 968d8e1..7a72caa 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/UTF8NGramTokenFactory.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/UTF8NGramTokenFactory.java
@@ -21,19 +21,19 @@
 
 public class UTF8NGramTokenFactory extends AbstractUTF8TokenFactory {
 
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
-	public UTF8NGramTokenFactory() {
-		super();
-	}
+    public UTF8NGramTokenFactory() {
+        super();
+    }
 
-	public UTF8NGramTokenFactory(byte tokenTypeTag, byte countTypeTag) {
-		super(tokenTypeTag, countTypeTag);
-	}
+    public UTF8NGramTokenFactory(byte tokenTypeTag, byte countTypeTag) {
+        super(tokenTypeTag, countTypeTag);
+    }
 
-	@Override
-	public IToken createToken() {
-		return new UTF8NGramToken(tokenTypeTag, countTypeTag);
-	}
+    @Override
+    public IToken createToken() {
+        return new UTF8NGramToken(tokenTypeTag, countTypeTag);
+    }
 
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/UTF8WordToken.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/UTF8WordToken.java
index 25e0cd3..c157909 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/UTF8WordToken.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/UTF8WordToken.java
@@ -26,21 +26,21 @@
 
 public class UTF8WordToken extends AbstractUTF8Token {
 
-	public UTF8WordToken(byte tokenTypeTag, byte countTypeTag) {
-		super(tokenTypeTag, countTypeTag);
-	}
+    public UTF8WordToken(byte tokenTypeTag, byte countTypeTag) {
+        super(tokenTypeTag, countTypeTag);
+    }
 
-	@Override
-	public void serializeToken(DataOutput dos) throws IOException {
-		handleTokenTypeTag(dos);
+    @Override
+    public void serializeToken(DataOutput dos) throws IOException {
+        handleTokenTypeTag(dos);
 
-		int tokenUTF8Len = getLowerCaseUTF8Len(tokenLength);
-		StringUtils.writeUTF8Len(tokenUTF8Len, dos);
-		int pos = start;
-		for (int i = 0; i < tokenLength; i++) {
-			char c = StringUtils.toLowerCase(StringUtils.charAt(data, pos));
-			StringUtils.writeCharAsModifiedUTF8(c, dos);
-			pos += StringUtils.charSize(data, pos);
-		}
-	}
+        int tokenUTF8Len = getLowerCaseUTF8Len(tokenLength);
+        StringUtils.writeUTF8Len(tokenUTF8Len, dos);
+        int pos = start;
+        for (int i = 0; i < tokenLength; i++) {
+            char c = StringUtils.toLowerCase(StringUtils.charAt(data, pos));
+            StringUtils.writeCharAsModifiedUTF8(c, dos);
+            pos += StringUtils.charSize(data, pos);
+        }
+    }
 }
diff --git a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/UTF8WordTokenFactory.java b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/UTF8WordTokenFactory.java
index 4358254..471747b 100644
--- a/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/UTF8WordTokenFactory.java
+++ b/hyracks/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/tokenizers/UTF8WordTokenFactory.java
@@ -21,19 +21,19 @@
 
 public class UTF8WordTokenFactory extends AbstractUTF8TokenFactory {
 
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
-	public UTF8WordTokenFactory() {
-		super();
-	}
+    public UTF8WordTokenFactory() {
+        super();
+    }
 
-	public UTF8WordTokenFactory(byte tokenTypeTag, byte countTypeTag) {
-		super(tokenTypeTag, countTypeTag);
-	}
+    public UTF8WordTokenFactory(byte tokenTypeTag, byte countTypeTag) {
+        super(tokenTypeTag, countTypeTag);
+    }
 
-	@Override
-	public IToken createToken() {
-		return new UTF8WordToken(tokenTypeTag, countTypeTag);
-	}
+    @Override
+    public IToken createToken() {
+        return new UTF8WordToken(tokenTypeTag, countTypeTag);
+    }
 
 }
diff --git a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/api/IRTreeFrame.java b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/api/IRTreeFrame.java
index ebc17b5..5986a1e 100644
--- a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/api/IRTreeFrame.java
+++ b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/api/IRTreeFrame.java
@@ -27,8 +27,6 @@
 
     public ITreeIndexTupleReference createTupleReference();
 
-    public void generateDist(ITupleReference tuple, TupleEntryArrayList entries, Rectangle rec, int start, int end);
-
     public void computeMBR(ISplitKey splitKey, MultiComparator cmp);
 
     public void insert(ITupleReference tuple, MultiComparator cmp, int tupleIndex) throws Exception;
diff --git a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeOpHelper.java b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeOpHelper.java
index 5b8931d..27c438a 100644
--- a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeOpHelper.java
+++ b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeOpHelper.java
@@ -16,8 +16,10 @@
 package edu.uci.ics.hyracks.storage.am.rtree.dataflow;
 
 import edu.uci.ics.hyracks.api.context.IHyracksStageletContext;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProvider;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrameFactory;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.ITreeIndexOperatorDescriptorHelper;
@@ -31,8 +33,6 @@
 
 public class RTreeOpHelper extends TreeIndexOpHelper {
 
-    protected MultiComparator interiorCmp;
-
     public RTreeOpHelper(ITreeIndexOperatorDescriptorHelper opDesc, IHyracksStageletContext ctx, int partition,
             IndexHelperOpenMode mode) {
         super(opDesc, ctx, partition, mode);
@@ -47,4 +47,13 @@
         return new RTree(bufferCache, freePageManager, opDesc.getTreeIndexInteriorFactory(),
                 opDesc.getTreeIndexLeafFactory(), cmp);
     }
+
+    public MultiComparator createMultiComparator(IBinaryComparator[] comparators) throws HyracksDataException {
+        IPrimitiveValueProvider[] keyValueProvider = new IPrimitiveValueProvider[opDesc
+                .getTreeIndexValueProviderFactories().length];
+        for (int i = 0; i < opDesc.getTreeIndexComparatorFactories().length; i++) {
+            keyValueProvider[i] = opDesc.getTreeIndexValueProviderFactories()[i].createPrimitiveValueProvider();
+        }
+        return new MultiComparator(opDesc.getTreeIndexTypeTraits(), comparators, keyValueProvider);
+    }
 }
diff --git a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeSearchOperatorDescriptor.java b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeSearchOperatorDescriptor.java
index 8aab763..0ce8c9b 100644
--- a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeSearchOperatorDescriptor.java
+++ b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeSearchOperatorDescriptor.java
@@ -24,6 +24,7 @@
 import edu.uci.ics.hyracks.api.job.IOperatorEnvironment;
 import edu.uci.ics.hyracks.api.job.JobSpecification;
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.AbstractTreeIndexOperatorDescriptor;
@@ -41,9 +42,10 @@
             IStorageManagerInterface storageManager, IIndexRegistryProvider<ITreeIndex> treeIndexRegistryProvider,
             IFileSplitProvider fileSplitProvider, ITreeIndexFrameFactory interiorFrameFactory,
             ITreeIndexFrameFactory leafFrameFactory, ITypeTrait[] typeTraits,
-            IBinaryComparatorFactory[] comparatorFactories, int[] keyFields, ITreeIndexOpHelperFactory opHelperFactory) {
+            IBinaryComparatorFactory[] comparatorFactories, IPrimitiveValueProviderFactory[] valueProviderFactories,
+            int[] keyFields, ITreeIndexOpHelperFactory opHelperFactory) {
         super(spec, 1, 1, recDesc, storageManager, treeIndexRegistryProvider, fileSplitProvider, interiorFrameFactory,
-                leafFrameFactory, typeTraits, comparatorFactories, opHelperFactory);
+                leafFrameFactory, typeTraits, comparatorFactories, valueProviderFactories, opHelperFactory);
         this.keyFields = keyFields;
     }
 
diff --git a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeSearchOperatorNodePushable.java b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeSearchOperatorNodePushable.java
index 6a13d9f..bfc2744 100644
--- a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeSearchOperatorNodePushable.java
+++ b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeSearchOperatorNodePushable.java
@@ -29,6 +29,7 @@
 import edu.uci.ics.hyracks.dataflow.common.comm.util.FrameUtils;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractUnaryInputUnaryOutputOperatorNodePushable;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProvider;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrame;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.AbstractTreeIndexOperatorDescriptor;
@@ -97,10 +98,15 @@
             for (int i = 0; i < keySearchFields; i++) {
                 keySearchComparators[i] = rtree.getCmp().getComparators()[i];
             }
-            cmp = new MultiComparator(rtree.getCmp().getTypeTraits(), keySearchComparators);
+
+            IPrimitiveValueProvider[] keyValueProvider = new IPrimitiveValueProvider[keySearchFields];
+            for (int i = 0; i < keySearchFields; i++) {
+                keyValueProvider[i] = rtree.getCmp().getValueProviders()[i];
+            }
+
+            cmp = new MultiComparator(rtree.getCmp().getTypeTraits(), keySearchComparators, keyValueProvider);
 
             searchPred = new SearchPredicate(searchKey, cmp);
-            accessor = new FrameTupleAccessor(treeIndexOpHelper.getHyracksStageletContext().getFrameSize(), recDesc);
 
             writeBuffer = treeIndexOpHelper.getHyracksStageletContext().allocateFrame();
             tb = new ArrayTupleBuilder(rtree.getCmp().getFieldCount());
diff --git a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMFrame.java b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMFrame.java
index 17c10e5..4dc175a 100644
--- a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMFrame.java
+++ b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMFrame.java
@@ -17,7 +17,6 @@
 
 import java.util.ArrayList;
 
-import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
 import edu.uci.ics.hyracks.storage.am.common.api.ISplitKey;
@@ -137,20 +136,21 @@
         return ret;
     }
 
-    public void generateDist(ITupleReference tuple, TupleEntryArrayList entries, Rectangle rec, int start, int end) {
+    public void generateDist(ITupleReference tuple, TupleEntryArrayList entries, Rectangle rec, int start, int end,
+            MultiComparator cmp) {
         int j = 0;
         while (entries.get(j).getTupleIndex() == -1) {
             j++;
         }
         frameTuple.resetByTupleIndex(this, entries.get(j).getTupleIndex());
-        rec.set(frameTuple);
+        rec.set(frameTuple, cmp);
         for (int i = start; i < end; ++i) {
             if (i != j) {
                 if (entries.get(i).getTupleIndex() != -1) {
                     frameTuple.resetByTupleIndex(this, entries.get(i).getTupleIndex());
-                    rec.enlarge(frameTuple);
+                    rec.enlarge(frameTuple, cmp);
                 } else {
-                    rec.enlarge(tuple);
+                    rec.enlarge(tuple, cmp);
                 }
             }
         }
diff --git a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrame.java b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrame.java
index d03c5e9..6080c9d 100644
--- a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrame.java
+++ b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrame.java
@@ -24,7 +24,6 @@
 import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
-import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
 import edu.uci.ics.hyracks.storage.am.common.api.ISplitKey;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrame;
@@ -205,7 +204,6 @@
                 return -1;
             }
         }
-        // return buf.getInt(frameTuple.getFieldStart(cmp.getKeyFieldCount()));
         return buf.getInt(getChildPointerOff(frameTuple, cmp));
     }
 
@@ -320,17 +318,16 @@
             for (int k = 0; k < getTupleCount(); ++k) {
 
                 frameTuple.resetByTupleIndex(this, k);
-
-                double LowerKey = DoubleSerializerDeserializer.getDouble(frameTuple.getFieldData(i),
+                double LowerKey = cmp.getValueProviders()[i].getValue(frameTuple.getFieldData(i),
                         frameTuple.getFieldStart(i));
-                double UpperKey = DoubleSerializerDeserializer.getDouble(frameTuple.getFieldData(j),
+                double UpperKey = cmp.getValueProviders()[j].getValue(frameTuple.getFieldData(j),
                         frameTuple.getFieldStart(j));
 
                 tupleEntries1.add(k, LowerKey);
                 tupleEntries2.add(k, UpperKey);
             }
-            double LowerKey = DoubleSerializerDeserializer.getDouble(tuple.getFieldData(i), tuple.getFieldStart(i));
-            double UpperKey = DoubleSerializerDeserializer.getDouble(tuple.getFieldData(j), tuple.getFieldStart(j));
+            double LowerKey = cmp.getValueProviders()[i].getValue(tuple.getFieldData(i), tuple.getFieldStart(i));
+            double UpperKey = cmp.getValueProviders()[j].getValue(tuple.getFieldData(j), tuple.getFieldStart(j));
 
             tupleEntries1.add(-1, LowerKey);
             tupleEntries2.add(-1, UpperKey);
@@ -343,10 +340,10 @@
             for (int k = 1; k <= splitDistribution; ++k) {
                 int d = m - 1 + k;
 
-                generateDist(tuple, tupleEntries1, rec[0], 0, d);
-                generateDist(tuple, tupleEntries2, rec[1], 0, d);
-                generateDist(tuple, tupleEntries1, rec[2], d, getTupleCount() + 1);
-                generateDist(tuple, tupleEntries2, rec[3], d, getTupleCount() + 1);
+                generateDist(tuple, tupleEntries1, rec[0], 0, d, cmp);
+                generateDist(tuple, tupleEntries2, rec[1], 0, d, cmp);
+                generateDist(tuple, tupleEntries1, rec[2], d, getTupleCount() + 1, cmp);
+                generateDist(tuple, tupleEntries2, rec[3], d, getTupleCount() + 1, cmp);
 
                 // calculate the margin of the distributions
                 lowerMargin += rec[0].margin() + rec[2].margin();
@@ -367,11 +364,11 @@
 
         for (int i = 0; i < getTupleCount(); ++i) {
             frameTuple.resetByTupleIndex(this, i);
-            double key = DoubleSerializerDeserializer.getDouble(frameTuple.getFieldData(splitAxis + sortOrder),
-                    frameTuple.getFieldStart(splitAxis + sortOrder));
+            double key = cmp.getValueProviders()[splitAxis + sortOrder].getValue(
+                    frameTuple.getFieldData(splitAxis + sortOrder), frameTuple.getFieldStart(splitAxis + sortOrder));
             tupleEntries1.add(i, key);
         }
-        double key = DoubleSerializerDeserializer.getDouble(tuple.getFieldData(splitAxis + sortOrder),
+        double key = cmp.getValueProviders()[splitAxis + sortOrder].getValue(tuple.getFieldData(splitAxis + sortOrder),
                 tuple.getFieldStart(splitAxis + sortOrder));
         tupleEntries1.add(-1, key);
         tupleEntries1.sort(EntriesOrder.ASCENDING, getTupleCount() + 1);
@@ -382,8 +379,8 @@
         for (int i = 1; i <= splitDistribution; ++i) {
             int d = m - 1 + i;
 
-            generateDist(tuple, tupleEntries1, rec[0], 0, d);
-            generateDist(tuple, tupleEntries1, rec[2], d, getTupleCount() + 1);
+            generateDist(tuple, tupleEntries1, rec[0], 0, d, cmp);
+            generateDist(tuple, tupleEntries1, rec[2], d, getTupleCount() + 1, cmp);
 
             double overlap = rec[0].overlappedArea(rec[2]);
             if (overlap < minOverlap) {
@@ -534,9 +531,9 @@
                         tuple1.getFieldLength(i), tupleToBeInserted.getFieldData(i),
                         tupleToBeInserted.getFieldStart(i), tupleToBeInserted.getFieldLength(i));
                 if (c < 0) {
-                    pLow1 = DoubleSerializerDeserializer.getDouble(tuple1.getFieldData(i), tuple1.getFieldStart(i));
+                    pLow1 = cmp.getValueProviders()[i].getValue(tuple1.getFieldData(i), tuple1.getFieldStart(i));
                 } else {
-                    pLow1 = DoubleSerializerDeserializer.getDouble(tupleToBeInserted.getFieldData(i),
+                    pLow1 = cmp.getValueProviders()[i].getValue(tupleToBeInserted.getFieldData(i),
                             tupleToBeInserted.getFieldStart(i));
                 }
 
@@ -544,18 +541,18 @@
                         tuple1.getFieldLength(j), tupleToBeInserted.getFieldData(j),
                         tupleToBeInserted.getFieldStart(j), tupleToBeInserted.getFieldLength(j));
                 if (c > 0) {
-                    pHigh1 = DoubleSerializerDeserializer.getDouble(tuple1.getFieldData(j), tuple1.getFieldStart(j));
+                    pHigh1 = cmp.getValueProviders()[j].getValue(tuple1.getFieldData(j), tuple1.getFieldStart(j));
                 } else {
-                    pHigh1 = DoubleSerializerDeserializer.getDouble(tupleToBeInserted.getFieldData(j),
+                    pHigh1 = cmp.getValueProviders()[j].getValue(tupleToBeInserted.getFieldData(j),
                             tupleToBeInserted.getFieldStart(j));
                 }
             } else {
-                pLow1 = DoubleSerializerDeserializer.getDouble(tuple1.getFieldData(i), tuple1.getFieldStart(i));
-                pHigh1 = DoubleSerializerDeserializer.getDouble(tuple1.getFieldData(j), tuple1.getFieldStart(j));
+                pLow1 = cmp.getValueProviders()[i].getValue(tuple1.getFieldData(i), tuple1.getFieldStart(i));
+                pHigh1 = cmp.getValueProviders()[j].getValue(tuple1.getFieldData(j), tuple1.getFieldStart(j));
             }
 
-            double pLow2 = DoubleSerializerDeserializer.getDouble(tuple2.getFieldData(i), tuple2.getFieldStart(i));
-            double pHigh2 = DoubleSerializerDeserializer.getDouble(tuple2.getFieldData(j), tuple2.getFieldStart(j));
+            double pLow2 = cmp.getValueProviders()[i].getValue(tuple2.getFieldData(i), tuple2.getFieldStart(i));
+            double pHigh2 = cmp.getValueProviders()[j].getValue(tuple2.getFieldData(j), tuple2.getFieldStart(j));
 
             if (pLow1 > pHigh2 || pHigh1 < pLow2) {
                 return 0.0;
@@ -580,9 +577,9 @@
                     tuple.getFieldLength(i), tupleToBeInserted.getFieldData(i), tupleToBeInserted.getFieldStart(i),
                     tupleToBeInserted.getFieldLength(i));
             if (c < 0) {
-                pLow = DoubleSerializerDeserializer.getDouble(tuple.getFieldData(i), tuple.getFieldStart(i));
+                pLow = cmp.getValueProviders()[i].getValue(tuple.getFieldData(i), tuple.getFieldStart(i));
             } else {
-                pLow = DoubleSerializerDeserializer.getDouble(tupleToBeInserted.getFieldData(i),
+                pLow = cmp.getValueProviders()[i].getValue(tupleToBeInserted.getFieldData(i),
                         tupleToBeInserted.getFieldStart(i));
             }
 
@@ -590,9 +587,9 @@
                     tupleToBeInserted.getFieldData(j), tupleToBeInserted.getFieldStart(j),
                     tupleToBeInserted.getFieldLength(j));
             if (c > 0) {
-                pHigh = DoubleSerializerDeserializer.getDouble(tuple.getFieldData(j), tuple.getFieldStart(j));
+                pHigh = cmp.getValueProviders()[j].getValue(tuple.getFieldData(j), tuple.getFieldStart(j));
             } else {
-                pHigh = DoubleSerializerDeserializer.getDouble(tupleToBeInserted.getFieldData(j),
+                pHigh = cmp.getValueProviders()[j].getValue(tupleToBeInserted.getFieldData(j),
                         tupleToBeInserted.getFieldStart(j));
             }
             areaAfterEnlarge *= pHigh - pLow;
@@ -605,8 +602,8 @@
         int maxFieldPos = cmp.getKeyFieldCount() / 2;
         for (int i = 0; i < maxFieldPos; i++) {
             int j = maxFieldPos + i;
-            area *= DoubleSerializerDeserializer.getDouble(tuple.getFieldData(j), tuple.getFieldStart(j))
-                    - DoubleSerializerDeserializer.getDouble(tuple.getFieldData(i), tuple.getFieldStart(i));
+            area *= cmp.getValueProviders()[j].getValue(tuple.getFieldData(j), tuple.getFieldStart(j))
+                    - cmp.getValueProviders()[i].getValue(tuple.getFieldData(i), tuple.getFieldStart(i));
         }
         return area;
     }
diff --git a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrameFactory.java b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrameFactory.java
index 9fd5a54..2a12e48 100644
--- a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrameFactory.java
+++ b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrameFactory.java
@@ -27,6 +27,9 @@
 
     public RTreeNSMInteriorFrameFactory(ITreeIndexTupleWriterFactory tupleWriterFactory, int keyFieldCount) {
         this.tupleWriterFactory = tupleWriterFactory;
+        if (keyFieldCount % 2 != 0) {
+            throw new IllegalArgumentException("The key has different number of dimensions.");
+        }
         this.keyFieldCount = keyFieldCount;
     }
 
diff --git a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrame.java b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrame.java
index 7ebe974..2cf7a97 100644
--- a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrame.java
+++ b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrame.java
@@ -16,7 +16,6 @@
 package edu.uci.ics.hyracks.storage.am.rtree.frames;
 
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
-import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
 import edu.uci.ics.hyracks.storage.am.common.api.ISplitKey;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrame;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleReference;
@@ -90,16 +89,16 @@
 
                 frameTuple.resetByTupleIndex(this, k);
 
-                double LowerKey = DoubleSerializerDeserializer.getDouble(frameTuple.getFieldData(i),
+                double LowerKey = cmp.getValueProviders()[i].getValue(frameTuple.getFieldData(i),
                         frameTuple.getFieldStart(i));
-                double UpperKey = DoubleSerializerDeserializer.getDouble(frameTuple.getFieldData(j),
+                double UpperKey = cmp.getValueProviders()[j].getValue(frameTuple.getFieldData(j),
                         frameTuple.getFieldStart(j));
 
                 tupleEntries1.add(k, LowerKey);
                 tupleEntries2.add(k, UpperKey);
             }
-            double LowerKey = DoubleSerializerDeserializer.getDouble(tuple.getFieldData(i), tuple.getFieldStart(i));
-            double UpperKey = DoubleSerializerDeserializer.getDouble(tuple.getFieldData(j), tuple.getFieldStart(j));
+            double LowerKey = cmp.getValueProviders()[i].getValue(tuple.getFieldData(i), tuple.getFieldStart(i));
+            double UpperKey = cmp.getValueProviders()[j].getValue(tuple.getFieldData(j), tuple.getFieldStart(j));
 
             tupleEntries1.add(-1, LowerKey);
             tupleEntries2.add(-1, UpperKey);
@@ -112,10 +111,10 @@
             for (int k = 1; k <= splitDistribution; ++k) {
                 int d = m - 1 + k;
 
-                generateDist(tuple, tupleEntries1, rec[0], 0, d);
-                generateDist(tuple, tupleEntries2, rec[1], 0, d);
-                generateDist(tuple, tupleEntries1, rec[2], d, getTupleCount() + 1);
-                generateDist(tuple, tupleEntries2, rec[3], d, getTupleCount() + 1);
+                generateDist(tuple, tupleEntries1, rec[0], 0, d, cmp);
+                generateDist(tuple, tupleEntries2, rec[1], 0, d, cmp);
+                generateDist(tuple, tupleEntries1, rec[2], d, getTupleCount() + 1, cmp);
+                generateDist(tuple, tupleEntries2, rec[3], d, getTupleCount() + 1, cmp);
 
                 // calculate the margin of the distributions
                 lowerMargin += rec[0].margin() + rec[2].margin();
@@ -136,11 +135,11 @@
 
         for (int i = 0; i < getTupleCount(); ++i) {
             frameTuple.resetByTupleIndex(this, i);
-            double key = DoubleSerializerDeserializer.getDouble(frameTuple.getFieldData(splitAxis + sortOrder),
-                    frameTuple.getFieldStart(splitAxis + sortOrder));
+            double key = cmp.getValueProviders()[splitAxis + sortOrder].getValue(
+                    frameTuple.getFieldData(splitAxis + sortOrder), frameTuple.getFieldStart(splitAxis + sortOrder));
             tupleEntries1.add(i, key);
         }
-        double key = DoubleSerializerDeserializer.getDouble(tuple.getFieldData(splitAxis + sortOrder),
+        double key = cmp.getValueProviders()[splitAxis + sortOrder].getValue(tuple.getFieldData(splitAxis + sortOrder),
                 tuple.getFieldStart(splitAxis + sortOrder));
         tupleEntries1.add(-1, key);
         tupleEntries1.sort(EntriesOrder.ASCENDING, getTupleCount() + 1);
@@ -151,8 +150,8 @@
         for (int i = 1; i <= splitDistribution; ++i) {
             int d = m - 1 + i;
 
-            generateDist(tuple, tupleEntries1, rec[0], 0, d);
-            generateDist(tuple, tupleEntries1, rec[2], d, getTupleCount() + 1);
+            generateDist(tuple, tupleEntries1, rec[0], 0, d, cmp);
+            generateDist(tuple, tupleEntries1, rec[2], d, getTupleCount() + 1, cmp);
 
             double overlap = rec[0].overlappedArea(rec[2]);
             if (overlap < minOverlap) {
diff --git a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrameFactory.java b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrameFactory.java
index 7da7f26..70c6456 100644
--- a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrameFactory.java
+++ b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrameFactory.java
@@ -27,6 +27,9 @@
 
     public RTreeNSMLeafFrameFactory(ITreeIndexTupleWriterFactory tupleWriterFactory, int keyFieldCount) {
         this.tupleWriterFactory = tupleWriterFactory;
+        if (keyFieldCount % 2 != 0) {
+            throw new IllegalArgumentException("The key has different number of dimensions.");
+        }
         this.keyFieldCount = keyFieldCount;
     }
 
diff --git a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/DoublePrimitiveValueProviderFactory.java b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/DoublePrimitiveValueProviderFactory.java
new file mode 100644
index 0000000..6607fdb
--- /dev/null
+++ b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/DoublePrimitiveValueProviderFactory.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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.
+ */
+package edu.uci.ics.hyracks.storage.am.rtree.impls;
+
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+
+public class DoublePrimitiveValueProviderFactory implements IPrimitiveValueProviderFactory {
+    private static final long serialVersionUID = 1L;
+
+    public static final DoublePrimitiveValueProviderFactory INSTANCE = new DoublePrimitiveValueProviderFactory();
+
+    private DoublePrimitiveValueProviderFactory() {
+    }
+
+    @Override
+    public IPrimitiveValueProvider createPrimitiveValueProvider() {
+        return new IPrimitiveValueProvider() {
+            @Override
+            public double getValue(byte[] bytes, int offset) {
+                return DoubleSerializerDeserializer.getDouble(bytes, offset);
+            }
+        };
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/FloatPrimitiveValueProviderFactory.java b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/FloatPrimitiveValueProviderFactory.java
new file mode 100644
index 0000000..5f93524
--- /dev/null
+++ b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/FloatPrimitiveValueProviderFactory.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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.
+ */
+package edu.uci.ics.hyracks.storage.am.rtree.impls;
+
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.FloatSerializerDeserializer;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+
+public class FloatPrimitiveValueProviderFactory implements IPrimitiveValueProviderFactory {
+    private static final long serialVersionUID = 1L;
+
+    public static final FloatPrimitiveValueProviderFactory INSTANCE = new FloatPrimitiveValueProviderFactory();
+
+    private FloatPrimitiveValueProviderFactory() {
+    }
+
+    @Override
+    public IPrimitiveValueProvider createPrimitiveValueProvider() {
+        return new IPrimitiveValueProvider() {
+            @Override
+            public double getValue(byte[] bytes, int offset) {
+                return FloatSerializerDeserializer.getFloat(bytes, offset);
+            }
+        };
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/IntegerPrimitiveValueProviderFactory.java b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/IntegerPrimitiveValueProviderFactory.java
new file mode 100644
index 0000000..18e7126
--- /dev/null
+++ b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/IntegerPrimitiveValueProviderFactory.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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.
+ */
+package edu.uci.ics.hyracks.storage.am.rtree.impls;
+
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
+
+public class IntegerPrimitiveValueProviderFactory implements IPrimitiveValueProviderFactory {
+    private static final long serialVersionUID = 1L;
+
+    public static final IntegerPrimitiveValueProviderFactory INSTANCE = new IntegerPrimitiveValueProviderFactory();
+
+    private IntegerPrimitiveValueProviderFactory() {
+    }
+
+    @Override
+    public IPrimitiveValueProvider createPrimitiveValueProvider() {
+        return new IPrimitiveValueProvider() {
+            @Override
+            public double getValue(byte[] bytes, int offset) {
+                return IntegerSerializerDeserializer.getInt(bytes, offset);
+            }
+        };
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java
index 8976409..42774f7 100644
--- a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java
+++ b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java
@@ -256,6 +256,16 @@
         ctx.interiorFrame.setPageTupleFieldCount(cmp.getKeyFieldCount());
         ctx.leafFrame.setPageTupleFieldCount(cmp.getFieldCount());
 
+        int maxFieldPos = cmp.getKeyFieldCount() / 2;
+        for (int i = 0; i < maxFieldPos; i++) {
+            int j = maxFieldPos + i;
+            int c = cmp.getComparators()[i].compare(tuple.getFieldData(i), tuple.getFieldStart(i),
+                    tuple.getFieldLength(i), tuple.getFieldData(j), tuple.getFieldStart(j), tuple.getFieldLength(j));
+            if (c > 0) {
+                throw new IllegalArgumentException("The low key point has larger coordinates than the high key point.");
+            }
+        }
+
         ICachedPage leafNode = findLeaf(ctx);
 
         int pageId = ctx.pathList.getLastPageId();
@@ -879,7 +889,7 @@
     public IIndexBulkLoadContext beginBulkLoad(float fillFactor, ITreeIndexFrame leafFrame,
             ITreeIndexFrame interiorFrame, ITreeIndexMetaDataFrame metaFrame) throws HyracksDataException {
         if (loaded)
-            throw new HyracksDataException("Trying to bulk-load RTree but has RTree already been loaded.");
+            throw new HyracksDataException("Trying to bulk-load RTree but RTree has already been loaded.");
 
         BulkLoadContext ctx = new BulkLoadContext(fillFactor, (IRTreeFrame) leafFrame, (IRTreeFrame) interiorFrame,
                 metaFrame);
diff --git a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTreeSearchCursor.java b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTreeSearchCursor.java
index 86a7bfd..52b5ffd 100644
--- a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTreeSearchCursor.java
+++ b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTreeSearchCursor.java
@@ -174,6 +174,17 @@
         cmp = pred.getLowKeyComparator();
         searchKey = pred.getSearchKey();
 
+        int maxFieldPos = cmp.getKeyFieldCount() / 2;
+        for (int i = 0; i < maxFieldPos; i++) {
+            int j = maxFieldPos + i;
+            int c = cmp.getComparators()[i].compare(searchKey.getFieldData(i), searchKey.getFieldStart(i),
+                    searchKey.getFieldLength(i), searchKey.getFieldData(j), searchKey.getFieldStart(j),
+                    searchKey.getFieldLength(j));
+            if (c > 0) {
+                throw new IllegalArgumentException("The low key point has larger coordinates than the high key point.");
+            }
+        }
+
         pathList.add(this.rootPage, -1, -1);
         frameTuple.setFieldCount(cmp.getFieldCount());
         tupleIndex = 0;
diff --git a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/Rectangle.java b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/Rectangle.java
index 1fb86a9..c5849ff 100644
--- a/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/Rectangle.java
+++ b/hyracks/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/Rectangle.java
@@ -16,7 +16,7 @@
 package edu.uci.ics.hyracks.storage.am.rtree.impls;
 
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
-import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
 
 public class Rectangle {
     private int dim;
@@ -49,23 +49,23 @@
         high[i] = value;
     }
 
-    public void set(ITupleReference tuple) {
+    public void set(ITupleReference tuple, MultiComparator cmp) {
         for (int i = 0; i < getDim(); i++) {
             int j = i + getDim();
-            setLow(i, DoubleSerializerDeserializer.getDouble(tuple.getFieldData(i), tuple.getFieldStart(i)));
-            setHigh(i, DoubleSerializerDeserializer.getDouble(tuple.getFieldData(j), tuple.getFieldStart(j)));
+            setLow(i, cmp.getValueProviders()[i].getValue(tuple.getFieldData(i), tuple.getFieldStart(i)));
+            setHigh(i, cmp.getValueProviders()[j].getValue(tuple.getFieldData(j), tuple.getFieldStart(j)));
         }
     }
 
-    public void enlarge(ITupleReference tupleToBeInserted) {
+    public void enlarge(ITupleReference tupleToBeInserted, MultiComparator cmp) {
         for (int i = 0; i < getDim(); i++) {
             int j = getDim() + i;
-            double low = DoubleSerializerDeserializer.getDouble(tupleToBeInserted.getFieldData(i),
+            double low = cmp.getValueProviders()[i].getValue(tupleToBeInserted.getFieldData(i),
                     tupleToBeInserted.getFieldStart(i));
             if (getLow(i) > low) {
                 setLow(i, low);
             }
-            double high = DoubleSerializerDeserializer.getDouble(tupleToBeInserted.getFieldData(j),
+            double high = cmp.getValueProviders()[j].getValue(tupleToBeInserted.getFieldData(j),
                     tupleToBeInserted.getFieldStart(j));
             if (getHigh(i) < high) {
                 setHigh(i, high);
@@ -82,24 +82,6 @@
         return margin;
     }
 
-    public double overlappedArea(ITupleReference tuple) {
-        double area = 1.0;
-        double f1, f2;
-
-        for (int i = 0; i < getDim(); i++) {
-            int j = getDim() + i;
-            double low = DoubleSerializerDeserializer.getDouble(tuple.getFieldData(i), tuple.getFieldStart(i));
-            double high = DoubleSerializerDeserializer.getDouble(tuple.getFieldData(j), tuple.getFieldStart(j));
-            if (getLow(i) > high || getHigh(i) < low) {
-                return 0.0;
-            }
-            f1 = Math.max(getLow(i), low);
-            f2 = Math.min(getHigh(i), high);
-            area *= f2 - f1;
-        }
-        return area;
-    }
-
     public double overlappedArea(Rectangle rec) {
         double area = 1.0;
         double f1, f2;
@@ -116,16 +98,6 @@
         return area;
     }
 
-    public double area(ITupleReference tuple) {
-        double area = 1.0;
-        for (int i = 0; i < getDim(); i++) {
-            int j = getDim() + i;
-            area *= DoubleSerializerDeserializer.getDouble(tuple.getFieldData(j), tuple.getFieldStart(j))
-                    - DoubleSerializerDeserializer.getDouble(tuple.getFieldData(i), tuple.getFieldStart(i));
-        }
-        return area;
-    }
-
     public double area() {
         double area = 1.0;
         for (int i = 0; i < getDim(); i++) {
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeFieldPrefixNSMTest.java b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeFieldPrefixNSMTest.java
index 2b2bf55..935a0ee 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeFieldPrefixNSMTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeFieldPrefixNSMTest.java
@@ -55,186 +55,171 @@
 
 public class BTreeFieldPrefixNSMTest extends AbstractBTreeTest {
 
-	private static final int PAGE_SIZE = 32768; // 32K
-	private static final int NUM_PAGES = 40;
-	private static final int MAX_OPEN_FILES = 10;
-	private static final int HYRACKS_FRAME_SIZE = 128;
-	private IHyracksStageletContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
-		
-	private ITupleReference createTuple(IHyracksStageletContext ctx, int f0,
-			int f1, int f2, boolean print) throws HyracksDataException {
-		if (print)
-		    LOGGER.info("CREATING: " + f0 + " " + f1 + " " + f2);		
+    private static final int PAGE_SIZE = 32768; // 32K
+    private static final int NUM_PAGES = 40;
+    private static final int MAX_OPEN_FILES = 10;
+    private static final int HYRACKS_FRAME_SIZE = 128;
+    private IHyracksStageletContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
 
-		ByteBuffer buf = ctx.allocateFrame();
-		FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
-		ArrayTupleBuilder tb = new ArrayTupleBuilder(3);
-		DataOutput dos = tb.getDataOutput();
+    private ITupleReference createTuple(IHyracksStageletContext ctx, int f0, int f1, int f2, boolean print)
+            throws HyracksDataException {
+        if (print)
+            LOGGER.info("CREATING: " + f0 + " " + f1 + " " + f2);
 
-		ISerializerDeserializer[] recDescSers = {
-				IntegerSerializerDeserializer.INSTANCE,
-				IntegerSerializerDeserializer.INSTANCE,
-				IntegerSerializerDeserializer.INSTANCE };
-		RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
-		IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx
-				.getFrameSize(), recDesc);
-		accessor.reset(buf);
-		FrameTupleReference tuple = new FrameTupleReference();
+        ByteBuffer buf = ctx.allocateFrame();
+        FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+        ArrayTupleBuilder tb = new ArrayTupleBuilder(3);
+        DataOutput dos = tb.getDataOutput();
 
-		tb.reset();
-		IntegerSerializerDeserializer.INSTANCE.serialize(f0, dos);
-		tb.addFieldEndOffset();
-		IntegerSerializerDeserializer.INSTANCE.serialize(f1, dos);
-		tb.addFieldEndOffset();
-		IntegerSerializerDeserializer.INSTANCE.serialize(f2, dos);
-		tb.addFieldEndOffset();
+        ISerializerDeserializer[] recDescSers = { IntegerSerializerDeserializer.INSTANCE,
+                IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
+        RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
+        IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(), recDesc);
+        accessor.reset(buf);
+        FrameTupleReference tuple = new FrameTupleReference();
 
-		appender.reset(buf, true);
-		appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb
-				.getSize());
+        tb.reset();
+        IntegerSerializerDeserializer.INSTANCE.serialize(f0, dos);
+        tb.addFieldEndOffset();
+        IntegerSerializerDeserializer.INSTANCE.serialize(f1, dos);
+        tb.addFieldEndOffset();
+        IntegerSerializerDeserializer.INSTANCE.serialize(f2, dos);
+        tb.addFieldEndOffset();
 
-		tuple.reset(accessor, 0);
+        appender.reset(buf, true);
+        appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
 
-		return tuple;
-	}
+        tuple.reset(accessor, 0);
 
-	@Test
-	public void test01() throws Exception {
-		
-		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES);
-		IBufferCache bufferCache = TestStorageManagerComponentHolder
-				.getBufferCache(ctx);
-		IFileMapProvider fmp = TestStorageManagerComponentHolder
-				.getFileMapProvider(ctx);
-		FileReference file = new FileReference(new File(fileName));
-		bufferCache.createFile(file);
-		int fileId = fmp.lookupFileId(file);
-		bufferCache.openFile(fileId);
+        return tuple;
+    }
 
-		// declare fields
-		int fieldCount = 3;
-		ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
-		typeTraits[0] = new TypeTrait(4);
-		typeTraits[1] = new TypeTrait(4);
-		typeTraits[2] = new TypeTrait(4);
+    @Test
+    public void test01() throws Exception {
 
-		// declare keys
-		int keyFieldCount = 3;
-		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-		cmps[0] = IntegerBinaryComparatorFactory.INSTANCE
-				.createBinaryComparator();
-		cmps[1] = IntegerBinaryComparatorFactory.INSTANCE
-				.createBinaryComparator();
-		cmps[2] = IntegerBinaryComparatorFactory.INSTANCE
-				.createBinaryComparator();
-		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES);
+        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
+        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
+        FileReference file = new FileReference(new File(fileName));
+        bufferCache.createFile(file);
+        int fileId = fmp.lookupFileId(file);
+        bufferCache.openFile(fileId);
 
-		// just for printing
-		ISerializerDeserializer[] sers = {
-				IntegerSerializerDeserializer.INSTANCE,
-				IntegerSerializerDeserializer.INSTANCE,
-				IntegerSerializerDeserializer.INSTANCE };
+        // declare fields
+        int fieldCount = 3;
+        ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
+        typeTraits[0] = new TypeTrait(4);
+        typeTraits[1] = new TypeTrait(4);
+        typeTraits[2] = new TypeTrait(4);
 
-		Random rnd = new Random();
-		rnd.setSeed(50);
+        // declare keys
+        int keyFieldCount = 3;
+        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+        cmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+        cmps[1] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+        cmps[2] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-		ICachedPage page = bufferCache.pin(BufferedFileHandle.getDiskPageId(
-				fileId, 0), false);
-		try {
+        // just for printing
+        ISerializerDeserializer[] sers = { IntegerSerializerDeserializer.INSTANCE,
+                IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
 
-			IPrefixSlotManager slotManager = new FieldPrefixSlotManager();
-			ITreeIndexTupleWriter tupleWriter = new TypeAwareTupleWriter(typeTraits);
-			BTreeFieldPrefixNSMLeafFrame frame = new BTreeFieldPrefixNSMLeafFrame(
-					tupleWriter);
-			frame.setPage(page);
-			frame.initBuffer((byte) 0);
-			slotManager.setFrame(frame);
-			frame.setPrefixTupleCount(0);
+        Random rnd = new Random();
+        rnd.setSeed(50);
 
-			String before = new String();
-			String after = new String();
+        ICachedPage page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, 0), false);
+        try {
 
-			int compactFreq = 5;
-			int compressFreq = 5;
-			int smallMax = 10;
-			int numRecords = 1000;
+            IPrefixSlotManager slotManager = new FieldPrefixSlotManager();
+            ITreeIndexTupleWriter tupleWriter = new TypeAwareTupleWriter(typeTraits);
+            BTreeFieldPrefixNSMLeafFrame frame = new BTreeFieldPrefixNSMLeafFrame(tupleWriter);
+            frame.setPage(page);
+            frame.initBuffer((byte) 0);
+            slotManager.setFrame(frame);
+            frame.setPrefixTupleCount(0);
 
-			int[][] savedFields = new int[numRecords][3];
+            String before = new String();
+            String after = new String();
 
-			// insert records with random calls to compact and compress
-			for (int i = 0; i < numRecords; i++) {
+            int compactFreq = 5;
+            int compressFreq = 5;
+            int smallMax = 10;
+            int numRecords = 1000;
 
-				if ((i + 1) % 100 == 0)
-					LOGGER.info("INSERTING " + (i + 1) + " / " + numRecords);
+            int[][] savedFields = new int[numRecords][3];
 
-				int a = rnd.nextInt() % smallMax;
-				int b = rnd.nextInt() % smallMax;
-				int c = i;
+            // insert records with random calls to compact and compress
+            for (int i = 0; i < numRecords; i++) {
 
-				ITupleReference tuple = createTuple(ctx, a, b, c, false);
-				try {
-					int targetTupleIndex = frame.findTupleIndex(tuple, cmp);
-					frame.insert(tuple, cmp, targetTupleIndex);
-				} catch (BTreeException e) {
-					e.printStackTrace();
-				} catch (Exception e) {
-					e.printStackTrace();
-				}
+                if ((i + 1) % 100 == 0)
+                    LOGGER.info("INSERTING " + (i + 1) + " / " + numRecords);
 
-				savedFields[i][0] = a;
-				savedFields[i][1] = b;
-				savedFields[i][2] = c;
+                int a = rnd.nextInt() % smallMax;
+                int b = rnd.nextInt() % smallMax;
+                int c = i;
 
-				if (rnd.nextInt() % compactFreq == 0) {
-					before = frame.printKeys(cmp, sers);
-					frame.compact(cmp);
-					after = frame.printKeys(cmp, sers);
-					Assert.assertEquals(before, after);
-				}
+                ITupleReference tuple = createTuple(ctx, a, b, c, false);
+                try {
+                    int targetTupleIndex = frame.findTupleIndex(tuple, cmp);
+                    frame.insert(tuple, cmp, targetTupleIndex);
+                } catch (BTreeException e) {
+                    e.printStackTrace();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
 
-				if (rnd.nextInt() % compressFreq == 0) {
-					before = frame.printKeys(cmp, sers);
-					frame.compress(cmp);
-					after = frame.printKeys(cmp, sers);
-					Assert.assertEquals(before, after);
-				}
+                savedFields[i][0] = a;
+                savedFields[i][1] = b;
+                savedFields[i][2] = c;
 
-			}
+                if (rnd.nextInt() % compactFreq == 0) {
+                    before = frame.printKeys(cmp, sers);
+                    frame.compact(cmp);
+                    after = frame.printKeys(cmp, sers);
+                    Assert.assertEquals(before, after);
+                }
 
-			// delete records with random calls to compact and compress
-			for (int i = 0; i < numRecords; i++) {
+                if (rnd.nextInt() % compressFreq == 0) {
+                    before = frame.printKeys(cmp, sers);
+                    frame.compress(cmp);
+                    after = frame.printKeys(cmp, sers);
+                    Assert.assertEquals(before, after);
+                }
 
-				if ((i + 1) % 100 == 0)
-					LOGGER.info("DELETING " + (i + 1) + " / " + numRecords);
+            }
 
-				ITupleReference tuple = createTuple(ctx,
-						savedFields[i][0], savedFields[i][1],
-						savedFields[i][2], false);
-				try {
-					frame.delete(tuple, cmp, true);
-				} catch (Exception e) {
-				}
+            // delete records with random calls to compact and compress
+            for (int i = 0; i < numRecords; i++) {
 
-				if (rnd.nextInt() % compactFreq == 0) {
-					before = frame.printKeys(cmp, sers);
-					frame.compact(cmp);
-					after = frame.printKeys(cmp, sers);
-					Assert.assertEquals(before, after);
-				}
+                if ((i + 1) % 100 == 0)
+                    LOGGER.info("DELETING " + (i + 1) + " / " + numRecords);
 
-				if (rnd.nextInt() % compressFreq == 0) {
-					before = frame.printKeys(cmp, sers);
-					frame.compress(cmp);
-					after = frame.printKeys(cmp, sers);
-					Assert.assertEquals(before, after);
-				}
-			}
+                ITupleReference tuple = createTuple(ctx, savedFields[i][0], savedFields[i][1], savedFields[i][2], false);
+                try {
+                    frame.delete(tuple, cmp, true);
+                } catch (Exception e) {
+                }
 
-		} finally {
-			bufferCache.unpin(page);
-		}
+                if (rnd.nextInt() % compactFreq == 0) {
+                    before = frame.printKeys(cmp, sers);
+                    frame.compact(cmp);
+                    after = frame.printKeys(cmp, sers);
+                    Assert.assertEquals(before, after);
+                }
 
-		bufferCache.closeFile(fileId);
-		bufferCache.close();
-	}
+                if (rnd.nextInt() % compressFreq == 0) {
+                    before = frame.printKeys(cmp, sers);
+                    frame.compress(cmp);
+                    after = frame.printKeys(cmp, sers);
+                    Assert.assertEquals(before, after);
+                }
+            }
+
+        } finally {
+            bufferCache.unpin(page);
+        }
+
+        bufferCache.closeFile(fileId);
+        bufferCache.close();
+    }
 }
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeStatsTest.java b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeStatsTest.java
index 44cf18b..dcfb7a2 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeStatsTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeStatsTest.java
@@ -47,127 +47,116 @@
 
 public class BTreeStatsTest extends AbstractBTreeTest {
 
-	// private static final int PAGE_SIZE = 256;
-	// private static final int NUM_PAGES = 10;
-	// private static final int PAGE_SIZE = 32768;
+    // private static final int PAGE_SIZE = 256;
+    // private static final int NUM_PAGES = 10;
+    // private static final int PAGE_SIZE = 32768;
     private static final int PAGE_SIZE = 4096;
     private static final int NUM_PAGES = 1000;
     private static final int MAX_OPEN_FILES = 10;
-	private static final int HYRACKS_FRAME_SIZE = 128;
-	private IHyracksStageletContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
-	
-	@Test
-	public void test01() throws Exception {
+    private static final int HYRACKS_FRAME_SIZE = 128;
+    private IHyracksStageletContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
 
-		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES);
-		IBufferCache bufferCache = TestStorageManagerComponentHolder
-				.getBufferCache(ctx);
-		IFileMapProvider fmp = TestStorageManagerComponentHolder
-				.getFileMapProvider(ctx);
-		FileReference file = new FileReference(new File(fileName));
-		bufferCache.createFile(file);
-		int fileId = fmp.lookupFileId(file);
-		bufferCache.openFile(fileId);
+    @Test
+    public void test01() throws Exception {
 
-		// declare fields
-		int fieldCount = 2;
-		ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
-		typeTraits[0] = new TypeTrait(4);
-		typeTraits[1] = new TypeTrait(4);
+        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES);
+        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
+        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
+        FileReference file = new FileReference(new File(fileName));
+        bufferCache.createFile(file);
+        int fileId = fmp.lookupFileId(file);
+        bufferCache.openFile(fileId);
 
-		// declare keys
-		int keyFieldCount = 1;
-		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-		cmps[0] = IntegerBinaryComparatorFactory.INSTANCE
-				.createBinaryComparator();
+        // declare fields
+        int fieldCount = 2;
+        ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
+        typeTraits[0] = new TypeTrait(4);
+        typeTraits[1] = new TypeTrait(4);
 
-		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+        // declare keys
+        int keyFieldCount = 1;
+        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+        cmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
 
-		TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(
-				typeTraits);
-		ITreeIndexFrameFactory leafFrameFactory = new BTreeNSMLeafFrameFactory(
-				tupleWriterFactory);
-		ITreeIndexFrameFactory interiorFrameFactory = new BTreeNSMInteriorFrameFactory(
-				tupleWriterFactory);
-		ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
+        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-		IBTreeLeafFrame leafFrame = (IBTreeLeafFrame)leafFrameFactory.createFrame();
-		IBTreeInteriorFrame interiorFrame = (IBTreeInteriorFrame)interiorFrameFactory.createFrame();
-		ITreeIndexMetaDataFrame metaFrame = metaFrameFactory.createFrame();
+        TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(typeTraits);
+        ITreeIndexFrameFactory leafFrameFactory = new BTreeNSMLeafFrameFactory(tupleWriterFactory);
+        ITreeIndexFrameFactory interiorFrameFactory = new BTreeNSMInteriorFrameFactory(tupleWriterFactory);
+        ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
 
-		IFreePageManager freePageManager = new LinkedListFreePageManager(
-				bufferCache, fileId, 0, metaFrameFactory);
+        IBTreeLeafFrame leafFrame = (IBTreeLeafFrame) leafFrameFactory.createFrame();
+        IBTreeInteriorFrame interiorFrame = (IBTreeInteriorFrame) interiorFrameFactory.createFrame();
+        ITreeIndexMetaDataFrame metaFrame = metaFrameFactory.createFrame();
 
-		BTree btree = new BTree(bufferCache, freePageManager,
-				interiorFrameFactory, leafFrameFactory, cmp);
-		btree.create(fileId, leafFrame, metaFrame);
-		btree.open(fileId);
+        IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, fileId, 0, metaFrameFactory);
 
-		Random rnd = new Random();
-		rnd.setSeed(50);
+        BTree btree = new BTree(bufferCache, freePageManager, interiorFrameFactory, leafFrameFactory, cmp);
+        btree.create(fileId, leafFrame, metaFrame);
+        btree.open(fileId);
 
-		long start = System.currentTimeMillis();
+        Random rnd = new Random();
+        rnd.setSeed(50);
 
-		LOGGER.info("INSERTING INTO TREE");
+        long start = System.currentTimeMillis();
 
-		ByteBuffer frame = ctx.allocateFrame();
-		FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
-		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
-		DataOutput dos = tb.getDataOutput();
+        LOGGER.info("INSERTING INTO TREE");
 
-		ISerializerDeserializer[] recDescSers = {
-				IntegerSerializerDeserializer.INSTANCE,
-				IntegerSerializerDeserializer.INSTANCE };
-		RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
-		IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx
-				.getFrameSize(), recDesc);
-		accessor.reset(frame);
-		FrameTupleReference tuple = new FrameTupleReference();
+        ByteBuffer frame = ctx.allocateFrame();
+        FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+        DataOutput dos = tb.getDataOutput();
 
-		BTreeOpContext insertOpCtx = btree.createOpContext(
-				IndexOp.INSERT, leafFrame, interiorFrame, metaFrame);
+        ISerializerDeserializer[] recDescSers = { IntegerSerializerDeserializer.INSTANCE,
+                IntegerSerializerDeserializer.INSTANCE };
+        RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
+        IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(), recDesc);
+        accessor.reset(frame);
+        FrameTupleReference tuple = new FrameTupleReference();
 
-		// 10000
-		for (int i = 0; i < 100000; i++) {
+        BTreeOpContext insertOpCtx = btree.createOpContext(IndexOp.INSERT, leafFrame, interiorFrame, metaFrame);
 
-			int f0 = rnd.nextInt() % 100000;
-			int f1 = 5;
+        // 10000
+        for (int i = 0; i < 100000; i++) {
 
-			tb.reset();
-			IntegerSerializerDeserializer.INSTANCE.serialize(f0, dos);
-			tb.addFieldEndOffset();
-			IntegerSerializerDeserializer.INSTANCE.serialize(f1, dos);
-			tb.addFieldEndOffset();
+            int f0 = rnd.nextInt() % 100000;
+            int f1 = 5;
 
-			appender.reset(frame, true);
-			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb
-					.getSize());
+            tb.reset();
+            IntegerSerializerDeserializer.INSTANCE.serialize(f0, dos);
+            tb.addFieldEndOffset();
+            IntegerSerializerDeserializer.INSTANCE.serialize(f1, dos);
+            tb.addFieldEndOffset();
 
-			tuple.reset(accessor, 0);
-			
-			if (i % 10000 == 0) {
-				long end = System.currentTimeMillis();
-				LOGGER.info("INSERTING " + i + " : " + f0 + " " + f1 + " "
-						+ (end - start));
-			}
+            appender.reset(frame, true);
+            appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
 
-			try {
-				btree.insert(tuple, insertOpCtx);
-			} catch (TreeIndexException e) {
-			} catch (Exception e) {
-				e.printStackTrace();
-			}			
-		}
-		
-		TreeIndexStatsGatherer statsGatherer = new TreeIndexStatsGatherer(bufferCache, freePageManager, fileId, btree.getRootPageId());		
-		TreeIndexStats stats = statsGatherer.gatherStats(leafFrame, interiorFrame, metaFrame);
-		LOGGER.info(stats.toString());
+            tuple.reset(accessor, 0);
 
-		TreeIndexBufferCacheWarmup bufferCacheWarmup = new TreeIndexBufferCacheWarmup(bufferCache, freePageManager, fileId);
-		bufferCacheWarmup.warmup(leafFrame, metaFrame, new int[] {1, 2}, new int[] {2, 5});
-		
-		btree.close();
-		bufferCache.closeFile(fileId);
-		bufferCache.close();
-	}
+            if (i % 10000 == 0) {
+                long end = System.currentTimeMillis();
+                LOGGER.info("INSERTING " + i + " : " + f0 + " " + f1 + " " + (end - start));
+            }
+
+            try {
+                btree.insert(tuple, insertOpCtx);
+            } catch (TreeIndexException e) {
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        TreeIndexStatsGatherer statsGatherer = new TreeIndexStatsGatherer(bufferCache, freePageManager, fileId,
+                btree.getRootPageId());
+        TreeIndexStats stats = statsGatherer.gatherStats(leafFrame, interiorFrame, metaFrame);
+        LOGGER.info(stats.toString());
+
+        TreeIndexBufferCacheWarmup bufferCacheWarmup = new TreeIndexBufferCacheWarmup(bufferCache, freePageManager,
+                fileId);
+        bufferCacheWarmup.warmup(leafFrame, metaFrame, new int[] { 1, 2 }, new int[] { 2, 5 });
+
+        btree.close();
+        bufferCache.closeFile(fileId);
+        bufferCache.close();
+    }
 }
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTest.java b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTest.java
index 6fa5d43..d94f22a 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTest.java
@@ -175,8 +175,8 @@
 
         int maxPage = btree.getFreePageManager().getMaxPage(metaFrame);
         LOGGER.info("MAXPAGE: " + maxPage);
-        LOGGER.info(btree.printStats());        
-        
+        LOGGER.info(btree.printStats());
+
         long end = System.currentTimeMillis();
         long duration = end - start;
         LOGGER.info("DURATION: " + duration);
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/RangeSearchCursorTest.java b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/RangeSearchCursorTest.java
index 1a3b219..c9ece57 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/RangeSearchCursorTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/RangeSearchCursorTest.java
@@ -71,540 +71,463 @@
 import edu.uci.ics.hyracks.test.support.TestUtils;
 
 public class RangeSearchCursorTest extends AbstractBTreeTest {
-	private static final int PAGE_SIZE = 256;
-	private static final int NUM_PAGES = 10;
-	private static final int MAX_OPEN_FILES = 10;
-	private static final int HYRACKS_FRAME_SIZE = 128;	
+    private static final int PAGE_SIZE = 256;
+    private static final int NUM_PAGES = 10;
+    private static final int MAX_OPEN_FILES = 10;
+    private static final int HYRACKS_FRAME_SIZE = 128;
 
-	// declare fields
-	int fieldCount = 2;
-	ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
+    // declare fields
+    int fieldCount = 2;
+    ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
 
-	TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(
-			typeTraits);
-	ITreeIndexFrameFactory leafFrameFactory = new BTreeNSMLeafFrameFactory(
-			tupleWriterFactory);
-	ITreeIndexFrameFactory interiorFrameFactory = new BTreeNSMInteriorFrameFactory(
-			tupleWriterFactory);
-	ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
+    TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(typeTraits);
+    ITreeIndexFrameFactory leafFrameFactory = new BTreeNSMLeafFrameFactory(tupleWriterFactory);
+    ITreeIndexFrameFactory interiorFrameFactory = new BTreeNSMInteriorFrameFactory(tupleWriterFactory);
+    ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
 
-	IBTreeLeafFrame leafFrame = (IBTreeLeafFrame)leafFrameFactory.createFrame();
-	IBTreeInteriorFrame interiorFrame = (IBTreeInteriorFrame)interiorFrameFactory.createFrame();
-	ITreeIndexMetaDataFrame metaFrame = metaFrameFactory.createFrame();
+    IBTreeLeafFrame leafFrame = (IBTreeLeafFrame) leafFrameFactory.createFrame();
+    IBTreeInteriorFrame interiorFrame = (IBTreeInteriorFrame) interiorFrameFactory.createFrame();
+    ITreeIndexMetaDataFrame metaFrame = metaFrameFactory.createFrame();
 
-	IHyracksStageletContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
-	ByteBuffer frame = ctx.allocateFrame();
-	FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+    IHyracksStageletContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
+    ByteBuffer frame = ctx.allocateFrame();
+    FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
 
-	ISerializerDeserializer[] recDescSers = {
-			IntegerSerializerDeserializer.INSTANCE,
-			IntegerSerializerDeserializer.INSTANCE };
-	RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
-	IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(),
-			recDesc);
-	FrameTupleReference tuple = new FrameTupleReference();
+    ISerializerDeserializer[] recDescSers = { IntegerSerializerDeserializer.INSTANCE,
+            IntegerSerializerDeserializer.INSTANCE };
+    RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
+    IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(), recDesc);
+    FrameTupleReference tuple = new FrameTupleReference();
 
-	Random rnd = new Random(50);
+    Random rnd = new Random(50);
 
-	@Before
-	public void setUp() {
-		typeTraits[0] = new TypeTrait(4);
-		typeTraits[1] = new TypeTrait(4);
-		accessor.reset(frame);
-	}
+    @Before
+    public void setUp() {
+        typeTraits[0] = new TypeTrait(4);
+        typeTraits[1] = new TypeTrait(4);
+        accessor.reset(frame);
+    }
 
-	@Test
-	public void uniqueIndexTest() throws Exception {
+    @Test
+    public void uniqueIndexTest() throws Exception {
 
-	    LOGGER.info("TESTING RANGE SEARCH CURSOR ON UNIQUE INDEX");
+        LOGGER.info("TESTING RANGE SEARCH CURSOR ON UNIQUE INDEX");
 
-		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES);
-		IBufferCache bufferCache = TestStorageManagerComponentHolder
-				.getBufferCache(ctx);
-		IFileMapProvider fmp = TestStorageManagerComponentHolder
-				.getFileMapProvider(ctx);
-		FileReference file = new FileReference(new File(fileName));
-		bufferCache.createFile(file);
-		int fileId = fmp.lookupFileId(file);
-		bufferCache.openFile(fileId);
+        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES);
+        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
+        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
+        FileReference file = new FileReference(new File(fileName));
+        bufferCache.createFile(file);
+        int fileId = fmp.lookupFileId(file);
+        bufferCache.openFile(fileId);
 
-		// declare keys
-		int keyFieldCount = 1;
-		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-		cmps[0] = IntegerBinaryComparatorFactory.INSTANCE
-				.createBinaryComparator();
+        // declare keys
+        int keyFieldCount = 1;
+        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+        cmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
 
-		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-		IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, fileId, 0, metaFrameFactory);
-		
-		BTree btree = new BTree(bufferCache, freePageManager, interiorFrameFactory,
-				leafFrameFactory, cmp);
-		btree.create(fileId, leafFrame, metaFrame);
-		btree.open(fileId);
+        IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, fileId, 0, metaFrameFactory);
 
-		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
-		DataOutput dos = tb.getDataOutput();
+        BTree btree = new BTree(bufferCache, freePageManager, interiorFrameFactory, leafFrameFactory, cmp);
+        btree.create(fileId, leafFrame, metaFrame);
+        btree.open(fileId);
 
-		BTreeOpContext insertOpCtx = btree.createOpContext(IndexOp.INSERT,
-				leafFrame, interiorFrame, metaFrame);
+        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+        DataOutput dos = tb.getDataOutput();
 
-		// generate keys
-		int numKeys = 50;
-		int maxKey = 1000;
-		TreeSet<Integer> uniqueKeys = new TreeSet<Integer>();
-		ArrayList<Integer> keys = new ArrayList<Integer>();
-		while (uniqueKeys.size() < numKeys) {
-			int key = rnd.nextInt() % maxKey;
-			uniqueKeys.add(key);
-		}
-		for (Integer i : uniqueKeys) {
-			keys.add(i);
-		}
+        BTreeOpContext insertOpCtx = btree.createOpContext(IndexOp.INSERT, leafFrame, interiorFrame, metaFrame);
 
-		// insert keys into btree
-		for (int i = 0; i < keys.size(); i++) {
+        // generate keys
+        int numKeys = 50;
+        int maxKey = 1000;
+        TreeSet<Integer> uniqueKeys = new TreeSet<Integer>();
+        ArrayList<Integer> keys = new ArrayList<Integer>();
+        while (uniqueKeys.size() < numKeys) {
+            int key = rnd.nextInt() % maxKey;
+            uniqueKeys.add(key);
+        }
+        for (Integer i : uniqueKeys) {
+            keys.add(i);
+        }
 
-			tb.reset();
-			IntegerSerializerDeserializer.INSTANCE.serialize(keys.get(i)
-					.intValue(), dos);
-			tb.addFieldEndOffset();
-			IntegerSerializerDeserializer.INSTANCE.serialize(i, dos);
-			tb.addFieldEndOffset();
+        // insert keys into btree
+        for (int i = 0; i < keys.size(); i++) {
 
-			appender.reset(frame, true);
-			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb
-					.getSize());
+            tb.reset();
+            IntegerSerializerDeserializer.INSTANCE.serialize(keys.get(i).intValue(), dos);
+            tb.addFieldEndOffset();
+            IntegerSerializerDeserializer.INSTANCE.serialize(i, dos);
+            tb.addFieldEndOffset();
 
-			tuple.reset(accessor, 0);
+            appender.reset(frame, true);
+            appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
 
-			try {
-				btree.insert(tuple, insertOpCtx);
-			} catch (BTreeException e) {
-			} catch (Exception e) {
-				e.printStackTrace();
-			}
-		}
+            tuple.reset(accessor, 0);
 
-		// btree.printTree(leafFrame, interiorFrame, recDescSers);
+            try {
+                btree.insert(tuple, insertOpCtx);
+            } catch (BTreeException e) {
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
 
-		int minSearchKey = -100;
-		int maxSearchKey = 100;
+        // btree.printTree(leafFrame, interiorFrame, recDescSers);
 
-		// forward searches
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, true, true, true, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, true, false, true, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, true, true, false, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, true, true, true, false);
+        int minSearchKey = -100;
+        int maxSearchKey = 100;
 
-		// backward searches
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, false, true, true, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, false, false, true, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, false, true, false, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, false, true, true, false);
+        // forward searches
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, true, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, false, true, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, false, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, true, false);
 
-		btree.close();
-		bufferCache.closeFile(fileId);
-		bufferCache.close();
-	}
+        // backward searches
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, true, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, false, true, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, false, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, true, false);
 
-	@Test
-	public void nonUniqueIndexTest() throws Exception {
+        btree.close();
+        bufferCache.closeFile(fileId);
+        bufferCache.close();
+    }
 
-	    LOGGER.info("TESTING RANGE SEARCH CURSOR ON NONUNIQUE INDEX");
+    @Test
+    public void nonUniqueIndexTest() throws Exception {
 
-		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES);
-		IBufferCache bufferCache = TestStorageManagerComponentHolder
-				.getBufferCache(ctx);
-		IFileMapProvider fmp = TestStorageManagerComponentHolder
-				.getFileMapProvider(ctx);
-		FileReference file = new FileReference(new File(fileName));
-		bufferCache.createFile(file);
-		int fileId = fmp.lookupFileId(file);
-		bufferCache.openFile(fileId);
+        LOGGER.info("TESTING RANGE SEARCH CURSOR ON NONUNIQUE INDEX");
 
-		// declare keys
-		int keyFieldCount = 2;
-		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-		cmps[0] = IntegerBinaryComparatorFactory.INSTANCE
-				.createBinaryComparator();
-		cmps[1] = IntegerBinaryComparatorFactory.INSTANCE
-				.createBinaryComparator();
+        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES);
+        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
+        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
+        FileReference file = new FileReference(new File(fileName));
+        bufferCache.createFile(file);
+        int fileId = fmp.lookupFileId(file);
+        bufferCache.openFile(fileId);
 
-		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+        // declare keys
+        int keyFieldCount = 2;
+        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+        cmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+        cmps[1] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
 
-		IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, fileId, 0, metaFrameFactory);
-		
-		BTree btree = new BTree(bufferCache, freePageManager, interiorFrameFactory,
-				leafFrameFactory, cmp);
-		btree.create(fileId, leafFrame, metaFrame);
-		btree.open(fileId);
+        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
-		DataOutput dos = tb.getDataOutput();
+        IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, fileId, 0, metaFrameFactory);
 
-		BTreeOpContext insertOpCtx = btree.createOpContext(IndexOp.INSERT,
-				leafFrame, interiorFrame, metaFrame);
+        BTree btree = new BTree(bufferCache, freePageManager, interiorFrameFactory, leafFrameFactory, cmp);
+        btree.create(fileId, leafFrame, metaFrame);
+        btree.open(fileId);
 
-		// generate keys
-		int numKeys = 50;
-		int maxKey = 10;
-		ArrayList<Integer> keys = new ArrayList<Integer>();
-		for (int i = 0; i < numKeys; i++) {
-			int k = rnd.nextInt() % maxKey;
-			keys.add(k);
-		}
-		Collections.sort(keys);
+        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+        DataOutput dos = tb.getDataOutput();
 
-		// insert keys into btree
-		for (int i = 0; i < keys.size(); i++) {
+        BTreeOpContext insertOpCtx = btree.createOpContext(IndexOp.INSERT, leafFrame, interiorFrame, metaFrame);
 
-			tb.reset();
-			IntegerSerializerDeserializer.INSTANCE.serialize(keys.get(i)
-					.intValue(), dos);
-			tb.addFieldEndOffset();
-			IntegerSerializerDeserializer.INSTANCE.serialize(i, dos);
-			tb.addFieldEndOffset();
+        // generate keys
+        int numKeys = 50;
+        int maxKey = 10;
+        ArrayList<Integer> keys = new ArrayList<Integer>();
+        for (int i = 0; i < numKeys; i++) {
+            int k = rnd.nextInt() % maxKey;
+            keys.add(k);
+        }
+        Collections.sort(keys);
 
-			appender.reset(frame, true);
-			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb
-					.getSize());
+        // insert keys into btree
+        for (int i = 0; i < keys.size(); i++) {
 
-			tuple.reset(accessor, 0);
+            tb.reset();
+            IntegerSerializerDeserializer.INSTANCE.serialize(keys.get(i).intValue(), dos);
+            tb.addFieldEndOffset();
+            IntegerSerializerDeserializer.INSTANCE.serialize(i, dos);
+            tb.addFieldEndOffset();
 
-			try {
-				btree.insert(tuple, insertOpCtx);
-			} catch (BTreeException e) {
-			} catch (Exception e) {
-				e.printStackTrace();
-			}
-		}
+            appender.reset(frame, true);
+            appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
 
-		// btree.printTree(leafFrame, interiorFrame, recDescSers);
+            tuple.reset(accessor, 0);
 
-		int minSearchKey = -100;
-		int maxSearchKey = 100;
+            try {
+                btree.insert(tuple, insertOpCtx);
+            } catch (BTreeException e) {
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
 
-		// forward searches
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, true, true, true, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, true, false, true, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, true, true, false, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, true, true, true, false);
+        // btree.printTree(leafFrame, interiorFrame, recDescSers);
 
-		// backward searches
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, false, true, true, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, false, false, true, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, false, true, false, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, false, true, true, false);
+        int minSearchKey = -100;
+        int maxSearchKey = 100;
 
-		btree.close();
-		bufferCache.closeFile(fileId);
-		bufferCache.close();
-	}
+        // forward searches
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, true, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, false, true, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, false, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, true, false);
 
-	@Test
-	public void nonUniqueFieldPrefixIndexTest() throws Exception {
+        // backward searches
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, true, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, false, true, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, false, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, true, false);
 
-	    LOGGER.info("TESTING RANGE SEARCH CURSOR ON NONUNIQUE FIELD-PREFIX COMPRESSED INDEX");
+        btree.close();
+        bufferCache.closeFile(fileId);
+        bufferCache.close();
+    }
 
-		ITreeIndexFrameFactory leafFrameFactory = new BTreeFieldPrefixNSMLeafFrameFactory(
-				tupleWriterFactory);
-		IBTreeLeafFrame leafFrame = (IBTreeLeafFrame)leafFrameFactory.createFrame();
+    @Test
+    public void nonUniqueFieldPrefixIndexTest() throws Exception {
 
-		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES);
-		IBufferCache bufferCache = TestStorageManagerComponentHolder
-				.getBufferCache(ctx);
-		IFileMapProvider fmp = TestStorageManagerComponentHolder
-				.getFileMapProvider(ctx);
-		FileReference file = new FileReference(new File(fileName));
-		bufferCache.createFile(file);
-		int fileId = fmp.lookupFileId(file);
-		bufferCache.openFile(fileId);
+        LOGGER.info("TESTING RANGE SEARCH CURSOR ON NONUNIQUE FIELD-PREFIX COMPRESSED INDEX");
 
-		// declare keys
-		int keyFieldCount = 2;
-		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-		cmps[0] = IntegerBinaryComparatorFactory.INSTANCE
-				.createBinaryComparator();
-		cmps[1] = IntegerBinaryComparatorFactory.INSTANCE
-				.createBinaryComparator();
+        ITreeIndexFrameFactory leafFrameFactory = new BTreeFieldPrefixNSMLeafFrameFactory(tupleWriterFactory);
+        IBTreeLeafFrame leafFrame = (IBTreeLeafFrame) leafFrameFactory.createFrame();
+
+        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES);
+        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
+        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
+        FileReference file = new FileReference(new File(fileName));
+        bufferCache.createFile(file);
+        int fileId = fmp.lookupFileId(file);
+        bufferCache.openFile(fileId);
+
+        // declare keys
+        int keyFieldCount = 2;
+        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+        cmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+        cmps[1] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+
+        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+        IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, fileId, 0, metaFrameFactory);
 
-		IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, fileId, 0, metaFrameFactory);		
-		
-		BTree btree = new BTree(bufferCache, freePageManager, interiorFrameFactory,
-				leafFrameFactory, cmp);
-		btree.create(fileId, leafFrame, metaFrame);
-		btree.open(fileId);
+        BTree btree = new BTree(bufferCache, freePageManager, interiorFrameFactory, leafFrameFactory, cmp);
+        btree.create(fileId, leafFrame, metaFrame);
+        btree.open(fileId);
 
-		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
-		DataOutput dos = tb.getDataOutput();
+        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+        DataOutput dos = tb.getDataOutput();
 
-		BTreeOpContext insertOpCtx = btree.createOpContext(IndexOp.INSERT,
-				leafFrame, interiorFrame, metaFrame);
+        BTreeOpContext insertOpCtx = btree.createOpContext(IndexOp.INSERT, leafFrame, interiorFrame, metaFrame);
 
-		// generate keys
-		int numKeys = 50;
-		int maxKey = 10;
-		ArrayList<Integer> keys = new ArrayList<Integer>();
-		for (int i = 0; i < numKeys; i++) {
-			int k = rnd.nextInt() % maxKey;
-			keys.add(k);
-		}
-		Collections.sort(keys);
+        // generate keys
+        int numKeys = 50;
+        int maxKey = 10;
+        ArrayList<Integer> keys = new ArrayList<Integer>();
+        for (int i = 0; i < numKeys; i++) {
+            int k = rnd.nextInt() % maxKey;
+            keys.add(k);
+        }
+        Collections.sort(keys);
 
-		// insert keys into btree
-		for (int i = 0; i < keys.size(); i++) {
+        // insert keys into btree
+        for (int i = 0; i < keys.size(); i++) {
 
-			tb.reset();
-			IntegerSerializerDeserializer.INSTANCE.serialize(keys.get(i)
-					.intValue(), dos);
-			tb.addFieldEndOffset();
-			IntegerSerializerDeserializer.INSTANCE.serialize(i, dos);
-			tb.addFieldEndOffset();
+            tb.reset();
+            IntegerSerializerDeserializer.INSTANCE.serialize(keys.get(i).intValue(), dos);
+            tb.addFieldEndOffset();
+            IntegerSerializerDeserializer.INSTANCE.serialize(i, dos);
+            tb.addFieldEndOffset();
 
-			appender.reset(frame, true);
-			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb
-					.getSize());
+            appender.reset(frame, true);
+            appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
 
-			tuple.reset(accessor, 0);
+            tuple.reset(accessor, 0);
 
-			try {
-				btree.insert(tuple, insertOpCtx);
-			} catch (BTreeException e) {
-			} catch (Exception e) {
-				e.printStackTrace();
-			}
-		}
+            try {
+                btree.insert(tuple, insertOpCtx);
+            } catch (BTreeException e) {
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
 
-		// btree.printTree(leafFrame, interiorFrame, recDescSers);
+        // btree.printTree(leafFrame, interiorFrame, recDescSers);
 
-		int minSearchKey = -100;
-		int maxSearchKey = 100;
+        int minSearchKey = -100;
+        int maxSearchKey = 100;
 
-		// forward searches
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, true, true, true, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, true, false, true, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, true, true, false, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, true, true, true, false);
+        // forward searches
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, true, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, false, true, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, false, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, true, false);
 
-		// backward searches
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, false, true, true, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, false, false, true, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, false, true, false, false);
-		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
-				maxSearchKey, false, true, true, false);
+        // backward searches
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, true, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, false, true, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, false, false);
+        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, true, false);
 
-		btree.close();
-		bufferCache.closeFile(fileId);
-		bufferCache.close();
-	}
+        btree.close();
+        bufferCache.closeFile(fileId);
+        bufferCache.close();
+    }
 
-	public RangePredicate createRangePredicate(int lk, int hk,
-			boolean isForward, boolean lowKeyInclusive,
-			boolean highKeyInclusive, MultiComparator cmp,
-			ITypeTrait[] typeTraits) throws HyracksDataException {
-		// build low and high keys
-		ArrayTupleBuilder ktb = new ArrayTupleBuilder(1);
-		DataOutput kdos = ktb.getDataOutput();
+    public RangePredicate createRangePredicate(int lk, int hk, boolean isForward, boolean lowKeyInclusive,
+            boolean highKeyInclusive, MultiComparator cmp, ITypeTrait[] typeTraits) throws HyracksDataException {
+        // build low and high keys
+        ArrayTupleBuilder ktb = new ArrayTupleBuilder(1);
+        DataOutput kdos = ktb.getDataOutput();
 
-		ISerializerDeserializer[] keyDescSers = { IntegerSerializerDeserializer.INSTANCE };
-		RecordDescriptor keyDesc = new RecordDescriptor(keyDescSers);
-		IFrameTupleAccessor keyAccessor = new FrameTupleAccessor(ctx
-				.getFrameSize(), keyDesc);
-		keyAccessor.reset(frame);
+        ISerializerDeserializer[] keyDescSers = { IntegerSerializerDeserializer.INSTANCE };
+        RecordDescriptor keyDesc = new RecordDescriptor(keyDescSers);
+        IFrameTupleAccessor keyAccessor = new FrameTupleAccessor(ctx.getFrameSize(), keyDesc);
+        keyAccessor.reset(frame);
 
-		appender.reset(frame, true);
+        appender.reset(frame, true);
 
-		// build and append low key
-		ktb.reset();
-		IntegerSerializerDeserializer.INSTANCE.serialize(lk, kdos);
-		ktb.addFieldEndOffset();
-		appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb
-				.getSize());
+        // build and append low key
+        ktb.reset();
+        IntegerSerializerDeserializer.INSTANCE.serialize(lk, kdos);
+        ktb.addFieldEndOffset();
+        appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb.getSize());
 
-		// build and append high key
-		ktb.reset();
-		IntegerSerializerDeserializer.INSTANCE.serialize(hk, kdos);
-		ktb.addFieldEndOffset();
-		appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb
-				.getSize());
+        // build and append high key
+        ktb.reset();
+        IntegerSerializerDeserializer.INSTANCE.serialize(hk, kdos);
+        ktb.addFieldEndOffset();
+        appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb.getSize());
 
-		// create tuplereferences for search keys
-		FrameTupleReference lowKey = new FrameTupleReference();
-		lowKey.reset(keyAccessor, 0);
+        // create tuplereferences for search keys
+        FrameTupleReference lowKey = new FrameTupleReference();
+        lowKey.reset(keyAccessor, 0);
 
-		FrameTupleReference highKey = new FrameTupleReference();
-		highKey.reset(keyAccessor, 1);
+        FrameTupleReference highKey = new FrameTupleReference();
+        highKey.reset(keyAccessor, 1);
 
-		IBinaryComparator[] searchCmps = new IBinaryComparator[1];
-		searchCmps[0] = IntegerBinaryComparatorFactory.INSTANCE
-				.createBinaryComparator();
-		MultiComparator searchCmp = new MultiComparator(typeTraits, searchCmps);
+        IBinaryComparator[] searchCmps = new IBinaryComparator[1];
+        searchCmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+        MultiComparator searchCmp = new MultiComparator(typeTraits, searchCmps);
 
-		RangePredicate rangePred = new RangePredicate(isForward, lowKey,
-				highKey, lowKeyInclusive, highKeyInclusive, searchCmp,
-				searchCmp);
-		return rangePred;
-	}
+        RangePredicate rangePred = new RangePredicate(isForward, lowKey, highKey, lowKeyInclusive, highKeyInclusive,
+                searchCmp, searchCmp);
+        return rangePred;
+    }
 
-	public void getExpectedResults(ArrayList<Integer> expectedResults,
-			ArrayList<Integer> keys, int lk, int hk, boolean isForward,
-			boolean lowKeyInclusive, boolean highKeyInclusive) {
+    public void getExpectedResults(ArrayList<Integer> expectedResults, ArrayList<Integer> keys, int lk, int hk,
+            boolean isForward, boolean lowKeyInclusive, boolean highKeyInclusive) {
 
-		// special cases
-		if (lk == hk && (!lowKeyInclusive || !highKeyInclusive))
-			return;
-		if (lk > hk)
-			return;
+        // special cases
+        if (lk == hk && (!lowKeyInclusive || !highKeyInclusive))
+            return;
+        if (lk > hk)
+            return;
 
-		if (isForward) {
-			for (int i = 0; i < keys.size(); i++) {
-				if ((lk == keys.get(i) && lowKeyInclusive)
-						|| (hk == keys.get(i) && highKeyInclusive)) {
-					expectedResults.add(keys.get(i));
-					continue;
-				}
+        if (isForward) {
+            for (int i = 0; i < keys.size(); i++) {
+                if ((lk == keys.get(i) && lowKeyInclusive) || (hk == keys.get(i) && highKeyInclusive)) {
+                    expectedResults.add(keys.get(i));
+                    continue;
+                }
 
-				if (lk < keys.get(i) && hk > keys.get(i)) {
-					expectedResults.add(keys.get(i));
-					continue;
-				}
-			}
-		} else {
-			for (int i = keys.size() - 1; i >= 0; i--) {
-				if ((lk == keys.get(i) && lowKeyInclusive)
-						|| (hk == keys.get(i) && highKeyInclusive)) {
-					expectedResults.add(keys.get(i));
-					continue;
-				}
+                if (lk < keys.get(i) && hk > keys.get(i)) {
+                    expectedResults.add(keys.get(i));
+                    continue;
+                }
+            }
+        } else {
+            for (int i = keys.size() - 1; i >= 0; i--) {
+                if ((lk == keys.get(i) && lowKeyInclusive) || (hk == keys.get(i) && highKeyInclusive)) {
+                    expectedResults.add(keys.get(i));
+                    continue;
+                }
 
-				if (lk < keys.get(i) && hk > keys.get(i)) {
-					expectedResults.add(keys.get(i));
-					continue;
-				}
-			}
-		}
-	}
+                if (lk < keys.get(i) && hk > keys.get(i)) {
+                    expectedResults.add(keys.get(i));
+                    continue;
+                }
+            }
+        }
+    }
 
-	public boolean performSearches(ArrayList<Integer> keys, BTree btree,
-			IBTreeLeafFrame leafFrame, IBTreeInteriorFrame interiorFrame,
-			int minKey, int maxKey, boolean isForward, boolean lowKeyInclusive,
-			boolean highKeyInclusive, boolean printExpectedResults)
-			throws Exception {
+    public boolean performSearches(ArrayList<Integer> keys, BTree btree, IBTreeLeafFrame leafFrame,
+            IBTreeInteriorFrame interiorFrame, int minKey, int maxKey, boolean isForward, boolean lowKeyInclusive,
+            boolean highKeyInclusive, boolean printExpectedResults) throws Exception {
 
-		ArrayList<Integer> results = new ArrayList<Integer>();
-		ArrayList<Integer> expectedResults = new ArrayList<Integer>();
+        ArrayList<Integer> results = new ArrayList<Integer>();
+        ArrayList<Integer> expectedResults = new ArrayList<Integer>();
 
-		for (int i = minKey; i < maxKey; i++) {
-			for (int j = minKey; j < maxKey; j++) {
+        for (int i = minKey; i < maxKey; i++) {
+            for (int j = minKey; j < maxKey; j++) {
 
-				results.clear();
-				expectedResults.clear();
+                results.clear();
+                expectedResults.clear();
 
-				int lowKey = i;
-				int highKey = j;
+                int lowKey = i;
+                int highKey = j;
 
-				ITreeIndexCursor rangeCursor = new BTreeRangeSearchCursor(leafFrame);
-				RangePredicate rangePred = createRangePredicate(lowKey,
-						highKey, isForward, lowKeyInclusive, highKeyInclusive,
-						btree.getMultiComparator(), btree.getMultiComparator()
-								.getTypeTraits());
-				BTreeOpContext searchOpCtx = btree.createOpContext(
-						IndexOp.SEARCH, leafFrame, interiorFrame, null);
-				btree.search(rangeCursor, rangePred, searchOpCtx);
+                ITreeIndexCursor rangeCursor = new BTreeRangeSearchCursor(leafFrame);
+                RangePredicate rangePred = createRangePredicate(lowKey, highKey, isForward, lowKeyInclusive,
+                        highKeyInclusive, btree.getMultiComparator(), btree.getMultiComparator().getTypeTraits());
+                BTreeOpContext searchOpCtx = btree.createOpContext(IndexOp.SEARCH, leafFrame, interiorFrame, null);
+                btree.search(rangeCursor, rangePred, searchOpCtx);
 
-				try {
-					while (rangeCursor.hasNext()) {
-						rangeCursor.next();
-						ITupleReference frameTuple = rangeCursor.getTuple();
-						ByteArrayInputStream inStream = new ByteArrayInputStream(
-								frameTuple.getFieldData(0), frameTuple
-										.getFieldStart(0), frameTuple
-										.getFieldLength(0));
-						DataInput dataIn = new DataInputStream(inStream);
-						Integer res = IntegerSerializerDeserializer.INSTANCE
-								.deserialize(dataIn);
-						results.add(res);
-					}
-				} catch (Exception e) {
-					e.printStackTrace();
-				} finally {
-					rangeCursor.close();
-				}
+                try {
+                    while (rangeCursor.hasNext()) {
+                        rangeCursor.next();
+                        ITupleReference frameTuple = rangeCursor.getTuple();
+                        ByteArrayInputStream inStream = new ByteArrayInputStream(frameTuple.getFieldData(0),
+                                frameTuple.getFieldStart(0), frameTuple.getFieldLength(0));
+                        DataInput dataIn = new DataInputStream(inStream);
+                        Integer res = IntegerSerializerDeserializer.INSTANCE.deserialize(dataIn);
+                        results.add(res);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                } finally {
+                    rangeCursor.close();
+                }
 
-				getExpectedResults(expectedResults, keys, lowKey, highKey,
-						isForward, lowKeyInclusive, highKeyInclusive);
+                getExpectedResults(expectedResults, keys, lowKey, highKey, isForward, lowKeyInclusive, highKeyInclusive);
 
-				if (printExpectedResults) {
-					if (expectedResults.size() > 0) {
-						char l, u;
+                if (printExpectedResults) {
+                    if (expectedResults.size() > 0) {
+                        char l, u;
 
-						if (lowKeyInclusive)
-							l = '[';
-						else
-							l = '(';
+                        if (lowKeyInclusive)
+                            l = '[';
+                        else
+                            l = '(';
 
-						if (highKeyInclusive)
-							u = ']';
-						else
-							u = ')';
+                        if (highKeyInclusive)
+                            u = ']';
+                        else
+                            u = ')';
 
-						LOGGER.info("RANGE: " + l + " " + lowKey + " , "
-								+ highKey + " " + u);
-						StringBuilder strBuilder = new StringBuilder();
-						for (Integer r : expectedResults) {
-							strBuilder.append(r + " ");
-						}
-						LOGGER.info(strBuilder.toString());
-					}
-				}
+                        LOGGER.info("RANGE: " + l + " " + lowKey + " , " + highKey + " " + u);
+                        StringBuilder strBuilder = new StringBuilder();
+                        for (Integer r : expectedResults) {
+                            strBuilder.append(r + " ");
+                        }
+                        LOGGER.info(strBuilder.toString());
+                    }
+                }
 
-				if (results.size() == expectedResults.size()) {
-					for (int k = 0; k < results.size(); k++) {
-						if (!results.get(k).equals(expectedResults.get(k))) {
-						    LOGGER.info("DIFFERENT RESULTS AT: i=" + i
-									+ " j=" + j + " k=" + k);
-						    LOGGER.info(results.get(k) + " "
-									+ expectedResults.get(k));
-							return false;
-						}
-					}
-				} else {
-				    LOGGER.info("UNEQUAL NUMBER OF RESULTS AT: i=" + i
-							+ " j=" + j);
-				    LOGGER.info("RESULTS: " + results.size());
-				    LOGGER.info("EXPECTED RESULTS: "
-							+ expectedResults.size());
-					return false;
-				}
-			}
-		}
+                if (results.size() == expectedResults.size()) {
+                    for (int k = 0; k < results.size(); k++) {
+                        if (!results.get(k).equals(expectedResults.get(k))) {
+                            LOGGER.info("DIFFERENT RESULTS AT: i=" + i + " j=" + j + " k=" + k);
+                            LOGGER.info(results.get(k) + " " + expectedResults.get(k));
+                            return false;
+                        }
+                    }
+                } else {
+                    LOGGER.info("UNEQUAL NUMBER OF RESULTS AT: i=" + i + " j=" + j);
+                    LOGGER.info("RESULTS: " + results.size());
+                    LOGGER.info("EXPECTED RESULTS: " + expectedResults.size());
+                    return false;
+                }
+            }
+        }
 
-		return true;
-	}
+        return true;
+    }
 }
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/StorageManagerTest.java b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/StorageManagerTest.java
index 1a510e6..8b6185d 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/StorageManagerTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/StorageManagerTest.java
@@ -35,238 +35,225 @@
 import edu.uci.ics.hyracks.test.support.TestUtils;
 
 public class StorageManagerTest extends AbstractBTreeTest {
-	private static final int PAGE_SIZE = 256;
-	private static final int NUM_PAGES = 10;
-	private static final int MAX_OPEN_FILES = 10;
-	private static final int HYRACKS_FRAME_SIZE = 128;
-	private IHyracksStageletContext ctx = TestUtils.create(32768);
+    private static final int PAGE_SIZE = 256;
+    private static final int NUM_PAGES = 10;
+    private static final int MAX_OPEN_FILES = 10;
+    private static final int HYRACKS_FRAME_SIZE = 128;
+    private IHyracksStageletContext ctx = TestUtils.create(32768);
 
-	public class PinnedLatchedPage {
-		public final ICachedPage page;
-		public final LatchType latch;
-		public final int pageId;
+    public class PinnedLatchedPage {
+        public final ICachedPage page;
+        public final LatchType latch;
+        public final int pageId;
 
-		public PinnedLatchedPage(ICachedPage page, int pageId, LatchType latch) {
-			this.page = page;
-			this.pageId = pageId;
-			this.latch = latch;
-		}
-	}
+        public PinnedLatchedPage(ICachedPage page, int pageId, LatchType latch) {
+            this.page = page;
+            this.pageId = pageId;
+            this.latch = latch;
+        }
+    }
 
-	public enum FileAccessType {
-		FTA_READONLY, FTA_WRITEONLY, FTA_MIXED, FTA_UNLATCHED
-	}
+    public enum FileAccessType {
+        FTA_READONLY, FTA_WRITEONLY, FTA_MIXED, FTA_UNLATCHED
+    }
 
-	public class FileAccessWorker implements Runnable {
-		private int workerId;
-		private final IBufferCache bufferCache;
-		private final int maxPages;
-		private final int fileId;
-		private final long thinkTime;
-		private final int maxLoopCount;
-		private final int maxPinnedPages;
-		private final int closeFileChance;
-		private final FileAccessType fta;
-		private int loopCount = 0;
-		private boolean fileIsOpen = false;
-		private Random rnd = new Random(50);
-		private List<PinnedLatchedPage> pinnedPages = new LinkedList<PinnedLatchedPage>();
+    public class FileAccessWorker implements Runnable {
+        private int workerId;
+        private final IBufferCache bufferCache;
+        private final int maxPages;
+        private final int fileId;
+        private final long thinkTime;
+        private final int maxLoopCount;
+        private final int maxPinnedPages;
+        private final int closeFileChance;
+        private final FileAccessType fta;
+        private int loopCount = 0;
+        private boolean fileIsOpen = false;
+        private Random rnd = new Random(50);
+        private List<PinnedLatchedPage> pinnedPages = new LinkedList<PinnedLatchedPage>();
 
-		public FileAccessWorker(int workerId, IBufferCache bufferCache,
-				FileAccessType fta, int fileId, int maxPages,
-				int maxPinnedPages, int maxLoopCount, int closeFileChance,
-				long thinkTime) {
-			this.bufferCache = bufferCache;
-			this.fileId = fileId;
-			this.maxPages = maxPages;
-			this.maxLoopCount = maxLoopCount;
-			this.maxPinnedPages = maxPinnedPages;
-			this.thinkTime = thinkTime;
-			this.closeFileChance = closeFileChance;
-			this.workerId = workerId;
-			this.fta = fta;
-		}
+        public FileAccessWorker(int workerId, IBufferCache bufferCache, FileAccessType fta, int fileId, int maxPages,
+                int maxPinnedPages, int maxLoopCount, int closeFileChance, long thinkTime) {
+            this.bufferCache = bufferCache;
+            this.fileId = fileId;
+            this.maxPages = maxPages;
+            this.maxLoopCount = maxLoopCount;
+            this.maxPinnedPages = maxPinnedPages;
+            this.thinkTime = thinkTime;
+            this.closeFileChance = closeFileChance;
+            this.workerId = workerId;
+            this.fta = fta;
+        }
 
-		private void pinRandomPage() {
-			int pageId = Math.abs(rnd.nextInt() % maxPages);
+        private void pinRandomPage() {
+            int pageId = Math.abs(rnd.nextInt() % maxPages);
 
-			LOGGER.info(workerId + " PINNING PAGE: " + pageId);
+            LOGGER.info(workerId + " PINNING PAGE: " + pageId);
 
-			try {
-				ICachedPage page = bufferCache.pin(BufferedFileHandle
-						.getDiskPageId(fileId, pageId), false);
-				LatchType latch = null;
+            try {
+                ICachedPage page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, pageId), false);
+                LatchType latch = null;
 
-				switch (fta) {
+                switch (fta) {
 
-				case FTA_UNLATCHED: {
-					latch = null;
-				}
-					break;
+                    case FTA_UNLATCHED: {
+                        latch = null;
+                    }
+                        break;
 
-				case FTA_READONLY: {
-				    LOGGER.info(workerId + " S LATCHING: " + pageId);
-					page.acquireReadLatch();
-					latch = LatchType.LATCH_S;
-				}
-					break;
+                    case FTA_READONLY: {
+                        LOGGER.info(workerId + " S LATCHING: " + pageId);
+                        page.acquireReadLatch();
+                        latch = LatchType.LATCH_S;
+                    }
+                        break;
 
-				case FTA_WRITEONLY: {
-				    LOGGER.info(workerId + " X LATCHING: " + pageId);
-					page.acquireWriteLatch();
-					latch = LatchType.LATCH_X;
-				}
-					break;
+                    case FTA_WRITEONLY: {
+                        LOGGER.info(workerId + " X LATCHING: " + pageId);
+                        page.acquireWriteLatch();
+                        latch = LatchType.LATCH_X;
+                    }
+                        break;
 
-				case FTA_MIXED: {
-					if (rnd.nextInt() % 2 == 0) {
-					    LOGGER.info(workerId + " S LATCHING: " + pageId);
-						page.acquireReadLatch();
-						latch = LatchType.LATCH_S;
-					} else {
-					    LOGGER.info(workerId + " X LATCHING: " + pageId);
-						page.acquireWriteLatch();
-						latch = LatchType.LATCH_X;
-					}
-				}
-					break;
+                    case FTA_MIXED: {
+                        if (rnd.nextInt() % 2 == 0) {
+                            LOGGER.info(workerId + " S LATCHING: " + pageId);
+                            page.acquireReadLatch();
+                            latch = LatchType.LATCH_S;
+                        } else {
+                            LOGGER.info(workerId + " X LATCHING: " + pageId);
+                            page.acquireWriteLatch();
+                            latch = LatchType.LATCH_X;
+                        }
+                    }
+                        break;
 
-				}
+                }
 
-				PinnedLatchedPage plPage = new PinnedLatchedPage(page, pageId,
-						latch);
-				pinnedPages.add(plPage);
-			} catch (HyracksDataException e) {
-				e.printStackTrace();
-			}
-		}
+                PinnedLatchedPage plPage = new PinnedLatchedPage(page, pageId, latch);
+                pinnedPages.add(plPage);
+            } catch (HyracksDataException e) {
+                e.printStackTrace();
+            }
+        }
 
-		private void unpinRandomPage() {
-			int index = Math.abs(rnd.nextInt() % pinnedPages.size());
-			try {
-				PinnedLatchedPage plPage = pinnedPages.get(index);
+        private void unpinRandomPage() {
+            int index = Math.abs(rnd.nextInt() % pinnedPages.size());
+            try {
+                PinnedLatchedPage plPage = pinnedPages.get(index);
 
-				if (plPage.latch != null) {
-					if (plPage.latch == LatchType.LATCH_S) {
-					    LOGGER.info(workerId + " S UNLATCHING: "
-								+ plPage.pageId);
-						plPage.page.releaseReadLatch();
-					} else {
-					    LOGGER.info(workerId + " X UNLATCHING: "
-								+ plPage.pageId);
-						plPage.page.releaseWriteLatch();
-					}
-				}
-				LOGGER.info(workerId + " UNPINNING PAGE: "
-						+ plPage.pageId);
+                if (plPage.latch != null) {
+                    if (plPage.latch == LatchType.LATCH_S) {
+                        LOGGER.info(workerId + " S UNLATCHING: " + plPage.pageId);
+                        plPage.page.releaseReadLatch();
+                    } else {
+                        LOGGER.info(workerId + " X UNLATCHING: " + plPage.pageId);
+                        plPage.page.releaseWriteLatch();
+                    }
+                }
+                LOGGER.info(workerId + " UNPINNING PAGE: " + plPage.pageId);
 
-				bufferCache.unpin(plPage.page);
-				pinnedPages.remove(index);
-			} catch (HyracksDataException e) {
-				e.printStackTrace();
-			}
-		}
+                bufferCache.unpin(plPage.page);
+                pinnedPages.remove(index);
+            } catch (HyracksDataException e) {
+                e.printStackTrace();
+            }
+        }
 
-		private void openFile() {
-		    LOGGER.info(workerId + " OPENING FILE: " + fileId);
-			try {
-				bufferCache.openFile(fileId);
-				fileIsOpen = true;
-			} catch (HyracksDataException e) {
-				e.printStackTrace();
-			}
-		}
+        private void openFile() {
+            LOGGER.info(workerId + " OPENING FILE: " + fileId);
+            try {
+                bufferCache.openFile(fileId);
+                fileIsOpen = true;
+            } catch (HyracksDataException e) {
+                e.printStackTrace();
+            }
+        }
 
-		private void closeFile() {
-		    LOGGER.info(workerId + " CLOSING FILE: " + fileId);
-			try {
-				bufferCache.closeFile(fileId);
-				fileIsOpen = false;
-			} catch (HyracksDataException e) {
-				e.printStackTrace();
-			}
-		}
+        private void closeFile() {
+            LOGGER.info(workerId + " CLOSING FILE: " + fileId);
+            try {
+                bufferCache.closeFile(fileId);
+                fileIsOpen = false;
+            } catch (HyracksDataException e) {
+                e.printStackTrace();
+            }
+        }
 
-		@Override
-		public void run() {
+        @Override
+        public void run() {
 
-			openFile();
+            openFile();
 
-			while (loopCount < maxLoopCount) {
-				loopCount++;
+            while (loopCount < maxLoopCount) {
+                loopCount++;
 
-				LOGGER.info(workerId + " LOOP: " + loopCount + "/"
-						+ maxLoopCount);
+                LOGGER.info(workerId + " LOOP: " + loopCount + "/" + maxLoopCount);
 
-				if (fileIsOpen) {
+                if (fileIsOpen) {
 
-					// pin some pages
-					int pagesToPin = Math.abs(rnd.nextInt())
-							% (maxPinnedPages - pinnedPages.size());
-					for (int i = 0; i < pagesToPin; i++) {
-						pinRandomPage();
-					}
+                    // pin some pages
+                    int pagesToPin = Math.abs(rnd.nextInt()) % (maxPinnedPages - pinnedPages.size());
+                    for (int i = 0; i < pagesToPin; i++) {
+                        pinRandomPage();
+                    }
 
-					// do some thinking
-					try {
-						Thread.sleep(thinkTime);
-					} catch (InterruptedException e) {
-						e.printStackTrace();
-					}
+                    // do some thinking
+                    try {
+                        Thread.sleep(thinkTime);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
 
-					// unpin some pages
-					if (!pinnedPages.isEmpty()) {
-						int pagesToUnpin = Math.abs(rnd.nextInt())
-								% pinnedPages.size();
-						for (int i = 0; i < pagesToUnpin; i++) {
-							unpinRandomPage();
-						}
-					}
+                    // unpin some pages
+                    if (!pinnedPages.isEmpty()) {
+                        int pagesToUnpin = Math.abs(rnd.nextInt()) % pinnedPages.size();
+                        for (int i = 0; i < pagesToUnpin; i++) {
+                            unpinRandomPage();
+                        }
+                    }
 
-					// possibly close file
-					int closeFileCheck = Math.abs(rnd.nextInt())
-							% closeFileChance;
-					if (pinnedPages.isEmpty() || closeFileCheck == 0) {
-						int numPinnedPages = pinnedPages.size();
-						for (int i = 0; i < numPinnedPages; i++) {
-							unpinRandomPage();
-						}
-						closeFile();
-					}
-				} else {
-					openFile();
-				}
-			}
+                    // possibly close file
+                    int closeFileCheck = Math.abs(rnd.nextInt()) % closeFileChance;
+                    if (pinnedPages.isEmpty() || closeFileCheck == 0) {
+                        int numPinnedPages = pinnedPages.size();
+                        for (int i = 0; i < numPinnedPages; i++) {
+                            unpinRandomPage();
+                        }
+                        closeFile();
+                    }
+                } else {
+                    openFile();
+                }
+            }
 
-			if (fileIsOpen) {
-				int numPinnedPages = pinnedPages.size();
-				for (int i = 0; i < numPinnedPages; i++) {
-					unpinRandomPage();
-				}
-				closeFile();
-			}
-		}
-	}
+            if (fileIsOpen) {
+                int numPinnedPages = pinnedPages.size();
+                for (int i = 0; i < numPinnedPages; i++) {
+                    unpinRandomPage();
+                }
+                closeFile();
+            }
+        }
+    }
 
-	@Test
-	public void oneThreadOneFileTest() throws Exception {
-		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES);
-		IBufferCache bufferCache = TestStorageManagerComponentHolder
-				.getBufferCache(ctx);
-		IFileMapProvider fmp = TestStorageManagerComponentHolder
-				.getFileMapProvider(ctx);
-		FileReference file = new FileReference(new File(fileName));
-		bufferCache.createFile(file);
-		int fileId = fmp.lookupFileId(file);
-		bufferCache.openFile(fileId);
+    @Test
+    public void oneThreadOneFileTest() throws Exception {
+        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES);
+        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
+        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
+        FileReference file = new FileReference(new File(fileName));
+        bufferCache.createFile(file);
+        int fileId = fmp.lookupFileId(file);
+        bufferCache.openFile(fileId);
 
-		Thread worker = new Thread(new FileAccessWorker(0, bufferCache,
-				FileAccessType.FTA_UNLATCHED, fileId, 10, 10, 100, 10, 0));
+        Thread worker = new Thread(new FileAccessWorker(0, bufferCache, FileAccessType.FTA_UNLATCHED, fileId, 10, 10,
+                100, 10, 0));
 
-		worker.start();
+        worker.start();
 
-		worker.join();
+        worker.join();
 
-		bufferCache.close();
-	}
+        bufferCache.close();
+    }
 }
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/AbstractInvIndexSearchTest.java b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/AbstractInvIndexSearchTest.java
index b42001d..444db8b 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/AbstractInvIndexSearchTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/AbstractInvIndexSearchTest.java
@@ -49,176 +49,155 @@
 import edu.uci.ics.hyracks.test.support.TestUtils;
 
 public abstract class AbstractInvIndexSearchTest extends AbstractInvIndexTest {
-	protected final int PAGE_SIZE = 32768;
-	protected final int NUM_PAGES = 100;
-	protected final int MAX_OPEN_FILES = 10;
-	protected final int HYRACKS_FRAME_SIZE = 32768;
-	protected IHyracksStageletContext stageletCtx = TestUtils
-			.create(HYRACKS_FRAME_SIZE);
+    protected final int PAGE_SIZE = 32768;
+    protected final int NUM_PAGES = 100;
+    protected final int MAX_OPEN_FILES = 10;
+    protected final int HYRACKS_FRAME_SIZE = 32768;
+    protected IHyracksStageletContext stageletCtx = TestUtils.create(HYRACKS_FRAME_SIZE);
 
-	protected IBufferCache bufferCache;
-	protected IFileMapProvider fmp;
+    protected IBufferCache bufferCache;
+    protected IFileMapProvider fmp;
 
-	// --- BTREE ---
+    // --- BTREE ---
 
-	// create file refs
-	protected FileReference btreeFile = new FileReference(new File(
-			btreeFileName));
-	protected int btreeFileId;
+    // create file refs
+    protected FileReference btreeFile = new FileReference(new File(btreeFileName));
+    protected int btreeFileId;
 
-	// declare btree fields
-	protected int fieldCount = 5;
-	protected ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
+    // declare btree fields
+    protected int fieldCount = 5;
+    protected ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
 
-	// declare btree keys
-	protected int btreeKeyFieldCount = 1;
-	protected IBinaryComparator[] btreeBinCmps = new IBinaryComparator[btreeKeyFieldCount];
-	protected MultiComparator btreeCmp = new MultiComparator(typeTraits,
-			btreeBinCmps);
+    // declare btree keys
+    protected int btreeKeyFieldCount = 1;
+    protected IBinaryComparator[] btreeBinCmps = new IBinaryComparator[btreeKeyFieldCount];
+    protected MultiComparator btreeCmp = new MultiComparator(typeTraits, btreeBinCmps);
 
-	// btree frame factories
-	protected TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(
-			typeTraits);
-	protected ITreeIndexFrameFactory leafFrameFactory = new BTreeNSMLeafFrameFactory(
-			tupleWriterFactory);
-	protected ITreeIndexFrameFactory interiorFrameFactory = new BTreeNSMInteriorFrameFactory(
-			tupleWriterFactory);
-	protected ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
+    // btree frame factories
+    protected TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(typeTraits);
+    protected ITreeIndexFrameFactory leafFrameFactory = new BTreeNSMLeafFrameFactory(tupleWriterFactory);
+    protected ITreeIndexFrameFactory interiorFrameFactory = new BTreeNSMInteriorFrameFactory(tupleWriterFactory);
+    protected ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
 
-	// btree frames
-	protected ITreeIndexFrame leafFrame = leafFrameFactory.createFrame();
-	protected ITreeIndexMetaDataFrame metaFrame = metaFrameFactory
-			.createFrame();
+    // btree frames
+    protected ITreeIndexFrame leafFrame = leafFrameFactory.createFrame();
+    protected ITreeIndexMetaDataFrame metaFrame = metaFrameFactory.createFrame();
 
-	protected IFreePageManager freePageManager;
+    protected IFreePageManager freePageManager;
 
-	protected BTree btree;
+    protected BTree btree;
 
-	// --- INVERTED INDEX ---
+    // --- INVERTED INDEX ---
 
-	protected FileReference invListsFile = new FileReference(new File(
-			invListsFileName));
-	protected int invListsFileId;
+    protected FileReference invListsFile = new FileReference(new File(invListsFileName));
+    protected int invListsFileId;
 
-	protected int invListFields = 1;
-	protected ITypeTrait[] invListTypeTraits = new ITypeTrait[invListFields];
+    protected int invListFields = 1;
+    protected ITypeTrait[] invListTypeTraits = new ITypeTrait[invListFields];
 
-	protected int invListKeys = 1;
-	protected IBinaryComparator[] invListBinCmps = new IBinaryComparator[invListKeys];
-	protected MultiComparator invListCmp = new MultiComparator(
-			invListTypeTraits, invListBinCmps);
+    protected int invListKeys = 1;
+    protected IBinaryComparator[] invListBinCmps = new IBinaryComparator[invListKeys];
+    protected MultiComparator invListCmp = new MultiComparator(invListTypeTraits, invListBinCmps);
 
-	protected InvertedIndex invIndex;
+    protected InvertedIndex invIndex;
 
-	protected Random rnd = new Random();
+    protected Random rnd = new Random();
 
-	protected ByteBuffer frame = stageletCtx.allocateFrame();
-	protected FrameTupleAppender appender = new FrameTupleAppender(
-			stageletCtx.getFrameSize());
-	protected ArrayTupleBuilder tb = new ArrayTupleBuilder(2);
-	protected DataOutput dos = tb.getDataOutput();
+    protected ByteBuffer frame = stageletCtx.allocateFrame();
+    protected FrameTupleAppender appender = new FrameTupleAppender(stageletCtx.getFrameSize());
+    protected ArrayTupleBuilder tb = new ArrayTupleBuilder(2);
+    protected DataOutput dos = tb.getDataOutput();
 
-	protected ISerializerDeserializer[] insertSerde = {
-			UTF8StringSerializerDeserializer.INSTANCE,
-			IntegerSerializerDeserializer.INSTANCE };
-	protected RecordDescriptor insertRecDesc = new RecordDescriptor(insertSerde);
-	protected IFrameTupleAccessor accessor = new FrameTupleAccessor(
-			stageletCtx.getFrameSize(), insertRecDesc);
+    protected ISerializerDeserializer[] insertSerde = { UTF8StringSerializerDeserializer.INSTANCE,
+            IntegerSerializerDeserializer.INSTANCE };
+    protected RecordDescriptor insertRecDesc = new RecordDescriptor(insertSerde);
+    protected IFrameTupleAccessor accessor = new FrameTupleAccessor(stageletCtx.getFrameSize(), insertRecDesc);
 
-	protected FrameTupleReference tuple = new FrameTupleReference();
+    protected FrameTupleReference tuple = new FrameTupleReference();
 
-	protected ArrayList<ArrayList<Integer>> checkInvLists = new ArrayList<ArrayList<Integer>>();
+    protected ArrayList<ArrayList<Integer>> checkInvLists = new ArrayList<ArrayList<Integer>>();
 
-	protected int maxId = 1000000;
-	// protected int maxId = 1000;
-	protected int[] scanCountArray = new int[maxId];
-	protected ArrayList<Integer> expectedResults = new ArrayList<Integer>();
+    protected int maxId = 1000000;
+    // protected int maxId = 1000;
+    protected int[] scanCountArray = new int[maxId];
+    protected ArrayList<Integer> expectedResults = new ArrayList<Integer>();
 
-	protected ISerializerDeserializer[] querySerde = { UTF8StringSerializerDeserializer.INSTANCE };
-	protected RecordDescriptor queryRecDesc = new RecordDescriptor(querySerde);
+    protected ISerializerDeserializer[] querySerde = { UTF8StringSerializerDeserializer.INSTANCE };
+    protected RecordDescriptor queryRecDesc = new RecordDescriptor(querySerde);
 
-	protected FrameTupleAppender queryAppender = new FrameTupleAppender(
-			stageletCtx.getFrameSize());
-	protected ArrayTupleBuilder queryTb = new ArrayTupleBuilder(
-			querySerde.length);
-	protected DataOutput queryDos = queryTb.getDataOutput();
+    protected FrameTupleAppender queryAppender = new FrameTupleAppender(stageletCtx.getFrameSize());
+    protected ArrayTupleBuilder queryTb = new ArrayTupleBuilder(querySerde.length);
+    protected DataOutput queryDos = queryTb.getDataOutput();
 
-	protected IFrameTupleAccessor queryAccessor = new FrameTupleAccessor(
-			stageletCtx.getFrameSize(), queryRecDesc);
-	protected FrameTupleReference queryTuple = new FrameTupleReference();
+    protected IFrameTupleAccessor queryAccessor = new FrameTupleAccessor(stageletCtx.getFrameSize(), queryRecDesc);
+    protected FrameTupleReference queryTuple = new FrameTupleReference();
 
-	protected ITokenFactory tokenFactory;
-	protected IBinaryTokenizer tokenizer;
+    protected ITokenFactory tokenFactory;
+    protected IBinaryTokenizer tokenizer;
 
-	protected TOccurrenceSearcher searcher;
-	protected IInvertedIndexResultCursor resultCursor;
+    protected TOccurrenceSearcher searcher;
+    protected IInvertedIndexResultCursor resultCursor;
 
-	/**
-	 * Initialize members, generate data, and bulk load the inverted index.
-	 * 
-	 */
-	@Before
-	public void start() throws Exception {
-		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES,
-				MAX_OPEN_FILES);
-		bufferCache = TestStorageManagerComponentHolder
-				.getBufferCache(stageletCtx);
-		fmp = TestStorageManagerComponentHolder.getFileMapProvider(stageletCtx);
+    /**
+     * Initialize members, generate data, and bulk load the inverted index.
+     * 
+     */
+    @Before
+    public void start() throws Exception {
+        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES);
+        bufferCache = TestStorageManagerComponentHolder.getBufferCache(stageletCtx);
+        fmp = TestStorageManagerComponentHolder.getFileMapProvider(stageletCtx);
 
-		// --- BTREE ---
+        // --- BTREE ---
 
-		bufferCache.createFile(btreeFile);
-		btreeFileId = fmp.lookupFileId(btreeFile);
-		bufferCache.openFile(btreeFileId);
+        bufferCache.createFile(btreeFile);
+        btreeFileId = fmp.lookupFileId(btreeFile);
+        bufferCache.openFile(btreeFileId);
 
-		// token (key)
-		typeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-		// startPageId
-		typeTraits[1] = new TypeTrait(4);
-		// endPageId
-		typeTraits[2] = new TypeTrait(4);
-		// startOff
-		typeTraits[3] = new TypeTrait(4);
-		// numElements
-		typeTraits[4] = new TypeTrait(4);
+        // token (key)
+        typeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        // startPageId
+        typeTraits[1] = new TypeTrait(4);
+        // endPageId
+        typeTraits[2] = new TypeTrait(4);
+        // startOff
+        typeTraits[3] = new TypeTrait(4);
+        // numElements
+        typeTraits[4] = new TypeTrait(4);
 
-		btreeBinCmps[0] = UTF8StringBinaryComparatorFactory.INSTANCE
-				.createBinaryComparator();
+        btreeBinCmps[0] = UTF8StringBinaryComparatorFactory.INSTANCE.createBinaryComparator();
 
-		freePageManager = new LinkedListFreePageManager(bufferCache,
-				btreeFileId, 0, metaFrameFactory);
+        freePageManager = new LinkedListFreePageManager(bufferCache, btreeFileId, 0, metaFrameFactory);
 
-		btree = new BTree(bufferCache, freePageManager, interiorFrameFactory,
-				leafFrameFactory, btreeCmp);
-		btree.create(btreeFileId, leafFrame, metaFrame);
-		btree.open(btreeFileId);
+        btree = new BTree(bufferCache, freePageManager, interiorFrameFactory, leafFrameFactory, btreeCmp);
+        btree.create(btreeFileId, leafFrame, metaFrame);
+        btree.open(btreeFileId);
 
-		// --- INVERTED INDEX ---
+        // --- INVERTED INDEX ---
 
-		bufferCache.createFile(invListsFile);
-		invListsFileId = fmp.lookupFileId(invListsFile);
-		bufferCache.openFile(invListsFileId);
+        bufferCache.createFile(invListsFile);
+        invListsFileId = fmp.lookupFileId(invListsFile);
+        bufferCache.openFile(invListsFileId);
 
-		invListTypeTraits[0] = new TypeTrait(4);
-		invListBinCmps[0] = IntegerBinaryComparatorFactory.INSTANCE
-				.createBinaryComparator();
+        invListTypeTraits[0] = new TypeTrait(4);
+        invListBinCmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
 
-		invIndex = new InvertedIndex(bufferCache, btree, invListCmp);
-		invIndex.open(invListsFileId);
+        invIndex = new InvertedIndex(bufferCache, btree, invListCmp);
+        invIndex.open(invListsFileId);
 
-		rnd.setSeed(50);
+        rnd.setSeed(50);
 
-		accessor.reset(frame);
-		queryAccessor.reset(frame);
-	}
+        accessor.reset(frame);
+        queryAccessor.reset(frame);
+    }
 
-	@After
-	public void deinit() throws HyracksDataException {
-		AbstractInvIndexTest.tearDown();
-		btree.close();
-		invIndex.close();
-		bufferCache.closeFile(btreeFileId);
-		bufferCache.closeFile(invListsFileId);
-		bufferCache.close();
-	}
+    @After
+    public void deinit() throws HyracksDataException {
+        AbstractInvIndexTest.tearDown();
+        btree.close();
+        invIndex.close();
+        bufferCache.closeFile(btreeFileId);
+        bufferCache.closeFile(invListsFileId);
+        bufferCache.close();
+    }
 }
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/AbstractInvIndexTest.java b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/AbstractInvIndexTest.java
index cc8ab15..c4bc5b9 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/AbstractInvIndexTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/AbstractInvIndexTest.java
@@ -22,22 +22,19 @@
 
 public abstract class AbstractInvIndexTest {
 
-	protected static final Logger LOGGER = Logger
-			.getLogger(AbstractInvIndexTest.class.getName());
+    protected static final Logger LOGGER = Logger.getLogger(AbstractInvIndexTest.class.getName());
 
-	protected final static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
-			"ddMMyy-hhmmssSS");
-	protected final static String tmpDir = System.getProperty("java.io.tmpdir");
-	protected final static String sep = System.getProperty("file.separator");
-	protected final static String baseFileName = tmpDir + sep
-			+ simpleDateFormat.format(new Date());
-	protected final static String btreeFileName = baseFileName + "btree";
-	protected final static String invListsFileName = baseFileName + "invlists";
+    protected final static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMyy-hhmmssSS");
+    protected final static String tmpDir = System.getProperty("java.io.tmpdir");
+    protected final static String sep = System.getProperty("file.separator");
+    protected final static String baseFileName = tmpDir + sep + simpleDateFormat.format(new Date());
+    protected final static String btreeFileName = baseFileName + "btree";
+    protected final static String invListsFileName = baseFileName + "invlists";
 
-	public static void tearDown() {
-		File btreeFile = new File(btreeFileName);
-		btreeFile.deleteOnExit();
-		File invListsFile = new File(invListsFileName);
-		invListsFile.deleteOnExit();
-	}
+    public static void tearDown() {
+        File btreeFile = new File(btreeFileName);
+        btreeFile.deleteOnExit();
+        File invListsFile = new File(invListsFileName);
+        invListsFile.deleteOnExit();
+    }
 }
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/BulkLoadTest.java b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/BulkLoadTest.java
index fb0b7b9..2393098 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/BulkLoadTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/BulkLoadTest.java
@@ -74,272 +74,239 @@
 
 public class BulkLoadTest extends AbstractInvIndexTest {
 
-	private static final int PAGE_SIZE = 32768;
-	private static final int NUM_PAGES = 100;
-	private static final int MAX_OPEN_FILES = 10;
-	private static final int HYRACKS_FRAME_SIZE = 32768;
-	private IHyracksStageletContext stageletCtx = TestUtils
-			.create(HYRACKS_FRAME_SIZE);
+    private static final int PAGE_SIZE = 32768;
+    private static final int NUM_PAGES = 100;
+    private static final int MAX_OPEN_FILES = 10;
+    private static final int HYRACKS_FRAME_SIZE = 32768;
+    private IHyracksStageletContext stageletCtx = TestUtils.create(HYRACKS_FRAME_SIZE);
 
-	/**
-	 * This test generates a list of <word-token, id> pairs which are pre-sorted
-	 * on the token. Those pairs for the input to an inverted-index bulk load.
-	 * The contents of the inverted lists are verified against the generated
-	 * data.
-	 * 
-	 */
-	@Test
-	public void singleFieldPayloadTest() throws Exception {
+    /**
+     * This test generates a list of <word-token, id> pairs which are pre-sorted
+     * on the token. Those pairs for the input to an inverted-index bulk load.
+     * The contents of the inverted lists are verified against the generated
+     * data.
+     * 
+     */
+    @Test
+    public void singleFieldPayloadTest() throws Exception {
 
-		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES,
-				MAX_OPEN_FILES);
-		IBufferCache bufferCache = TestStorageManagerComponentHolder
-				.getBufferCache(stageletCtx);
-		IFileMapProvider fmp = TestStorageManagerComponentHolder
-				.getFileMapProvider(stageletCtx);
+        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES);
+        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(stageletCtx);
+        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(stageletCtx);
 
-		// create file refs
-		FileReference btreeFile = new FileReference(new File(btreeFileName));
-		bufferCache.createFile(btreeFile);
-		int btreeFileId = fmp.lookupFileId(btreeFile);
-		bufferCache.openFile(btreeFileId);
+        // create file refs
+        FileReference btreeFile = new FileReference(new File(btreeFileName));
+        bufferCache.createFile(btreeFile);
+        int btreeFileId = fmp.lookupFileId(btreeFile);
+        bufferCache.openFile(btreeFileId);
 
-		FileReference invListsFile = new FileReference(new File(
-				invListsFileName));
-		bufferCache.createFile(invListsFile);
-		int invListsFileId = fmp.lookupFileId(invListsFile);
-		bufferCache.openFile(invListsFileId);
+        FileReference invListsFile = new FileReference(new File(invListsFileName));
+        bufferCache.createFile(invListsFile);
+        int invListsFileId = fmp.lookupFileId(invListsFile);
+        bufferCache.openFile(invListsFileId);
 
-		// declare btree fields
-		int fieldCount = 5;
-		ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
-		// token (key)
-		typeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-		// startPageId
-		typeTraits[1] = new TypeTrait(4);
-		// endPageId
-		typeTraits[2] = new TypeTrait(4);
-		// startOff
-		typeTraits[3] = new TypeTrait(4);
-		// numElements
-		typeTraits[4] = new TypeTrait(4);
+        // declare btree fields
+        int fieldCount = 5;
+        ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
+        // token (key)
+        typeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+        // startPageId
+        typeTraits[1] = new TypeTrait(4);
+        // endPageId
+        typeTraits[2] = new TypeTrait(4);
+        // startOff
+        typeTraits[3] = new TypeTrait(4);
+        // numElements
+        typeTraits[4] = new TypeTrait(4);
 
-		// declare btree keys
-		int keyFieldCount = 1;
-		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-		cmps[0] = UTF8StringBinaryComparatorFactory.INSTANCE
-				.createBinaryComparator();
+        // declare btree keys
+        int keyFieldCount = 1;
+        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+        cmps[0] = UTF8StringBinaryComparatorFactory.INSTANCE.createBinaryComparator();
 
-		MultiComparator btreeCmp = new MultiComparator(typeTraits, cmps);
+        MultiComparator btreeCmp = new MultiComparator(typeTraits, cmps);
 
-		TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(
-				typeTraits);
-		ITreeIndexFrameFactory leafFrameFactory = new BTreeNSMLeafFrameFactory(
-				tupleWriterFactory);
-		ITreeIndexFrameFactory interiorFrameFactory = new BTreeNSMInteriorFrameFactory(
-				tupleWriterFactory);
-		ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
+        TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(typeTraits);
+        ITreeIndexFrameFactory leafFrameFactory = new BTreeNSMLeafFrameFactory(tupleWriterFactory);
+        ITreeIndexFrameFactory interiorFrameFactory = new BTreeNSMInteriorFrameFactory(tupleWriterFactory);
+        ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
 
-		ITreeIndexFrame leafFrame = leafFrameFactory.createFrame();
-		ITreeIndexFrame interiorFrame = interiorFrameFactory.createFrame();
-		ITreeIndexMetaDataFrame metaFrame = metaFrameFactory.createFrame();
+        ITreeIndexFrame leafFrame = leafFrameFactory.createFrame();
+        ITreeIndexFrame interiorFrame = interiorFrameFactory.createFrame();
+        ITreeIndexMetaDataFrame metaFrame = metaFrameFactory.createFrame();
 
-		IFreePageManager freePageManager = new LinkedListFreePageManager(
-				bufferCache, btreeFileId, 0, metaFrameFactory);
+        IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, btreeFileId, 0, metaFrameFactory);
 
-		BTree btree = new BTree(bufferCache, freePageManager,
-				interiorFrameFactory, leafFrameFactory, btreeCmp);
-		btree.create(btreeFileId, leafFrame, metaFrame);
-		btree.open(btreeFileId);
+        BTree btree = new BTree(bufferCache, freePageManager, interiorFrameFactory, leafFrameFactory, btreeCmp);
+        btree.create(btreeFileId, leafFrame, metaFrame);
+        btree.open(btreeFileId);
 
-		int invListFields = 1;
-		ITypeTrait[] invListTypeTraits = new ITypeTrait[invListFields];
-		invListTypeTraits[0] = new TypeTrait(4);
+        int invListFields = 1;
+        ITypeTrait[] invListTypeTraits = new ITypeTrait[invListFields];
+        invListTypeTraits[0] = new TypeTrait(4);
 
-		int invListKeys = 1;
-		IBinaryComparator[] invListBinCmps = new IBinaryComparator[invListKeys];
-		invListBinCmps[0] = IntegerBinaryComparatorFactory.INSTANCE
-				.createBinaryComparator();
+        int invListKeys = 1;
+        IBinaryComparator[] invListBinCmps = new IBinaryComparator[invListKeys];
+        invListBinCmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
 
-		MultiComparator invListCmp = new MultiComparator(invListTypeTraits,
-				invListBinCmps);
+        MultiComparator invListCmp = new MultiComparator(invListTypeTraits, invListBinCmps);
 
-		InvertedIndex invIndex = new InvertedIndex(bufferCache, btree,
-				invListCmp);
-		invIndex.open(invListsFileId);
+        InvertedIndex invIndex = new InvertedIndex(bufferCache, btree, invListCmp);
+        invIndex.open(invListsFileId);
 
-		Random rnd = new Random();
-		rnd.setSeed(50);
+        Random rnd = new Random();
+        rnd.setSeed(50);
 
-		ByteBuffer frame = stageletCtx.allocateFrame();
-		FrameTupleAppender appender = new FrameTupleAppender(
-				stageletCtx.getFrameSize());
-		ArrayTupleBuilder tb = new ArrayTupleBuilder(2);
-		DataOutput dos = tb.getDataOutput();
+        ByteBuffer frame = stageletCtx.allocateFrame();
+        FrameTupleAppender appender = new FrameTupleAppender(stageletCtx.getFrameSize());
+        ArrayTupleBuilder tb = new ArrayTupleBuilder(2);
+        DataOutput dos = tb.getDataOutput();
 
-		ISerializerDeserializer[] insertSerde = {
-				UTF8StringSerializerDeserializer.INSTANCE,
-				IntegerSerializerDeserializer.INSTANCE };
-		RecordDescriptor insertRecDesc = new RecordDescriptor(insertSerde);
-		IFrameTupleAccessor accessor = new FrameTupleAccessor(
-				stageletCtx.getFrameSize(), insertRecDesc);
-		accessor.reset(frame);
-		FrameTupleReference tuple = new FrameTupleReference();
+        ISerializerDeserializer[] insertSerde = { UTF8StringSerializerDeserializer.INSTANCE,
+                IntegerSerializerDeserializer.INSTANCE };
+        RecordDescriptor insertRecDesc = new RecordDescriptor(insertSerde);
+        IFrameTupleAccessor accessor = new FrameTupleAccessor(stageletCtx.getFrameSize(), insertRecDesc);
+        accessor.reset(frame);
+        FrameTupleReference tuple = new FrameTupleReference();
 
-		List<String> tokens = new ArrayList<String>();
-		tokens.add("compilers");
-		tokens.add("computer");
-		tokens.add("databases");
-		tokens.add("fast");
-		tokens.add("hyracks");
-		tokens.add("major");
-		tokens.add("science");
-		tokens.add("systems");
-		tokens.add("university");
+        List<String> tokens = new ArrayList<String>();
+        tokens.add("compilers");
+        tokens.add("computer");
+        tokens.add("databases");
+        tokens.add("fast");
+        tokens.add("hyracks");
+        tokens.add("major");
+        tokens.add("science");
+        tokens.add("systems");
+        tokens.add("university");
 
-		ArrayList<ArrayList<Integer>> checkListElements = new ArrayList<ArrayList<Integer>>();
-		for (int i = 0; i < tokens.size(); i++) {
-			checkListElements.add(new ArrayList<Integer>());
-		}
+        ArrayList<ArrayList<Integer>> checkListElements = new ArrayList<ArrayList<Integer>>();
+        for (int i = 0; i < tokens.size(); i++) {
+            checkListElements.add(new ArrayList<Integer>());
+        }
 
-		int maxId = 1000000;
-		int addProb = 0;
-		int addProbStep = 10;
+        int maxId = 1000000;
+        int addProb = 0;
+        int addProbStep = 10;
 
-		IInvertedListBuilder invListBuilder = new FixedSizeElementInvertedListBuilder(
-				invListTypeTraits);
-		InvertedIndex.BulkLoadContext ctx = invIndex.beginBulkLoad(
-				invListBuilder, HYRACKS_FRAME_SIZE, BTree.DEFAULT_FILL_FACTOR);
+        IInvertedListBuilder invListBuilder = new FixedSizeElementInvertedListBuilder(invListTypeTraits);
+        InvertedIndex.BulkLoadContext ctx = invIndex.beginBulkLoad(invListBuilder, HYRACKS_FRAME_SIZE,
+                BTree.DEFAULT_FILL_FACTOR);
 
-		int totalElements = 0;
-		for (int i = 0; i < tokens.size(); i++) {
+        int totalElements = 0;
+        for (int i = 0; i < tokens.size(); i++) {
 
-			addProb += addProbStep * (i + 1);
-			for (int j = 0; j < maxId; j++) {
-				if ((Math.abs(rnd.nextInt()) % addProb) == 0) {
+            addProb += addProbStep * (i + 1);
+            for (int j = 0; j < maxId; j++) {
+                if ((Math.abs(rnd.nextInt()) % addProb) == 0) {
 
-					totalElements++;
+                    totalElements++;
 
-					tb.reset();
-					UTF8StringSerializerDeserializer.INSTANCE.serialize(
-							tokens.get(i), dos);
-					tb.addFieldEndOffset();
-					IntegerSerializerDeserializer.INSTANCE.serialize(j, dos);
-					tb.addFieldEndOffset();
+                    tb.reset();
+                    UTF8StringSerializerDeserializer.INSTANCE.serialize(tokens.get(i), dos);
+                    tb.addFieldEndOffset();
+                    IntegerSerializerDeserializer.INSTANCE.serialize(j, dos);
+                    tb.addFieldEndOffset();
 
-					checkListElements.get(i).add(j);
+                    checkListElements.get(i).add(j);
 
-					appender.reset(frame, true);
-					appender.append(tb.getFieldEndOffsets(), tb.getByteArray(),
-							0, tb.getSize());
+                    appender.reset(frame, true);
+                    appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
 
-					tuple.reset(accessor, 0);
+                    tuple.reset(accessor, 0);
 
-					try {
-						invIndex.bulkLoadAddTuple(ctx, tuple);
-					} catch (Exception e) {
-						e.printStackTrace();
-					}
-				}
-			}
-		}
-		invIndex.endBulkLoad(ctx);
+                    try {
+                        invIndex.bulkLoadAddTuple(ctx, tuple);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+        invIndex.endBulkLoad(ctx);
 
-		// ------- START VERIFICATION -----------
+        // ------- START VERIFICATION -----------
 
-		ITreeIndexCursor btreeCursor = new BTreeRangeSearchCursor(
-				(IBTreeLeafFrame) leafFrame);
-		FrameTupleReference searchKey = new FrameTupleReference();
-		RangePredicate btreePred = new RangePredicate(true, searchKey,
-				searchKey, true, true, btreeCmp, btreeCmp);
+        ITreeIndexCursor btreeCursor = new BTreeRangeSearchCursor((IBTreeLeafFrame) leafFrame);
+        FrameTupleReference searchKey = new FrameTupleReference();
+        RangePredicate btreePred = new RangePredicate(true, searchKey, searchKey, true, true, btreeCmp, btreeCmp);
 
-		IInvertedListCursor invListCursor = new FixedSizeElementInvertedListCursor(
-				bufferCache, invListsFileId, invListTypeTraits);
+        IInvertedListCursor invListCursor = new FixedSizeElementInvertedListCursor(bufferCache, invListsFileId,
+                invListTypeTraits);
 
-		ISerializerDeserializer[] tokenSerde = { UTF8StringSerializerDeserializer.INSTANCE };
-		RecordDescriptor tokenRecDesc = new RecordDescriptor(tokenSerde);
-		FrameTupleAppender tokenAppender = new FrameTupleAppender(
-				stageletCtx.getFrameSize());
-		ArrayTupleBuilder tokenTupleBuilder = new ArrayTupleBuilder(1);
-		DataOutput tokenDos = tokenTupleBuilder.getDataOutput();
-		IFrameTupleAccessor tokenAccessor = new FrameTupleAccessor(
-				stageletCtx.getFrameSize(), tokenRecDesc);
-		tokenAccessor.reset(frame);
+        ISerializerDeserializer[] tokenSerde = { UTF8StringSerializerDeserializer.INSTANCE };
+        RecordDescriptor tokenRecDesc = new RecordDescriptor(tokenSerde);
+        FrameTupleAppender tokenAppender = new FrameTupleAppender(stageletCtx.getFrameSize());
+        ArrayTupleBuilder tokenTupleBuilder = new ArrayTupleBuilder(1);
+        DataOutput tokenDos = tokenTupleBuilder.getDataOutput();
+        IFrameTupleAccessor tokenAccessor = new FrameTupleAccessor(stageletCtx.getFrameSize(), tokenRecDesc);
+        tokenAccessor.reset(frame);
 
-		BTreeOpContext btreeOpCtx = invIndex.getBTree().createOpContext(
-				IndexOp.SEARCH, leafFrame, interiorFrame, null);
+        BTreeOpContext btreeOpCtx = invIndex.getBTree().createOpContext(IndexOp.SEARCH, leafFrame, interiorFrame, null);
 
-		// verify created inverted lists one-by-one
-		for (int i = 0; i < tokens.size(); i++) {
+        // verify created inverted lists one-by-one
+        for (int i = 0; i < tokens.size(); i++) {
 
-			tokenTupleBuilder.reset();
-			UTF8StringSerializerDeserializer.INSTANCE.serialize(tokens.get(i),
-					tokenDos);
-			tokenTupleBuilder.addFieldEndOffset();
+            tokenTupleBuilder.reset();
+            UTF8StringSerializerDeserializer.INSTANCE.serialize(tokens.get(i), tokenDos);
+            tokenTupleBuilder.addFieldEndOffset();
 
-			tokenAppender.reset(frame, true);
-			tokenAppender.append(tokenTupleBuilder.getFieldEndOffsets(),
-					tokenTupleBuilder.getByteArray(), 0,
-					tokenTupleBuilder.getSize());
+            tokenAppender.reset(frame, true);
+            tokenAppender.append(tokenTupleBuilder.getFieldEndOffsets(), tokenTupleBuilder.getByteArray(), 0,
+                    tokenTupleBuilder.getSize());
 
-			searchKey.reset(tokenAccessor, 0);
+            searchKey.reset(tokenAccessor, 0);
 
-			invIndex.openCursor(btreeCursor, btreePred, btreeOpCtx,
-					invListCursor);
+            invIndex.openCursor(btreeCursor, btreePred, btreeOpCtx, invListCursor);
 
-			invListCursor.pinPagesSync();
-			int checkIndex = 0;
-			while (invListCursor.hasNext()) {
-				invListCursor.next();
-				ITupleReference invListTuple = invListCursor.getTuple();
-				int invListElement = IntegerSerializerDeserializer.getInt(
-						invListTuple.getFieldData(0),
-						invListTuple.getFieldStart(0));
-				int checkInvListElement = checkListElements.get(i)
-						.get(checkIndex).intValue();
-				Assert.assertEquals(invListElement, checkInvListElement);
-				checkIndex++;
-			}
-			invListCursor.unpinPages();
-			Assert.assertEquals(checkIndex, checkListElements.get(i).size());
-		}
+            invListCursor.pinPagesSync();
+            int checkIndex = 0;
+            while (invListCursor.hasNext()) {
+                invListCursor.next();
+                ITupleReference invListTuple = invListCursor.getTuple();
+                int invListElement = IntegerSerializerDeserializer.getInt(invListTuple.getFieldData(0),
+                        invListTuple.getFieldStart(0));
+                int checkInvListElement = checkListElements.get(i).get(checkIndex).intValue();
+                Assert.assertEquals(invListElement, checkInvListElement);
+                checkIndex++;
+            }
+            invListCursor.unpinPages();
+            Assert.assertEquals(checkIndex, checkListElements.get(i).size());
+        }
 
-		// check that non-existing tokens have an empty inverted list
-		List<String> nonExistingTokens = new ArrayList<String>();
-		nonExistingTokens.add("watermelon");
-		nonExistingTokens.add("avocado");
-		nonExistingTokens.add("lemon");
+        // check that non-existing tokens have an empty inverted list
+        List<String> nonExistingTokens = new ArrayList<String>();
+        nonExistingTokens.add("watermelon");
+        nonExistingTokens.add("avocado");
+        nonExistingTokens.add("lemon");
 
-		for (int i = 0; i < nonExistingTokens.size(); i++) {
+        for (int i = 0; i < nonExistingTokens.size(); i++) {
 
-			tokenTupleBuilder.reset();
-			UTF8StringSerializerDeserializer.INSTANCE.serialize(
-					nonExistingTokens.get(i), tokenDos);
-			tokenTupleBuilder.addFieldEndOffset();
+            tokenTupleBuilder.reset();
+            UTF8StringSerializerDeserializer.INSTANCE.serialize(nonExistingTokens.get(i), tokenDos);
+            tokenTupleBuilder.addFieldEndOffset();
 
-			tokenAppender.reset(frame, true);
-			tokenAppender.append(tokenTupleBuilder.getFieldEndOffsets(),
-					tokenTupleBuilder.getByteArray(), 0,
-					tokenTupleBuilder.getSize());
+            tokenAppender.reset(frame, true);
+            tokenAppender.append(tokenTupleBuilder.getFieldEndOffsets(), tokenTupleBuilder.getByteArray(), 0,
+                    tokenTupleBuilder.getSize());
 
-			searchKey.reset(tokenAccessor, 0);
+            searchKey.reset(tokenAccessor, 0);
 
-			invIndex.openCursor(btreeCursor, btreePred, btreeOpCtx,
-					invListCursor);
+            invIndex.openCursor(btreeCursor, btreePred, btreeOpCtx, invListCursor);
 
-			invListCursor.pinPagesSync();
-			Assert.assertEquals(invListCursor.hasNext(), false);
-			invListCursor.unpinPages();
-		}
+            invListCursor.pinPagesSync();
+            Assert.assertEquals(invListCursor.hasNext(), false);
+            invListCursor.unpinPages();
+        }
 
-		btree.close();
-		bufferCache.closeFile(btreeFileId);
-		bufferCache.closeFile(invListsFileId);
-		bufferCache.close();
-	}
+        btree.close();
+        bufferCache.closeFile(btreeFileId);
+        bufferCache.closeFile(invListsFileId);
+        bufferCache.close();
+    }
 
-	@AfterClass
-	public static void deinit() {
-		AbstractInvIndexTest.tearDown();
-	}
+    @AfterClass
+    public static void deinit() {
+        AbstractInvIndexTest.tearDown();
+    }
 }
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/FixedSizeFrameTupleTest.java b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/FixedSizeFrameTupleTest.java
index 0b49ec1..6e2ab22 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/FixedSizeFrameTupleTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/FixedSizeFrameTupleTest.java
@@ -31,48 +31,45 @@
 
 public class FixedSizeFrameTupleTest {
 
-	private static int FRAME_SIZE = 4096;
+    private static int FRAME_SIZE = 4096;
 
-	private Random rnd = new Random(50);
+    private Random rnd = new Random(50);
 
-	/**
-	 * This test verifies the correct behavior of the FixedSizeFrameTuple class.
-	 * Frames containing FixedSizeFrameTuple's require neither tuple slots nor
-	 * field slots. The tests inserts generated data into a frame until the
-	 * frame is full, and then verifies the frame's contents.
-	 * 
-	 */
-	@Test
-	public void singleFieldTest() throws Exception {
-		ByteBuffer buffer = ByteBuffer.allocate(FRAME_SIZE);
+    /**
+     * This test verifies the correct behavior of the FixedSizeFrameTuple class.
+     * Frames containing FixedSizeFrameTuple's require neither tuple slots nor
+     * field slots. The tests inserts generated data into a frame until the
+     * frame is full, and then verifies the frame's contents.
+     * 
+     */
+    @Test
+    public void singleFieldTest() throws Exception {
+        ByteBuffer buffer = ByteBuffer.allocate(FRAME_SIZE);
 
-		ITypeTrait[] fields = new TypeTrait[1];
-		fields[0] = new TypeTrait(4);
+        ITypeTrait[] fields = new TypeTrait[1];
+        fields[0] = new TypeTrait(4);
 
-		FixedSizeFrameTupleAppender ftapp = new FixedSizeFrameTupleAppender(
-				FRAME_SIZE, fields);
-		FixedSizeFrameTupleAccessor ftacc = new FixedSizeFrameTupleAccessor(
-				FRAME_SIZE, fields);
+        FixedSizeFrameTupleAppender ftapp = new FixedSizeFrameTupleAppender(FRAME_SIZE, fields);
+        FixedSizeFrameTupleAccessor ftacc = new FixedSizeFrameTupleAccessor(FRAME_SIZE, fields);
 
-		boolean frameHasSpace = true;
+        boolean frameHasSpace = true;
 
-		ArrayList<Integer> check = new ArrayList<Integer>();
+        ArrayList<Integer> check = new ArrayList<Integer>();
 
-		ftapp.reset(buffer, true);
-		while (frameHasSpace) {
-			int val = rnd.nextInt();
-			frameHasSpace = ftapp.append(val);
-			if (frameHasSpace) {
-				check.add(val);
-				ftapp.incrementTupleCount(1);
-			}
-		}
+        ftapp.reset(buffer, true);
+        while (frameHasSpace) {
+            int val = rnd.nextInt();
+            frameHasSpace = ftapp.append(val);
+            if (frameHasSpace) {
+                check.add(val);
+                ftapp.incrementTupleCount(1);
+            }
+        }
 
-		ftacc.reset(buffer);
-		for (int i = 0; i < ftacc.getTupleCount(); i++) {
-			int val = IntegerSerializerDeserializer.getInt(ftacc.getBuffer()
-					.array(), ftacc.getTupleStartOffset(i));
-			Assert.assertEquals(check.get(i).intValue(), val);
-		}
-	}
+        ftacc.reset(buffer);
+        for (int i = 0; i < ftacc.getTupleCount(); i++) {
+            int val = IntegerSerializerDeserializer.getInt(ftacc.getBuffer().array(), ftacc.getTupleStartOffset(i));
+            Assert.assertEquals(check.get(i).intValue(), val);
+        }
+    }
 }
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/NGramTokenizerTest.java b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/NGramTokenizerTest.java
index 5f15a91..83b1764 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/NGramTokenizerTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/NGramTokenizerTest.java
@@ -41,207 +41,199 @@
 
 public class NGramTokenizerTest {
 
-	private char PRECHAR = '#';
-	private char POSTCHAR = '$';
+    private char PRECHAR = '#';
+    private char POSTCHAR = '$';
 
-	private String str = "Jürgen S. Generic's Car";
-	private byte[] inputBuffer;
+    private String str = "Jürgen S. Generic's Car";
+    private byte[] inputBuffer;
 
-	private int gramLength = 3;
+    private int gramLength = 3;
 
-	private void getExpectedGrams(String s, int gramLength,
-			ArrayList<String> grams, boolean prePost) {
+    private void getExpectedGrams(String s, int gramLength, ArrayList<String> grams, boolean prePost) {
 
-		String tmp = s.toLowerCase();
-		if (prePost) {
-			StringBuilder preBuilder = new StringBuilder();
-			for (int i = 0; i < gramLength - 1; i++) {
-				preBuilder.append(PRECHAR);
-			}
-			String pre = preBuilder.toString();
+        String tmp = s.toLowerCase();
+        if (prePost) {
+            StringBuilder preBuilder = new StringBuilder();
+            for (int i = 0; i < gramLength - 1; i++) {
+                preBuilder.append(PRECHAR);
+            }
+            String pre = preBuilder.toString();
 
-			StringBuilder postBuilder = new StringBuilder();
-			for (int i = 0; i < gramLength - 1; i++) {
-				postBuilder.append(POSTCHAR);
-			}
-			String post = postBuilder.toString();
+            StringBuilder postBuilder = new StringBuilder();
+            for (int i = 0; i < gramLength - 1; i++) {
+                postBuilder.append(POSTCHAR);
+            }
+            String post = postBuilder.toString();
 
-			tmp = pre + s.toLowerCase() + post;
-		}
+            tmp = pre + s.toLowerCase() + post;
+        }
 
-		for (int i = 0; i < tmp.length() - gramLength + 1; i++) {
-			String gram = tmp.substring(i, i + gramLength);
-			grams.add(gram);
-		}
-	}
+        for (int i = 0; i < tmp.length() - gramLength + 1; i++) {
+            String gram = tmp.substring(i, i + gramLength);
+            grams.add(gram);
+        }
+    }
 
-	@Before
-	public void init() throws Exception {
-		// serialize string into bytes
-		ByteArrayOutputStream baos = new ByteArrayOutputStream();
-		DataOutput dos = new DataOutputStream(baos);
-		dos.writeUTF(str);
-		inputBuffer = baos.toByteArray();
-	}
+    @Before
+    public void init() throws Exception {
+        // serialize string into bytes
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        DataOutput dos = new DataOutputStream(baos);
+        dos.writeUTF(str);
+        inputBuffer = baos.toByteArray();
+    }
 
-	void runTestNGramTokenizerWithCountedHashedUTF8Tokens(boolean prePost)
-			throws IOException {
-		HashedUTF8NGramTokenFactory tokenFactory = new HashedUTF8NGramTokenFactory();
-		NGramUTF8StringBinaryTokenizer tokenizer = new NGramUTF8StringBinaryTokenizer(
-				gramLength, prePost, false, false, tokenFactory);
-		tokenizer.reset(inputBuffer, 0, inputBuffer.length);
+    void runTestNGramTokenizerWithCountedHashedUTF8Tokens(boolean prePost) throws IOException {
+        HashedUTF8NGramTokenFactory tokenFactory = new HashedUTF8NGramTokenFactory();
+        NGramUTF8StringBinaryTokenizer tokenizer = new NGramUTF8StringBinaryTokenizer(gramLength, prePost, false,
+                false, tokenFactory);
+        tokenizer.reset(inputBuffer, 0, inputBuffer.length);
 
-		ArrayList<String> expectedGrams = new ArrayList<String>();
-		getExpectedGrams(str, gramLength, expectedGrams, prePost);
-		ArrayList<Integer> expectedHashedGrams = new ArrayList<Integer>();
-		HashMap<String, Integer> gramCounts = new HashMap<String, Integer>();
-		for (String s : expectedGrams) {
-			Integer count = gramCounts.get(s);
-			if (count == null) {
-				count = 1;
-				gramCounts.put(s, count);
-			} else {
-				count++;
-			}
+        ArrayList<String> expectedGrams = new ArrayList<String>();
+        getExpectedGrams(str, gramLength, expectedGrams, prePost);
+        ArrayList<Integer> expectedHashedGrams = new ArrayList<Integer>();
+        HashMap<String, Integer> gramCounts = new HashMap<String, Integer>();
+        for (String s : expectedGrams) {
+            Integer count = gramCounts.get(s);
+            if (count == null) {
+                count = 1;
+                gramCounts.put(s, count);
+            } else {
+                count++;
+            }
 
-			int hash = tokenHash(s, count);
-			expectedHashedGrams.add(hash);
-		}
+            int hash = tokenHash(s, count);
+            expectedHashedGrams.add(hash);
+        }
 
-		int tokenCount = 0;
+        int tokenCount = 0;
 
-		while (tokenizer.hasNext()) {
-			tokenizer.next();
+        while (tokenizer.hasNext()) {
+            tokenizer.next();
 
-			// serialize hashed token
-			ByteArrayOutputStream tokenBaos = new ByteArrayOutputStream();
-			DataOutput tokenDos = new DataOutputStream(tokenBaos);
+            // serialize hashed token
+            ByteArrayOutputStream tokenBaos = new ByteArrayOutputStream();
+            DataOutput tokenDos = new DataOutputStream(tokenBaos);
 
-			IToken token = tokenizer.getToken();
-			token.serializeToken(tokenDos);
+            IToken token = tokenizer.getToken();
+            token.serializeToken(tokenDos);
 
-			// deserialize token
-			ByteArrayInputStream bais = new ByteArrayInputStream(
-					tokenBaos.toByteArray());
-			DataInput in = new DataInputStream(bais);
+            // deserialize token
+            ByteArrayInputStream bais = new ByteArrayInputStream(tokenBaos.toByteArray());
+            DataInput in = new DataInputStream(bais);
 
-			Integer hashedGram = in.readInt();
+            Integer hashedGram = in.readInt();
 
-			// System.out.println(hashedGram);
+            // System.out.println(hashedGram);
 
-			Assert.assertEquals(expectedHashedGrams.get(tokenCount), hashedGram);
+            Assert.assertEquals(expectedHashedGrams.get(tokenCount), hashedGram);
 
-			tokenCount++;
-		}
-		// System.out.println("---------");
-	}
+            tokenCount++;
+        }
+        // System.out.println("---------");
+    }
 
-	void runTestNGramTokenizerWithHashedUTF8Tokens(boolean prePost)
-			throws IOException {
-		HashedUTF8NGramTokenFactory tokenFactory = new HashedUTF8NGramTokenFactory();
-		NGramUTF8StringBinaryTokenizer tokenizer = new NGramUTF8StringBinaryTokenizer(
-				gramLength, prePost, true, false, tokenFactory);
-		tokenizer.reset(inputBuffer, 0, inputBuffer.length);
+    void runTestNGramTokenizerWithHashedUTF8Tokens(boolean prePost) throws IOException {
+        HashedUTF8NGramTokenFactory tokenFactory = new HashedUTF8NGramTokenFactory();
+        NGramUTF8StringBinaryTokenizer tokenizer = new NGramUTF8StringBinaryTokenizer(gramLength, prePost, true, false,
+                tokenFactory);
+        tokenizer.reset(inputBuffer, 0, inputBuffer.length);
 
-		ArrayList<String> expectedGrams = new ArrayList<String>();
-		getExpectedGrams(str, gramLength, expectedGrams, prePost);
-		ArrayList<Integer> expectedHashedGrams = new ArrayList<Integer>();
-		for (String s : expectedGrams) {
-			int hash = tokenHash(s, 1);
-			expectedHashedGrams.add(hash);
-		}
+        ArrayList<String> expectedGrams = new ArrayList<String>();
+        getExpectedGrams(str, gramLength, expectedGrams, prePost);
+        ArrayList<Integer> expectedHashedGrams = new ArrayList<Integer>();
+        for (String s : expectedGrams) {
+            int hash = tokenHash(s, 1);
+            expectedHashedGrams.add(hash);
+        }
 
-		int tokenCount = 0;
+        int tokenCount = 0;
 
-		while (tokenizer.hasNext()) {
-			tokenizer.next();
+        while (tokenizer.hasNext()) {
+            tokenizer.next();
 
-			// serialize hashed token
-			ByteArrayOutputStream tokenBaos = new ByteArrayOutputStream();
-			DataOutput tokenDos = new DataOutputStream(tokenBaos);
+            // serialize hashed token
+            ByteArrayOutputStream tokenBaos = new ByteArrayOutputStream();
+            DataOutput tokenDos = new DataOutputStream(tokenBaos);
 
-			IToken token = tokenizer.getToken();
-			token.serializeToken(tokenDos);
+            IToken token = tokenizer.getToken();
+            token.serializeToken(tokenDos);
 
-			// deserialize token
-			ByteArrayInputStream bais = new ByteArrayInputStream(
-					tokenBaos.toByteArray());
-			DataInput in = new DataInputStream(bais);
+            // deserialize token
+            ByteArrayInputStream bais = new ByteArrayInputStream(tokenBaos.toByteArray());
+            DataInput in = new DataInputStream(bais);
 
-			Integer hashedGram = in.readInt();
+            Integer hashedGram = in.readInt();
 
-			// System.out.println(hashedGram);
+            // System.out.println(hashedGram);
 
-			Assert.assertEquals(expectedHashedGrams.get(tokenCount), hashedGram);
+            Assert.assertEquals(expectedHashedGrams.get(tokenCount), hashedGram);
 
-			tokenCount++;
-		}
-		// System.out.println("---------");
-	}
+            tokenCount++;
+        }
+        // System.out.println("---------");
+    }
 
-	void runTestNGramTokenizerWithUTF8Tokens(boolean prePost)
-			throws IOException {
-		UTF8NGramTokenFactory tokenFactory = new UTF8NGramTokenFactory();
-		NGramUTF8StringBinaryTokenizer tokenizer = new NGramUTF8StringBinaryTokenizer(
-				gramLength, prePost, true, false, tokenFactory);
-		tokenizer.reset(inputBuffer, 0, inputBuffer.length);
+    void runTestNGramTokenizerWithUTF8Tokens(boolean prePost) throws IOException {
+        UTF8NGramTokenFactory tokenFactory = new UTF8NGramTokenFactory();
+        NGramUTF8StringBinaryTokenizer tokenizer = new NGramUTF8StringBinaryTokenizer(gramLength, prePost, true, false,
+                tokenFactory);
+        tokenizer.reset(inputBuffer, 0, inputBuffer.length);
 
-		ArrayList<String> expectedGrams = new ArrayList<String>();
-		getExpectedGrams(str, gramLength, expectedGrams, prePost);
+        ArrayList<String> expectedGrams = new ArrayList<String>();
+        getExpectedGrams(str, gramLength, expectedGrams, prePost);
 
-		int tokenCount = 0;
+        int tokenCount = 0;
 
-		while (tokenizer.hasNext()) {
-			tokenizer.next();
+        while (tokenizer.hasNext()) {
+            tokenizer.next();
 
-			// serialize hashed token
-			ByteArrayOutputStream tokenBaos = new ByteArrayOutputStream();
-			DataOutput tokenDos = new DataOutputStream(tokenBaos);
+            // serialize hashed token
+            ByteArrayOutputStream tokenBaos = new ByteArrayOutputStream();
+            DataOutput tokenDos = new DataOutputStream(tokenBaos);
 
-			IToken token = tokenizer.getToken();
-			token.serializeToken(tokenDos);
+            IToken token = tokenizer.getToken();
+            token.serializeToken(tokenDos);
 
-			// deserialize token
-			ByteArrayInputStream bais = new ByteArrayInputStream(
-					tokenBaos.toByteArray());
-			DataInput in = new DataInputStream(bais);
+            // deserialize token
+            ByteArrayInputStream bais = new ByteArrayInputStream(tokenBaos.toByteArray());
+            DataInput in = new DataInputStream(bais);
 
-			String strGram = in.readUTF();
+            String strGram = in.readUTF();
 
-			// System.out.println("\"" + strGram + "\"");
+            // System.out.println("\"" + strGram + "\"");
 
-			Assert.assertEquals(expectedGrams.get(tokenCount), strGram);
+            Assert.assertEquals(expectedGrams.get(tokenCount), strGram);
 
-			tokenCount++;
-		}
-		// System.out.println("---------");
-	}
+            tokenCount++;
+        }
+        // System.out.println("---------");
+    }
 
-	@Test
-	public void testNGramTokenizerWithCountedHashedUTF8Tokens()
-			throws Exception {
-		runTestNGramTokenizerWithCountedHashedUTF8Tokens(false);
-		runTestNGramTokenizerWithCountedHashedUTF8Tokens(true);
-	}
+    @Test
+    public void testNGramTokenizerWithCountedHashedUTF8Tokens() throws Exception {
+        runTestNGramTokenizerWithCountedHashedUTF8Tokens(false);
+        runTestNGramTokenizerWithCountedHashedUTF8Tokens(true);
+    }
 
-	@Test
-	public void testNGramTokenizerWithHashedUTF8Tokens() throws Exception {
-		runTestNGramTokenizerWithHashedUTF8Tokens(false);
-		runTestNGramTokenizerWithHashedUTF8Tokens(true);
-	}
+    @Test
+    public void testNGramTokenizerWithHashedUTF8Tokens() throws Exception {
+        runTestNGramTokenizerWithHashedUTF8Tokens(false);
+        runTestNGramTokenizerWithHashedUTF8Tokens(true);
+    }
 
-	@Test
-	public void testNGramTokenizerWithUTF8Tokens() throws IOException {
-		runTestNGramTokenizerWithUTF8Tokens(false);
-		runTestNGramTokenizerWithUTF8Tokens(true);
-	}
+    @Test
+    public void testNGramTokenizerWithUTF8Tokens() throws IOException {
+        runTestNGramTokenizerWithUTF8Tokens(false);
+        runTestNGramTokenizerWithUTF8Tokens(true);
+    }
 
-	public int tokenHash(String token, int tokenCount) {
-		int h = AbstractUTF8Token.GOLDEN_RATIO_32;
-		for (int i = 0; i < token.length(); i++) {
-			h ^= token.charAt(i);
-			h *= AbstractUTF8Token.GOLDEN_RATIO_32;
-		}
-		return h + tokenCount;
-	}
+    public int tokenHash(String token, int tokenCount) {
+        int h = AbstractUTF8Token.GOLDEN_RATIO_32;
+        for (int i = 0; i < token.length(); i++) {
+            h ^= token.charAt(i);
+            h *= AbstractUTF8Token.GOLDEN_RATIO_32;
+        }
+        return h + tokenCount;
+    }
 }
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/SearchPerfTest.java b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/SearchPerfTest.java
index 161f20f..00533d0 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/SearchPerfTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/SearchPerfTest.java
@@ -50,243 +50,231 @@
  */
 public class SearchPerfTest extends AbstractInvIndexSearchTest {
 
-	protected List<String> tokens = new ArrayList<String>();
+    protected List<String> tokens = new ArrayList<String>();
 
-	@Before
-	public void start() throws Exception {
-		super.start();
-		tokenFactory = new UTF8WordTokenFactory();
-		tokenizer = new DelimitedUTF8StringBinaryTokenizer(true, false,
-				tokenFactory);
-		searcher = new TOccurrenceSearcher(stageletCtx, invIndex, tokenizer);
-		resultCursor = new SearchResultCursor(
-				searcher.createResultFrameTupleAccessor(),
-				searcher.createResultTupleReference());
-		loadData();
-	}
+    @Before
+    public void start() throws Exception {
+        super.start();
+        tokenFactory = new UTF8WordTokenFactory();
+        tokenizer = new DelimitedUTF8StringBinaryTokenizer(true, false, tokenFactory);
+        searcher = new TOccurrenceSearcher(stageletCtx, invIndex, tokenizer);
+        resultCursor = new SearchResultCursor(searcher.createResultFrameTupleAccessor(),
+                searcher.createResultTupleReference());
+        loadData();
+    }
 
-	public void loadData() throws HyracksDataException {
-		tokens.add("compilers");
-		tokens.add("computer");
-		tokens.add("databases");
-		tokens.add("fast");
-		tokens.add("hyracks");
-		tokens.add("major");
-		tokens.add("science");
-		tokens.add("systems");
-		tokens.add("university");
+    public void loadData() throws HyracksDataException {
+        tokens.add("compilers");
+        tokens.add("computer");
+        tokens.add("databases");
+        tokens.add("fast");
+        tokens.add("hyracks");
+        tokens.add("major");
+        tokens.add("science");
+        tokens.add("systems");
+        tokens.add("university");
 
-		for (int i = 0; i < tokens.size(); i++) {
-			checkInvLists.add(new ArrayList<Integer>());
-		}
+        for (int i = 0; i < tokens.size(); i++) {
+            checkInvLists.add(new ArrayList<Integer>());
+        }
 
-		// for generating length-skewed inverted lists
-		int addProb = 0;
-		int addProbStep = 10;
+        // for generating length-skewed inverted lists
+        int addProb = 0;
+        int addProbStep = 10;
 
-		IInvertedListBuilder invListBuilder = new FixedSizeElementInvertedListBuilder(
-				invListTypeTraits);
-		InvertedIndex.BulkLoadContext ctx = invIndex.beginBulkLoad(
-				invListBuilder, HYRACKS_FRAME_SIZE, BTree.DEFAULT_FILL_FACTOR);
+        IInvertedListBuilder invListBuilder = new FixedSizeElementInvertedListBuilder(invListTypeTraits);
+        InvertedIndex.BulkLoadContext ctx = invIndex.beginBulkLoad(invListBuilder, HYRACKS_FRAME_SIZE,
+                BTree.DEFAULT_FILL_FACTOR);
 
-		int totalElements = 0;
-		for (int i = 0; i < tokens.size(); i++) {
+        int totalElements = 0;
+        for (int i = 0; i < tokens.size(); i++) {
 
-			addProb += addProbStep * (i + 1);
-			for (int j = 0; j < maxId; j++) {
-				if ((Math.abs(rnd.nextInt()) % addProb) == 0) {
+            addProb += addProbStep * (i + 1);
+            for (int j = 0; j < maxId; j++) {
+                if ((Math.abs(rnd.nextInt()) % addProb) == 0) {
 
-					totalElements++;
+                    totalElements++;
 
-					tb.reset();
-					UTF8StringSerializerDeserializer.INSTANCE.serialize(
-							tokens.get(i), dos);
-					tb.addFieldEndOffset();
-					IntegerSerializerDeserializer.INSTANCE.serialize(j, dos);
-					tb.addFieldEndOffset();
+                    tb.reset();
+                    UTF8StringSerializerDeserializer.INSTANCE.serialize(tokens.get(i), dos);
+                    tb.addFieldEndOffset();
+                    IntegerSerializerDeserializer.INSTANCE.serialize(j, dos);
+                    tb.addFieldEndOffset();
 
-					checkInvLists.get(i).add(j);
+                    checkInvLists.get(i).add(j);
 
-					appender.reset(frame, true);
-					appender.append(tb.getFieldEndOffsets(), tb.getByteArray(),
-							0, tb.getSize());
+                    appender.reset(frame, true);
+                    appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
 
-					tuple.reset(accessor, 0);
+                    tuple.reset(accessor, 0);
 
-					try {
-						invIndex.bulkLoadAddTuple(ctx, tuple);
-					} catch (Exception e) {
-						e.printStackTrace();
-					}
-				}
-			}
-		}
-		invIndex.endBulkLoad(ctx);
-	}
+                    try {
+                        invIndex.bulkLoadAddTuple(ctx, tuple);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+        invIndex.endBulkLoad(ctx);
+    }
 
-	/**
-	 * Determine the expected results with the ScanCount algorithm. The
-	 * ScanCount algorithm is very simple, so we can be confident the results
-	 * are correct.
-	 * 
-	 */
-	protected void fillExpectedResults(int[] queryTokenIndexes,
-			int numQueryTokens, int occurrenceThreshold) {
-		// reset scan count array
-		for (int i = 0; i < maxId; i++) {
-			scanCountArray[i] = 0;
-		}
+    /**
+     * Determine the expected results with the ScanCount algorithm. The
+     * ScanCount algorithm is very simple, so we can be confident the results
+     * are correct.
+     * 
+     */
+    protected void fillExpectedResults(int[] queryTokenIndexes, int numQueryTokens, int occurrenceThreshold) {
+        // reset scan count array
+        for (int i = 0; i < maxId; i++) {
+            scanCountArray[i] = 0;
+        }
 
-		// count occurrences
-		for (int i = 0; i < numQueryTokens; i++) {
-			ArrayList<Integer> list = checkInvLists.get(queryTokenIndexes[i]);
-			for (int j = 0; j < list.size(); j++) {
-				scanCountArray[list.get(j)]++;
-			}
-		}
+        // count occurrences
+        for (int i = 0; i < numQueryTokens; i++) {
+            ArrayList<Integer> list = checkInvLists.get(queryTokenIndexes[i]);
+            for (int j = 0; j < list.size(); j++) {
+                scanCountArray[list.get(j)]++;
+            }
+        }
 
-		// check threshold
-		expectedResults.clear();
-		for (int i = 0; i < maxId; i++) {
-			if (scanCountArray[i] >= occurrenceThreshold) {
-				expectedResults.add(i);
-			}
-		}
-	}
+        // check threshold
+        expectedResults.clear();
+        for (int i = 0; i < maxId; i++) {
+            if (scanCountArray[i] >= occurrenceThreshold) {
+                expectedResults.add(i);
+            }
+        }
+    }
 
-	/**
-	 * Generates a specified number of queries. Each query consists of a set of
-	 * randomly chosen tokens that are picked from the pre-defined set of
-	 * tokens. We run each query, measure it's time, and verify it's results
-	 * against the results produced by ScanCount, implemented in
-	 * fillExpectedResults().
-	 * 
-	 */
-	private void runQueries(IInvertedIndexSearchModifier searchModifier,
-			int numQueries) throws Exception {
+    /**
+     * Generates a specified number of queries. Each query consists of a set of
+     * randomly chosen tokens that are picked from the pre-defined set of
+     * tokens. We run each query, measure it's time, and verify it's results
+     * against the results produced by ScanCount, implemented in
+     * fillExpectedResults().
+     * 
+     */
+    private void runQueries(IInvertedIndexSearchModifier searchModifier, int numQueries) throws Exception {
 
-		rnd.setSeed(50);
+        rnd.setSeed(50);
 
-		// generate random queries
-		int[] queryTokenIndexes = new int[tokens.size()];
-		for (int i = 0; i < numQueries; i++) {
+        // generate random queries
+        int[] queryTokenIndexes = new int[tokens.size()];
+        for (int i = 0; i < numQueries; i++) {
 
-			int numQueryTokens = Math.abs(rnd.nextInt() % tokens.size()) + 1;
-			for (int j = 0; j < numQueryTokens; j++) {
-				queryTokenIndexes[j] = Math.abs(rnd.nextInt() % tokens.size());
-			}
+            int numQueryTokens = Math.abs(rnd.nextInt() % tokens.size()) + 1;
+            for (int j = 0; j < numQueryTokens; j++) {
+                queryTokenIndexes[j] = Math.abs(rnd.nextInt() % tokens.size());
+            }
 
-			StringBuilder strBuilder = new StringBuilder();
-			for (int j = 0; j < numQueryTokens; j++) {
-				strBuilder.append(tokens.get(queryTokenIndexes[j]));
-				if (j + 1 != numQueryTokens)
-					strBuilder.append(" ");
-			}
+            StringBuilder strBuilder = new StringBuilder();
+            for (int j = 0; j < numQueryTokens; j++) {
+                strBuilder.append(tokens.get(queryTokenIndexes[j]));
+                if (j + 1 != numQueryTokens)
+                    strBuilder.append(" ");
+            }
 
-			String queryString = strBuilder.toString();
+            String queryString = strBuilder.toString();
 
-			queryTb.reset();
-			UTF8StringSerializerDeserializer.INSTANCE.serialize(queryString,
-					queryDos);
-			queryTb.addFieldEndOffset();
+            queryTb.reset();
+            UTF8StringSerializerDeserializer.INSTANCE.serialize(queryString, queryDos);
+            queryTb.addFieldEndOffset();
 
-			queryAppender.reset(frame, true);
-			queryAppender.append(queryTb.getFieldEndOffsets(),
-					queryTb.getByteArray(), 0, queryTb.getSize());
-			queryTuple.reset(queryAccessor, 0);
+            queryAppender.reset(frame, true);
+            queryAppender.append(queryTb.getFieldEndOffsets(), queryTb.getByteArray(), 0, queryTb.getSize());
+            queryTuple.reset(queryAccessor, 0);
 
-			boolean panic = false;
+            boolean panic = false;
 
-			int repeats = 1;
-			double totalTime = 0;
-			for (int j = 0; j < repeats; j++) {
-				long timeStart = System.currentTimeMillis();
-				try {
-					searcher.reset();
-					searcher.search(resultCursor, queryTuple, 0, searchModifier);
-				} catch (OccurrenceThresholdPanicException e) {
-					panic = true;
-				}
-				long timeEnd = System.currentTimeMillis();
-				totalTime += timeEnd - timeStart;
-			}
-			double avgTime = totalTime / (double) repeats;
-			LOGGER.info(i + ": " + "\"" + queryString + "\": " + avgTime + "ms");
+            int repeats = 1;
+            double totalTime = 0;
+            for (int j = 0; j < repeats; j++) {
+                long timeStart = System.currentTimeMillis();
+                try {
+                    searcher.reset();
+                    searcher.search(resultCursor, queryTuple, 0, searchModifier);
+                } catch (OccurrenceThresholdPanicException e) {
+                    panic = true;
+                }
+                long timeEnd = System.currentTimeMillis();
+                totalTime += timeEnd - timeStart;
+            }
+            double avgTime = totalTime / (double) repeats;
+            LOGGER.info(i + ": " + "\"" + queryString + "\": " + avgTime + "ms");
 
-			if (!panic) {
+            if (!panic) {
 
-				fillExpectedResults(queryTokenIndexes, numQueryTokens,
-						searcher.getOccurrenceThreshold());
+                fillExpectedResults(queryTokenIndexes, numQueryTokens, searcher.getOccurrenceThreshold());
 
-				// verify results
-				int checkIndex = 0;
-				while (resultCursor.hasNext()) {
-					resultCursor.next();
-					ITupleReference resultTuple = resultCursor.getTuple();
-					int id = IntegerSerializerDeserializer.getInt(
-							resultTuple.getFieldData(0),
-							resultTuple.getFieldStart(0));
-					Assert.assertEquals(expectedResults.get(checkIndex)
-							.intValue(), id);
-					checkIndex++;
-				}
+                // verify results
+                int checkIndex = 0;
+                while (resultCursor.hasNext()) {
+                    resultCursor.next();
+                    ITupleReference resultTuple = resultCursor.getTuple();
+                    int id = IntegerSerializerDeserializer.getInt(resultTuple.getFieldData(0),
+                            resultTuple.getFieldStart(0));
+                    Assert.assertEquals(expectedResults.get(checkIndex).intValue(), id);
+                    checkIndex++;
+                }
 
-				if (expectedResults.size() != checkIndex) {
-					LOGGER.info("CHECKING");
-					StringBuilder expectedStrBuilder = new StringBuilder();
-					for (Integer x : expectedResults) {
-						expectedStrBuilder.append(x + " ");
-					}
-					LOGGER.info(expectedStrBuilder.toString());
-				}
+                if (expectedResults.size() != checkIndex) {
+                    LOGGER.info("CHECKING");
+                    StringBuilder expectedStrBuilder = new StringBuilder();
+                    for (Integer x : expectedResults) {
+                        expectedStrBuilder.append(x + " ");
+                    }
+                    LOGGER.info(expectedStrBuilder.toString());
+                }
 
-				Assert.assertEquals(expectedResults.size(), checkIndex);
-			}
-		}
-	}
+                Assert.assertEquals(expectedResults.size(), checkIndex);
+            }
+        }
+    }
 
-	/**
-	 * Runs 50 random conjunctive search queries to test the
-	 * ConjunctiveSearchModifier.
-	 * 
-	 */
-	@Test
-	public void conjunctiveKeywordQueryTest() throws Exception {
-		IInvertedIndexSearchModifier searchModifier = new ConjunctiveSearchModifier();
-		runQueries(searchModifier, 50);
-	}
+    /**
+     * Runs 50 random conjunctive search queries to test the
+     * ConjunctiveSearchModifier.
+     * 
+     */
+    @Test
+    public void conjunctiveKeywordQueryTest() throws Exception {
+        IInvertedIndexSearchModifier searchModifier = new ConjunctiveSearchModifier();
+        runQueries(searchModifier, 50);
+    }
 
-	/**
-	 * Runs 50 random jaccard-based search queries with thresholds 1.0, 0.9,
-	 * 0.8, 0.7, 0.6, 0.5. Tests the JaccardSearchModifier.
-	 * 
-	 */
-	@Test
-	public void jaccardKeywordQueryTest() throws Exception {
-		JaccardSearchModifier searchModifier = new JaccardSearchModifier(1.0f);
+    /**
+     * Runs 50 random jaccard-based search queries with thresholds 1.0, 0.9,
+     * 0.8, 0.7, 0.6, 0.5. Tests the JaccardSearchModifier.
+     * 
+     */
+    @Test
+    public void jaccardKeywordQueryTest() throws Exception {
+        JaccardSearchModifier searchModifier = new JaccardSearchModifier(1.0f);
 
-		LOGGER.info("JACCARD: " + 1.0f);
-		searchModifier.setJaccThresh(1.0f);
-		runQueries(searchModifier, 50);
+        LOGGER.info("JACCARD: " + 1.0f);
+        searchModifier.setJaccThresh(1.0f);
+        runQueries(searchModifier, 50);
 
-		LOGGER.info("JACCARD: " + 0.9f);
-		searchModifier.setJaccThresh(0.9f);
-		runQueries(searchModifier, 50);
+        LOGGER.info("JACCARD: " + 0.9f);
+        searchModifier.setJaccThresh(0.9f);
+        runQueries(searchModifier, 50);
 
-		LOGGER.info("JACCARD: " + 0.8f);
-		searchModifier.setJaccThresh(0.8f);
-		runQueries(searchModifier, 50);
+        LOGGER.info("JACCARD: " + 0.8f);
+        searchModifier.setJaccThresh(0.8f);
+        runQueries(searchModifier, 50);
 
-		LOGGER.info("JACCARD: " + 0.7f);
-		searchModifier.setJaccThresh(0.7f);
-		runQueries(searchModifier, 50);
+        LOGGER.info("JACCARD: " + 0.7f);
+        searchModifier.setJaccThresh(0.7f);
+        runQueries(searchModifier, 50);
 
-		LOGGER.info("JACCARD: " + 0.6f);
-		searchModifier.setJaccThresh(0.6f);
-		runQueries(searchModifier, 50);
+        LOGGER.info("JACCARD: " + 0.6f);
+        searchModifier.setJaccThresh(0.6f);
+        runQueries(searchModifier, 50);
 
-		LOGGER.info("JACCARD: " + 0.5f);
-		searchModifier.setJaccThresh(0.5f);
-		runQueries(searchModifier, 50);
-	}
+        LOGGER.info("JACCARD: " + 0.5f);
+        searchModifier.setJaccThresh(0.5f);
+        runQueries(searchModifier, 50);
+    }
 }
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/SearchTest.java b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/SearchTest.java
index d9fef2c..9161e5a 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/SearchTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/SearchTest.java
@@ -30,247 +30,235 @@
 
 public class SearchTest extends AbstractInvIndexSearchTest {
 
-	protected List<String> dataStrings = new ArrayList<String>();
-	protected List<String> firstNames = new ArrayList<String>();
-	protected List<String> lastNames = new ArrayList<String>();
+    protected List<String> dataStrings = new ArrayList<String>();
+    protected List<String> firstNames = new ArrayList<String>();
+    protected List<String> lastNames = new ArrayList<String>();
 
-	@Before
-	public void start() throws Exception {
-		super.start();
-		tokenFactory = new UTF8NGramTokenFactory();
-		tokenizer = new NGramUTF8StringBinaryTokenizer(3, false, true, false,
-				tokenFactory);
-		searcher = new TOccurrenceSearcher(stageletCtx, invIndex, tokenizer);
-		resultCursor = new SearchResultCursor(
-				searcher.createResultFrameTupleAccessor(),
-				searcher.createResultTupleReference());
-		generateDataStrings();
-		loadData();
-	}
+    @Before
+    public void start() throws Exception {
+        super.start();
+        tokenFactory = new UTF8NGramTokenFactory();
+        tokenizer = new NGramUTF8StringBinaryTokenizer(3, false, true, false, tokenFactory);
+        searcher = new TOccurrenceSearcher(stageletCtx, invIndex, tokenizer);
+        resultCursor = new SearchResultCursor(searcher.createResultFrameTupleAccessor(),
+                searcher.createResultTupleReference());
+        generateDataStrings();
+        loadData();
+    }
 
-	public void generateDataStrings() {
-		firstNames.add("Kathrin");
-		firstNames.add("Cathrin");
-		firstNames.add("Kathryn");
-		firstNames.add("Cathryn");
-		firstNames.add("Kathrine");
-		firstNames.add("Cathrine");
-		firstNames.add("Kathryne");
-		firstNames.add("Cathryne");
-		firstNames.add("Katherin");
-		firstNames.add("Catherin");
-		firstNames.add("Katheryn");
-		firstNames.add("Catheryn");
-		firstNames.add("Katherine");
-		firstNames.add("Catherine");
-		firstNames.add("Katheryne");
-		firstNames.add("Catheryne");
-		firstNames.add("John");
-		firstNames.add("Jack");
-		firstNames.add("Jonathan");
-		firstNames.add("Nathan");
+    public void generateDataStrings() {
+        firstNames.add("Kathrin");
+        firstNames.add("Cathrin");
+        firstNames.add("Kathryn");
+        firstNames.add("Cathryn");
+        firstNames.add("Kathrine");
+        firstNames.add("Cathrine");
+        firstNames.add("Kathryne");
+        firstNames.add("Cathryne");
+        firstNames.add("Katherin");
+        firstNames.add("Catherin");
+        firstNames.add("Katheryn");
+        firstNames.add("Catheryn");
+        firstNames.add("Katherine");
+        firstNames.add("Catherine");
+        firstNames.add("Katheryne");
+        firstNames.add("Catheryne");
+        firstNames.add("John");
+        firstNames.add("Jack");
+        firstNames.add("Jonathan");
+        firstNames.add("Nathan");
 
-		lastNames.add("Miller");
-		lastNames.add("Myller");
-		lastNames.add("Keller");
-		lastNames.add("Ketler");
-		lastNames.add("Muller");
-		lastNames.add("Fuller");
-		lastNames.add("Smith");
-		lastNames.add("Smyth");
-		lastNames.add("Smithe");
-		lastNames.add("Smythe");
+        lastNames.add("Miller");
+        lastNames.add("Myller");
+        lastNames.add("Keller");
+        lastNames.add("Ketler");
+        lastNames.add("Muller");
+        lastNames.add("Fuller");
+        lastNames.add("Smith");
+        lastNames.add("Smyth");
+        lastNames.add("Smithe");
+        lastNames.add("Smythe");
 
-		// Generate all 'firstName lastName' combinations as data strings
-		for (String f : firstNames) {
-			for (String l : lastNames) {
-				dataStrings.add(f + " " + l);
-			}
-		}
-	}
+        // Generate all 'firstName lastName' combinations as data strings
+        for (String f : firstNames) {
+            for (String l : lastNames) {
+                dataStrings.add(f + " " + l);
+            }
+        }
+    }
 
-	private class TokenIdPair implements Comparable<TokenIdPair> {
-		public ByteArrayAccessibleOutputStream baaos = new ByteArrayAccessibleOutputStream();
-		public DataOutputStream dos = new DataOutputStream(baaos);
-		public int id;
+    private class TokenIdPair implements Comparable<TokenIdPair> {
+        public ByteArrayAccessibleOutputStream baaos = new ByteArrayAccessibleOutputStream();
+        public DataOutputStream dos = new DataOutputStream(baaos);
+        public int id;
 
-		TokenIdPair(IToken token, int id) throws IOException {
-			token.serializeToken(dos);
-			this.id = id;
-		}
+        TokenIdPair(IToken token, int id) throws IOException {
+            token.serializeToken(dos);
+            this.id = id;
+        }
 
-		@Override
-		public int compareTo(TokenIdPair o) {
-			int cmp = btreeBinCmps[0].compare(baaos.getByteArray(), 0,
-					baaos.getByteArray().length, o.baaos.getByteArray(), 0,
-					o.baaos.getByteArray().length);
-			if (cmp == 0) {
-				return id - o.id;
-			} else {
-				return cmp;
-			}
-		}
-	}
+        @Override
+        public int compareTo(TokenIdPair o) {
+            int cmp = btreeBinCmps[0].compare(baaos.getByteArray(), 0, baaos.getByteArray().length,
+                    o.baaos.getByteArray(), 0, o.baaos.getByteArray().length);
+            if (cmp == 0) {
+                return id - o.id;
+            } else {
+                return cmp;
+            }
+        }
+    }
 
-	public void loadData() throws IOException {
-		List<TokenIdPair> pairs = new ArrayList<TokenIdPair>();
-		// generate pairs for subsequent sorting and bulk-loading
-		int id = 0;
-		for (String s : dataStrings) {
-			ByteArrayAccessibleOutputStream baaos = new ByteArrayAccessibleOutputStream();
-			DataOutputStream dos = new DataOutputStream(baaos);
-			UTF8StringSerializerDeserializer.INSTANCE.serialize(s, dos);
-			tokenizer.reset(baaos.getByteArray(), 0, baaos.size());
-			int tokenCount = 0;
-			while (tokenizer.hasNext()) {
-				tokenizer.next();
-				IToken token = tokenizer.getToken();
-				pairs.add(new TokenIdPair(token, id));
-				++tokenCount;
-			}
-			++id;
-		}
-		Collections.sort(pairs);
+    public void loadData() throws IOException {
+        List<TokenIdPair> pairs = new ArrayList<TokenIdPair>();
+        // generate pairs for subsequent sorting and bulk-loading
+        int id = 0;
+        for (String s : dataStrings) {
+            ByteArrayAccessibleOutputStream baaos = new ByteArrayAccessibleOutputStream();
+            DataOutputStream dos = new DataOutputStream(baaos);
+            UTF8StringSerializerDeserializer.INSTANCE.serialize(s, dos);
+            tokenizer.reset(baaos.getByteArray(), 0, baaos.size());
+            int tokenCount = 0;
+            while (tokenizer.hasNext()) {
+                tokenizer.next();
+                IToken token = tokenizer.getToken();
+                pairs.add(new TokenIdPair(token, id));
+                ++tokenCount;
+            }
+            ++id;
+        }
+        Collections.sort(pairs);
 
-		// bulk load index
-		IInvertedListBuilder invListBuilder = new FixedSizeElementInvertedListBuilder(
-				invListTypeTraits);
-		InvertedIndex.BulkLoadContext ctx = invIndex.beginBulkLoad(
-				invListBuilder, HYRACKS_FRAME_SIZE, BTree.DEFAULT_FILL_FACTOR);
+        // bulk load index
+        IInvertedListBuilder invListBuilder = new FixedSizeElementInvertedListBuilder(invListTypeTraits);
+        InvertedIndex.BulkLoadContext ctx = invIndex.beginBulkLoad(invListBuilder, HYRACKS_FRAME_SIZE,
+                BTree.DEFAULT_FILL_FACTOR);
 
-		for (TokenIdPair t : pairs) {
-			tb.reset();
-			tb.addField(t.baaos.getByteArray(), 0,
-					t.baaos.getByteArray().length);
-			IntegerSerializerDeserializer.INSTANCE.serialize(t.id, dos);
-			tb.addFieldEndOffset();
+        for (TokenIdPair t : pairs) {
+            tb.reset();
+            tb.addField(t.baaos.getByteArray(), 0, t.baaos.getByteArray().length);
+            IntegerSerializerDeserializer.INSTANCE.serialize(t.id, dos);
+            tb.addFieldEndOffset();
 
-			appender.reset(frame, true);
-			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0,
-					tb.getSize());
+            appender.reset(frame, true);
+            appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
 
-			tuple.reset(accessor, 0);
+            tuple.reset(accessor, 0);
 
-			try {
-				invIndex.bulkLoadAddTuple(ctx, tuple);
-			} catch (Exception e) {
-				e.printStackTrace();
-			}
-		}
-		invIndex.endBulkLoad(ctx);
-	}
+            try {
+                invIndex.bulkLoadAddTuple(ctx, tuple);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        invIndex.endBulkLoad(ctx);
+    }
 
-	/**
-	 * Runs a specified number of randomly picked strings from dataStrings as
-	 * queries. We run each query, measure it's time, and print it's results.
-	 * 
-	 */
-	private void runQueries(IInvertedIndexSearchModifier searchModifier,
-			int numQueries) throws Exception {
+    /**
+     * Runs a specified number of randomly picked strings from dataStrings as
+     * queries. We run each query, measure it's time, and print it's results.
+     * 
+     */
+    private void runQueries(IInvertedIndexSearchModifier searchModifier, int numQueries) throws Exception {
 
-		rnd.setSeed(50);
+        rnd.setSeed(50);
 
-		for (int i = 0; i < numQueries; i++) {
+        for (int i = 0; i < numQueries; i++) {
 
-			int queryIndex = Math.abs(rnd.nextInt() % dataStrings.size());
-			String queryString = dataStrings.get(queryIndex);
+            int queryIndex = Math.abs(rnd.nextInt() % dataStrings.size());
+            String queryString = dataStrings.get(queryIndex);
 
-			queryTb.reset();
-			UTF8StringSerializerDeserializer.INSTANCE.serialize(queryString,
-					queryDos);
-			queryTb.addFieldEndOffset();
+            queryTb.reset();
+            UTF8StringSerializerDeserializer.INSTANCE.serialize(queryString, queryDos);
+            queryTb.addFieldEndOffset();
 
-			queryAppender.reset(frame, true);
-			queryAppender.append(queryTb.getFieldEndOffsets(),
-					queryTb.getByteArray(), 0, queryTb.getSize());
-			queryTuple.reset(queryAccessor, 0);
+            queryAppender.reset(frame, true);
+            queryAppender.append(queryTb.getFieldEndOffsets(), queryTb.getByteArray(), 0, queryTb.getSize());
+            queryTuple.reset(queryAccessor, 0);
 
-			int repeats = 1;
-			double totalTime = 0;
-			for (int j = 0; j < repeats; j++) {
-				long timeStart = System.currentTimeMillis();
-				try {
-					searcher.reset();
-					searcher.search(resultCursor, queryTuple, 0, searchModifier);
-				} catch (OccurrenceThresholdPanicException e) {
-					// ignore panic queries
-				}
-				long timeEnd = System.currentTimeMillis();
-				totalTime += timeEnd - timeStart;
-			}
-			double avgTime = totalTime / (double) repeats;
-			StringBuilder strBuilder = new StringBuilder();
-			strBuilder.append(i + ": " + "\"" + queryString + "\": " + avgTime
-					+ "ms" + "\n");
-			strBuilder.append("CANDIDATE RESULTS:\n");
-			while (resultCursor.hasNext()) {
-				resultCursor.next();
-				ITupleReference resultTuple = resultCursor.getTuple();
-				int id = IntegerSerializerDeserializer.getInt(
-						resultTuple.getFieldData(0),
-						resultTuple.getFieldStart(0));
-				strBuilder.append(id + " " + dataStrings.get(id));
-				strBuilder.append('\n');
-			}
-			// remove trailing newline
-			strBuilder.deleteCharAt(strBuilder.length() - 1);
-			LOGGER.info(strBuilder.toString());
-		}
-	}
+            int repeats = 1;
+            double totalTime = 0;
+            for (int j = 0; j < repeats; j++) {
+                long timeStart = System.currentTimeMillis();
+                try {
+                    searcher.reset();
+                    searcher.search(resultCursor, queryTuple, 0, searchModifier);
+                } catch (OccurrenceThresholdPanicException e) {
+                    // ignore panic queries
+                }
+                long timeEnd = System.currentTimeMillis();
+                totalTime += timeEnd - timeStart;
+            }
+            double avgTime = totalTime / (double) repeats;
+            StringBuilder strBuilder = new StringBuilder();
+            strBuilder.append(i + ": " + "\"" + queryString + "\": " + avgTime + "ms" + "\n");
+            strBuilder.append("CANDIDATE RESULTS:\n");
+            while (resultCursor.hasNext()) {
+                resultCursor.next();
+                ITupleReference resultTuple = resultCursor.getTuple();
+                int id = IntegerSerializerDeserializer
+                        .getInt(resultTuple.getFieldData(0), resultTuple.getFieldStart(0));
+                strBuilder.append(id + " " + dataStrings.get(id));
+                strBuilder.append('\n');
+            }
+            // remove trailing newline
+            strBuilder.deleteCharAt(strBuilder.length() - 1);
+            LOGGER.info(strBuilder.toString());
+        }
+    }
 
-	/**
-	 * Runs 5 random conjunctive search queries to test the
-	 * ConjunctiveSearchModifier.
-	 * 
-	 */
-	@Test
-	public void conjunctiveQueryTest() throws Exception {
-		IInvertedIndexSearchModifier searchModifier = new ConjunctiveSearchModifier();
-		runQueries(searchModifier, 5);
-	}
+    /**
+     * Runs 5 random conjunctive search queries to test the
+     * ConjunctiveSearchModifier.
+     * 
+     */
+    @Test
+    public void conjunctiveQueryTest() throws Exception {
+        IInvertedIndexSearchModifier searchModifier = new ConjunctiveSearchModifier();
+        runQueries(searchModifier, 5);
+    }
 
-	/**
-	 * Runs 5 random jaccard-based search queries with thresholds 0.9, 0.8, 0.7.
-	 * Tests the JaccardSearchModifier.
-	 * 
-	 */
-	@Test
-	public void jaccardQueryTest() throws Exception {
-		JaccardSearchModifier searchModifier = new JaccardSearchModifier(1.0f);
+    /**
+     * Runs 5 random jaccard-based search queries with thresholds 0.9, 0.8, 0.7.
+     * Tests the JaccardSearchModifier.
+     * 
+     */
+    @Test
+    public void jaccardQueryTest() throws Exception {
+        JaccardSearchModifier searchModifier = new JaccardSearchModifier(1.0f);
 
-		LOGGER.info("JACCARD: " + 0.9f);
-		searchModifier.setJaccThresh(0.9f);
-		runQueries(searchModifier, 5);
+        LOGGER.info("JACCARD: " + 0.9f);
+        searchModifier.setJaccThresh(0.9f);
+        runQueries(searchModifier, 5);
 
-		LOGGER.info("JACCARD: " + 0.8f);
-		searchModifier.setJaccThresh(0.8f);
-		runQueries(searchModifier, 5);
+        LOGGER.info("JACCARD: " + 0.8f);
+        searchModifier.setJaccThresh(0.8f);
+        runQueries(searchModifier, 5);
 
-		LOGGER.info("JACCARD: " + 0.7f);
-		searchModifier.setJaccThresh(0.7f);
-		runQueries(searchModifier, 5);
-	}
+        LOGGER.info("JACCARD: " + 0.7f);
+        searchModifier.setJaccThresh(0.7f);
+        runQueries(searchModifier, 5);
+    }
 
-	/**
-	 * Runs 5 random edit-distance based search queries with thresholds 1, 2, 3.
-	 * Tests the EditDistanceSearchModifier.
-	 * 
-	 */
-	@Test
-	public void editDistanceQueryTest() throws Exception {
-		EditDistanceSearchModifier searchModifier = new EditDistanceSearchModifier(
-				3, 0);
+    /**
+     * Runs 5 random edit-distance based search queries with thresholds 1, 2, 3.
+     * Tests the EditDistanceSearchModifier.
+     * 
+     */
+    @Test
+    public void editDistanceQueryTest() throws Exception {
+        EditDistanceSearchModifier searchModifier = new EditDistanceSearchModifier(3, 0);
 
-		LOGGER.info("EDIT DISTANCE: " + 1);
-		searchModifier.setEdThresh(1);
-		runQueries(searchModifier, 5);
+        LOGGER.info("EDIT DISTANCE: " + 1);
+        searchModifier.setEdThresh(1);
+        runQueries(searchModifier, 5);
 
-		LOGGER.info("EDIT DISTANCE: " + 2);
-		searchModifier.setEdThresh(2);
-		runQueries(searchModifier, 5);
+        LOGGER.info("EDIT DISTANCE: " + 2);
+        searchModifier.setEdThresh(2);
+        runQueries(searchModifier, 5);
 
-		LOGGER.info("EDIT DISTANCE: " + 3);
-		searchModifier.setEdThresh(3);
-		runQueries(searchModifier, 5);
-	}
+        LOGGER.info("EDIT DISTANCE: " + 3);
+        searchModifier.setEdThresh(3);
+        runQueries(searchModifier, 5);
+    }
 }
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/WordTokenizerTest.java b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/WordTokenizerTest.java
index 57fe306..41b63e7 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/WordTokenizerTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/WordTokenizerTest.java
@@ -42,181 +42,173 @@
 
 public class WordTokenizerTest {
 
-	private String text = "Hello World, I would like to inform you of the importance of Foo Bar. Yes, Foo Bar. Jürgen.";
-	private byte[] inputBuffer;
+    private String text = "Hello World, I would like to inform you of the importance of Foo Bar. Yes, Foo Bar. Jürgen.";
+    private byte[] inputBuffer;
 
-	private ArrayList<String> expectedUTF8Tokens = new ArrayList<String>();
-	private ArrayList<Integer> expectedHashedUTF8Tokens = new ArrayList<Integer>();
-	private ArrayList<Integer> expectedCountedHashedUTF8Tokens = new ArrayList<Integer>();
+    private ArrayList<String> expectedUTF8Tokens = new ArrayList<String>();
+    private ArrayList<Integer> expectedHashedUTF8Tokens = new ArrayList<Integer>();
+    private ArrayList<Integer> expectedCountedHashedUTF8Tokens = new ArrayList<Integer>();
 
-	@Before
-	public void init() throws IOException {
-		// serialize text into bytes
-		ByteArrayOutputStream baos = new ByteArrayOutputStream();
-		DataOutput dos = new DataOutputStream(baos);
-		dos.writeUTF(text);
-		inputBuffer = baos.toByteArray();
+    @Before
+    public void init() throws IOException {
+        // serialize text into bytes
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        DataOutput dos = new DataOutputStream(baos);
+        dos.writeUTF(text);
+        inputBuffer = baos.toByteArray();
 
-		// init expected string tokens
-		expectedUTF8Tokens.add("hello");
-		expectedUTF8Tokens.add("world");
-		expectedUTF8Tokens.add("i");
-		expectedUTF8Tokens.add("would");
-		expectedUTF8Tokens.add("like");
-		expectedUTF8Tokens.add("to");
-		expectedUTF8Tokens.add("inform");
-		expectedUTF8Tokens.add("you");
-		expectedUTF8Tokens.add("of");
-		expectedUTF8Tokens.add("the");
-		expectedUTF8Tokens.add("importance");
-		expectedUTF8Tokens.add("of");
-		expectedUTF8Tokens.add("foo");
-		expectedUTF8Tokens.add("bar");
-		expectedUTF8Tokens.add("yes");
-		expectedUTF8Tokens.add("foo");
-		expectedUTF8Tokens.add("bar");
-		expectedUTF8Tokens.add("jürgen");
+        // init expected string tokens
+        expectedUTF8Tokens.add("hello");
+        expectedUTF8Tokens.add("world");
+        expectedUTF8Tokens.add("i");
+        expectedUTF8Tokens.add("would");
+        expectedUTF8Tokens.add("like");
+        expectedUTF8Tokens.add("to");
+        expectedUTF8Tokens.add("inform");
+        expectedUTF8Tokens.add("you");
+        expectedUTF8Tokens.add("of");
+        expectedUTF8Tokens.add("the");
+        expectedUTF8Tokens.add("importance");
+        expectedUTF8Tokens.add("of");
+        expectedUTF8Tokens.add("foo");
+        expectedUTF8Tokens.add("bar");
+        expectedUTF8Tokens.add("yes");
+        expectedUTF8Tokens.add("foo");
+        expectedUTF8Tokens.add("bar");
+        expectedUTF8Tokens.add("jürgen");
 
-		// hashed tokens ignoring token count
-		for (int i = 0; i < expectedUTF8Tokens.size(); i++) {
-			int hash = tokenHash(expectedUTF8Tokens.get(i), 1);
-			expectedHashedUTF8Tokens.add(hash);
-		}
+        // hashed tokens ignoring token count
+        for (int i = 0; i < expectedUTF8Tokens.size(); i++) {
+            int hash = tokenHash(expectedUTF8Tokens.get(i), 1);
+            expectedHashedUTF8Tokens.add(hash);
+        }
 
-		// hashed tokens using token count
-		HashMap<String, Integer> tokenCounts = new HashMap<String, Integer>();
-		for (int i = 0; i < expectedUTF8Tokens.size(); i++) {
-			Integer count = tokenCounts.get(expectedUTF8Tokens.get(i));
-			if (count == null) {
-				count = 1;
-				tokenCounts.put(expectedUTF8Tokens.get(i), count);
-			} else {
-				count++;
-			}
+        // hashed tokens using token count
+        HashMap<String, Integer> tokenCounts = new HashMap<String, Integer>();
+        for (int i = 0; i < expectedUTF8Tokens.size(); i++) {
+            Integer count = tokenCounts.get(expectedUTF8Tokens.get(i));
+            if (count == null) {
+                count = 1;
+                tokenCounts.put(expectedUTF8Tokens.get(i), count);
+            } else {
+                count++;
+            }
 
-			int hash = tokenHash(expectedUTF8Tokens.get(i), count);
-			expectedCountedHashedUTF8Tokens.add(hash);
-		}
-	}
+            int hash = tokenHash(expectedUTF8Tokens.get(i), count);
+            expectedCountedHashedUTF8Tokens.add(hash);
+        }
+    }
 
-	@Test
-	public void testWordTokenizerWithCountedHashedUTF8Tokens()
-			throws IOException {
+    @Test
+    public void testWordTokenizerWithCountedHashedUTF8Tokens() throws IOException {
 
-		HashedUTF8WordTokenFactory tokenFactory = new HashedUTF8WordTokenFactory();
-		DelimitedUTF8StringBinaryTokenizer tokenizer = new DelimitedUTF8StringBinaryTokenizer(
-				false, false, tokenFactory);
+        HashedUTF8WordTokenFactory tokenFactory = new HashedUTF8WordTokenFactory();
+        DelimitedUTF8StringBinaryTokenizer tokenizer = new DelimitedUTF8StringBinaryTokenizer(false, false,
+                tokenFactory);
 
-		tokenizer.reset(inputBuffer, 0, inputBuffer.length);
+        tokenizer.reset(inputBuffer, 0, inputBuffer.length);
 
-		int tokenCount = 0;
+        int tokenCount = 0;
 
-		while (tokenizer.hasNext()) {
-			tokenizer.next();
+        while (tokenizer.hasNext()) {
+            tokenizer.next();
 
-			// serialize token
-			ByteArrayOutputStream tokenBaos = new ByteArrayOutputStream();
-			DataOutput tokenDos = new DataOutputStream(tokenBaos);
+            // serialize token
+            ByteArrayOutputStream tokenBaos = new ByteArrayOutputStream();
+            DataOutput tokenDos = new DataOutputStream(tokenBaos);
 
-			IToken token = tokenizer.getToken();
-			token.serializeToken(tokenDos);
+            IToken token = tokenizer.getToken();
+            token.serializeToken(tokenDos);
 
-			// deserialize token
-			ByteArrayInputStream bais = new ByteArrayInputStream(
-					tokenBaos.toByteArray());
-			DataInput in = new DataInputStream(bais);
+            // deserialize token
+            ByteArrayInputStream bais = new ByteArrayInputStream(tokenBaos.toByteArray());
+            DataInput in = new DataInputStream(bais);
 
-			Integer hashedToken = in.readInt();
+            Integer hashedToken = in.readInt();
 
-			// System.out.println(hashedToken);
+            // System.out.println(hashedToken);
 
-			Assert.assertEquals(hashedToken,
-					expectedCountedHashedUTF8Tokens.get(tokenCount));
+            Assert.assertEquals(hashedToken, expectedCountedHashedUTF8Tokens.get(tokenCount));
 
-			tokenCount++;
-		}
-	}
+            tokenCount++;
+        }
+    }
 
-	@Test
-	public void testWordTokenizerWithHashedUTF8Tokens() throws IOException {
+    @Test
+    public void testWordTokenizerWithHashedUTF8Tokens() throws IOException {
 
-		HashedUTF8WordTokenFactory tokenFactory = new HashedUTF8WordTokenFactory();
-		DelimitedUTF8StringBinaryTokenizer tokenizer = new DelimitedUTF8StringBinaryTokenizer(
-				true, false, tokenFactory);
+        HashedUTF8WordTokenFactory tokenFactory = new HashedUTF8WordTokenFactory();
+        DelimitedUTF8StringBinaryTokenizer tokenizer = new DelimitedUTF8StringBinaryTokenizer(true, false, tokenFactory);
 
-		tokenizer.reset(inputBuffer, 0, inputBuffer.length);
+        tokenizer.reset(inputBuffer, 0, inputBuffer.length);
 
-		int tokenCount = 0;
+        int tokenCount = 0;
 
-		while (tokenizer.hasNext()) {
-			tokenizer.next();
+        while (tokenizer.hasNext()) {
+            tokenizer.next();
 
-			// serialize token
-			ByteArrayOutputStream tokenBaos = new ByteArrayOutputStream();
-			DataOutput tokenDos = new DataOutputStream(tokenBaos);
+            // serialize token
+            ByteArrayOutputStream tokenBaos = new ByteArrayOutputStream();
+            DataOutput tokenDos = new DataOutputStream(tokenBaos);
 
-			IToken token = tokenizer.getToken();
-			token.serializeToken(tokenDos);
+            IToken token = tokenizer.getToken();
+            token.serializeToken(tokenDos);
 
-			// deserialize token
-			ByteArrayInputStream bais = new ByteArrayInputStream(
-					tokenBaos.toByteArray());
-			DataInput in = new DataInputStream(bais);
+            // deserialize token
+            ByteArrayInputStream bais = new ByteArrayInputStream(tokenBaos.toByteArray());
+            DataInput in = new DataInputStream(bais);
 
-			Integer hashedToken = in.readInt();
+            Integer hashedToken = in.readInt();
 
-			// System.out.println(hashedToken);
+            // System.out.println(hashedToken);
 
-			Assert.assertEquals(expectedHashedUTF8Tokens.get(tokenCount),
-					hashedToken);
+            Assert.assertEquals(expectedHashedUTF8Tokens.get(tokenCount), hashedToken);
 
-			tokenCount++;
-		}
-	}
+            tokenCount++;
+        }
+    }
 
-	@Test
-	public void testWordTokenizerWithUTF8Tokens() throws IOException {
+    @Test
+    public void testWordTokenizerWithUTF8Tokens() throws IOException {
 
-		UTF8WordTokenFactory tokenFactory = new UTF8WordTokenFactory();
-		DelimitedUTF8StringBinaryTokenizer tokenizer = new DelimitedUTF8StringBinaryTokenizer(
-				true, false, tokenFactory);
+        UTF8WordTokenFactory tokenFactory = new UTF8WordTokenFactory();
+        DelimitedUTF8StringBinaryTokenizer tokenizer = new DelimitedUTF8StringBinaryTokenizer(true, false, tokenFactory);
 
-		tokenizer.reset(inputBuffer, 0, inputBuffer.length);
+        tokenizer.reset(inputBuffer, 0, inputBuffer.length);
 
-		int tokenCount = 0;
+        int tokenCount = 0;
 
-		while (tokenizer.hasNext()) {
-			tokenizer.next();
+        while (tokenizer.hasNext()) {
+            tokenizer.next();
 
-			// serialize hashed token
-			ByteArrayOutputStream tokenBaos = new ByteArrayOutputStream();
-			DataOutput tokenDos = new DataOutputStream(tokenBaos);
+            // serialize hashed token
+            ByteArrayOutputStream tokenBaos = new ByteArrayOutputStream();
+            DataOutput tokenDos = new DataOutputStream(tokenBaos);
 
-			IToken token = tokenizer.getToken();
-			token.serializeToken(tokenDos);
+            IToken token = tokenizer.getToken();
+            token.serializeToken(tokenDos);
 
-			// deserialize token
-			ByteArrayInputStream bais = new ByteArrayInputStream(
-					tokenBaos.toByteArray());
-			DataInput in = new DataInputStream(bais);
+            // deserialize token
+            ByteArrayInputStream bais = new ByteArrayInputStream(tokenBaos.toByteArray());
+            DataInput in = new DataInputStream(bais);
 
-			String strToken = in.readUTF();
+            String strToken = in.readUTF();
 
-			// System.out.println(strToken);
+            // System.out.println(strToken);
 
-			Assert.assertEquals(expectedUTF8Tokens.get(tokenCount), strToken);
+            Assert.assertEquals(expectedUTF8Tokens.get(tokenCount), strToken);
 
-			tokenCount++;
-		}
-	}
+            tokenCount++;
+        }
+    }
 
-	// JAQL
-	public int tokenHash(String token, int tokenCount) {
-		int h = AbstractUTF8Token.GOLDEN_RATIO_32;
-		for (int i = 0; i < token.length(); i++) {
-			h ^= token.charAt(i);
-			h *= AbstractUTF8Token.GOLDEN_RATIO_32;
-		}
-		return h + tokenCount;
-	}
+    // JAQL
+    public int tokenHash(String token, int tokenCount) {
+        int h = AbstractUTF8Token.GOLDEN_RATIO_32;
+        for (int i = 0; i < token.length(); i++) {
+            h ^= token.charAt(i);
+            h *= AbstractUTF8Token.GOLDEN_RATIO_32;
+        }
+        return h + tokenCount;
+    }
 }
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeTest.java b/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeTest.java
index 72c3f38..9659553 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeTest.java
@@ -36,9 +36,11 @@
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.FrameTupleReference;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
 import edu.uci.ics.hyracks.dataflow.common.data.comparators.DoubleBinaryComparatorFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.comparators.IntegerBinaryComparatorFactory;
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
 import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProvider;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrame;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrameFactory;
@@ -53,6 +55,8 @@
 import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeFrame;
 import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.DoublePrimitiveValueProviderFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.IntegerPrimitiveValueProviderFactory;
 import edu.uci.ics.hyracks.storage.am.rtree.impls.RTree;
 import edu.uci.ics.hyracks.storage.am.rtree.impls.RTreeOpContext;
 import edu.uci.ics.hyracks.storage.am.rtree.tuples.RTreeTypeAwareTupleWriterFactory;
@@ -102,7 +106,14 @@
         typeTraits[5] = new TypeTrait(4);
         typeTraits[6] = new TypeTrait(8);
 
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+        // declare value providers
+        IPrimitiveValueProvider[] valueProviders = new IPrimitiveValueProvider[keyFieldCount];
+        valueProviders[0] = DoublePrimitiveValueProviderFactory.INSTANCE.createPrimitiveValueProvider();
+        valueProviders[1] = valueProviders[0];
+        valueProviders[2] = valueProviders[0];
+        valueProviders[3] = valueProviders[0];
+
+        MultiComparator cmp = new MultiComparator(typeTraits, cmps, valueProviders);
 
         RTreeTypeAwareTupleWriterFactory tupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(typeTraits);
 
@@ -256,7 +267,14 @@
         typeTraits[5] = new TypeTrait(4);
         typeTraits[6] = new TypeTrait(8);
 
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+        // declare value providers
+        IPrimitiveValueProvider[] valueProviders = new IPrimitiveValueProvider[keyFieldCount];
+        valueProviders[0] = DoublePrimitiveValueProviderFactory.INSTANCE.createPrimitiveValueProvider();
+        valueProviders[1] = valueProviders[0];
+        valueProviders[2] = valueProviders[0];
+        valueProviders[3] = valueProviders[0];
+
+        MultiComparator cmp = new MultiComparator(typeTraits, cmps, valueProviders);
 
         RTreeTypeAwareTupleWriterFactory tupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(typeTraits);
 
@@ -442,7 +460,16 @@
         typeTraits[7] = new TypeTrait(4);
         typeTraits[8] = new TypeTrait(8);
 
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+        // declare value providers
+        IPrimitiveValueProvider[] valueProviders = new IPrimitiveValueProvider[keyFieldCount];
+        valueProviders[0] = DoublePrimitiveValueProviderFactory.INSTANCE.createPrimitiveValueProvider();
+        valueProviders[1] = valueProviders[0];
+        valueProviders[2] = valueProviders[0];
+        valueProviders[3] = valueProviders[0];
+        valueProviders[4] = valueProviders[0];
+        valueProviders[5] = valueProviders[0];
+
+        MultiComparator cmp = new MultiComparator(typeTraits, cmps, valueProviders);
 
         RTreeTypeAwareTupleWriterFactory tupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(typeTraits);
 
@@ -567,4 +594,165 @@
         bufferCache.close();
 
     }
+
+    // create an R-tree of two dimensions
+    // fill the R-tree with random integer key values using insertions
+    // perform ordered scan
+    @Test
+    public void test04() throws Exception {
+
+        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES);
+        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
+        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
+        FileReference file = new FileReference(new File(fileName));
+        bufferCache.createFile(file);
+        int fileId = fmp.lookupFileId(file);
+        bufferCache.openFile(fileId);
+
+        // declare keys
+        int keyFieldCount = 4;
+        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+        cmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+        cmps[1] = cmps[0];
+        cmps[2] = cmps[0];
+        cmps[3] = cmps[0];
+
+        // declare tuple fields
+        int fieldCount = 7;
+        ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
+        typeTraits[0] = new TypeTrait(4);
+        typeTraits[1] = new TypeTrait(4);
+        typeTraits[2] = new TypeTrait(4);
+        typeTraits[3] = new TypeTrait(4);
+        typeTraits[4] = new TypeTrait(8);
+        typeTraits[5] = new TypeTrait(4);
+        typeTraits[6] = new TypeTrait(8);
+
+        // declare value providers
+        IPrimitiveValueProvider[] valueProviders = new IPrimitiveValueProvider[keyFieldCount];
+        valueProviders[0] = IntegerPrimitiveValueProviderFactory.INSTANCE.createPrimitiveValueProvider();
+        valueProviders[1] = valueProviders[0];
+        valueProviders[2] = valueProviders[0];
+        valueProviders[3] = valueProviders[0];
+
+        MultiComparator cmp = new MultiComparator(typeTraits, cmps, valueProviders);
+
+        RTreeTypeAwareTupleWriterFactory tupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(typeTraits);
+
+        ITreeIndexFrameFactory interiorFrameFactory = new RTreeNSMInteriorFrameFactory(tupleWriterFactory,
+                keyFieldCount);
+        ITreeIndexFrameFactory leafFrameFactory = new RTreeNSMLeafFrameFactory(tupleWriterFactory, keyFieldCount);
+        ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
+        ITreeIndexMetaDataFrame metaFrame = metaFrameFactory.createFrame();
+
+        IRTreeFrame interiorFrame = (IRTreeFrame) interiorFrameFactory.createFrame();
+        IRTreeFrame leafFrame = (IRTreeFrame) leafFrameFactory.createFrame();
+        IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, fileId, 0, metaFrameFactory);
+
+        RTree rtree = new RTree(bufferCache, freePageManager, interiorFrameFactory, leafFrameFactory, cmp);
+        rtree.create(fileId, leafFrame, metaFrame);
+        rtree.open(fileId);
+
+        ByteBuffer hyracksFrame = ctx.allocateFrame();
+        FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+        DataOutput dos = tb.getDataOutput();
+
+        @SuppressWarnings("rawtypes")
+        ISerializerDeserializer[] recDescSers = { IntegerSerializerDeserializer.INSTANCE,
+                IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE,
+                IntegerSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+                IntegerSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE };
+        RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
+        IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(), recDesc);
+        accessor.reset(hyracksFrame);
+        FrameTupleReference tuple = new FrameTupleReference();
+
+        RTreeOpContext insertOpCtx = rtree.createOpContext(IndexOp.INSERT, leafFrame, interiorFrame, metaFrame);
+
+        Random rnd = new Random();
+        rnd.setSeed(50);
+
+        Random rnd2 = new Random();
+        rnd2.setSeed(50);
+        for (int i = 0; i < 5000; i++) {
+
+            int p1x = rnd.nextInt();
+            int p1y = rnd.nextInt();
+            int p2x = rnd.nextInt();
+            int p2y = rnd.nextInt();
+
+            double pk1 = rnd2.nextDouble();
+            int pk2 = rnd2.nextInt();
+            double pk3 = rnd2.nextDouble();
+
+            tb.reset();
+            IntegerSerializerDeserializer.INSTANCE.serialize(Math.min(p1x, p2x), dos);
+            tb.addFieldEndOffset();
+            IntegerSerializerDeserializer.INSTANCE.serialize(Math.min(p1y, p2y), dos);
+            tb.addFieldEndOffset();
+            IntegerSerializerDeserializer.INSTANCE.serialize(Math.max(p1x, p2x), dos);
+            tb.addFieldEndOffset();
+            IntegerSerializerDeserializer.INSTANCE.serialize(Math.max(p1y, p2y), dos);
+            tb.addFieldEndOffset();
+            DoubleSerializerDeserializer.INSTANCE.serialize(pk1, dos);
+            tb.addFieldEndOffset();
+            IntegerSerializerDeserializer.INSTANCE.serialize(pk2, dos);
+            tb.addFieldEndOffset();
+            DoubleSerializerDeserializer.INSTANCE.serialize(pk3, dos);
+            tb.addFieldEndOffset();
+
+            appender.reset(hyracksFrame, true);
+            appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
+
+            tuple.reset(accessor, 0);
+
+            if (i % 1000 == 0) {
+                print("INSERTING " + i + " " + Math.min(p1x, p2x) + " " + Math.min(p1y, p2y) + " " + Math.max(p1x, p2x)
+                        + " " + Math.max(p1y, p2y) + "\n");
+            }
+
+            try {
+                rtree.insert(tuple, insertOpCtx);
+            } catch (TreeIndexException e) {
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        // rtree.printTree(leafFrame, interiorFrame, recDescSers);
+        // System.err.println();
+
+        String rtreeStats = rtree.printStats();
+        print(rtreeStats);
+
+        // disk-order scan
+        print("DISK-ORDER SCAN:\n");
+        TreeDiskOrderScanCursor diskOrderCursor = new TreeDiskOrderScanCursor(leafFrame);
+        RTreeOpContext diskOrderScanOpCtx = rtree.createOpContext(IndexOp.DISKORDERSCAN, leafFrame, null, null);
+        rtree.diskOrderScan(diskOrderCursor, leafFrame, metaFrame, diskOrderScanOpCtx);
+        try {
+            while (diskOrderCursor.hasNext()) {
+                diskOrderCursor.next();
+                ITupleReference frameTuple = diskOrderCursor.getTuple();
+                String rec = cmp.printTuple(frameTuple, recDescSers);
+                print(rec + "\n");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            diskOrderCursor.close();
+        }
+
+        TreeIndexStatsGatherer statsGatherer = new TreeIndexStatsGatherer(bufferCache, freePageManager, fileId,
+                rtree.getRootPageId());
+        TreeIndexStats stats = statsGatherer.gatherStats(leafFrame, interiorFrame, metaFrame);
+        String string = stats.toString();
+        System.err.println(string);
+
+        rtree.close();
+        bufferCache.closeFile(fileId);
+        bufferCache.close();
+
+    }
 }
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/SearchCursorTest.java b/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/SearchCursorTest.java
index 3060765..68db811 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/SearchCursorTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/SearchCursorTest.java
@@ -43,6 +43,7 @@
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
 import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
+import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProvider;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrame;
@@ -56,6 +57,7 @@
 import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeLeafFrame;
 import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.DoublePrimitiveValueProviderFactory;
 import edu.uci.ics.hyracks.storage.am.rtree.impls.RTree;
 import edu.uci.ics.hyracks.storage.am.rtree.impls.RTreeOpContext;
 import edu.uci.ics.hyracks.storage.am.rtree.impls.RTreeSearchCursor;
@@ -104,7 +106,14 @@
         typeTraits[3] = new TypeTrait(8);
         typeTraits[4] = new TypeTrait(4);
 
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+        // declare value providers
+        IPrimitiveValueProvider[] valueProviders = new IPrimitiveValueProvider[keyFieldCount];
+        valueProviders[0] = DoublePrimitiveValueProviderFactory.INSTANCE.createPrimitiveValueProvider();
+        valueProviders[1] = valueProviders[0];
+        valueProviders[2] = valueProviders[0];
+        valueProviders[3] = valueProviders[0];
+
+        MultiComparator cmp = new MultiComparator(typeTraits, cmps, valueProviders);
 
         RTreeTypeAwareTupleWriterFactory tupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(typeTraits);