Allowed the r-tree to have keys of type double, float, or integer.

git-svn-id: https://hyracks.googlecode.com/svn/branches/hyracks_dev_next@547 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks-dataflow-common/src/main/java/edu/uci/ics/hyracks/dataflow/common/data/marshalling/DoubleSerializerDeserializer.java b/hyracks-dataflow-common/src/main/java/edu/uci/ics/hyracks/dataflow/common/data/marshalling/DoubleSerializerDeserializer.java
index 82c80e6..7b97b2c 100644
--- a/hyracks-dataflow-common/src/main/java/edu/uci/ics/hyracks/dataflow/common/data/marshalling/DoubleSerializerDeserializer.java
+++ b/hyracks-dataflow-common/src/main/java/edu/uci/ics/hyracks/dataflow/common/data/marshalling/DoubleSerializerDeserializer.java
@@ -26,7 +26,7 @@
 
     public static final DoubleSerializerDeserializer INSTANCE = new DoubleSerializerDeserializer();
 
-    private DoubleSerializerDeserializer() {
+    protected DoubleSerializerDeserializer() {
     }
 
     @Override
diff --git a/hyracks-dataflow-common/src/main/java/edu/uci/ics/hyracks/dataflow/common/data/marshalling/FloatSerializerDeserializer.java b/hyracks-dataflow-common/src/main/java/edu/uci/ics/hyracks/dataflow/common/data/marshalling/FloatSerializerDeserializer.java
index e2d1bb2..5f17c67 100644
--- a/hyracks-dataflow-common/src/main/java/edu/uci/ics/hyracks/dataflow/common/data/marshalling/FloatSerializerDeserializer.java
+++ b/hyracks-dataflow-common/src/main/java/edu/uci/ics/hyracks/dataflow/common/data/marshalling/FloatSerializerDeserializer.java
@@ -26,7 +26,7 @@
 
     public static final FloatSerializerDeserializer INSTANCE = new FloatSerializerDeserializer();
 
-    private FloatSerializerDeserializer() {
+    protected FloatSerializerDeserializer() {
     }
 
     @Override
diff --git a/hyracks-dataflow-common/src/main/java/edu/uci/ics/hyracks/dataflow/common/data/marshalling/IntegerSerializerDeserializer.java b/hyracks-dataflow-common/src/main/java/edu/uci/ics/hyracks/dataflow/common/data/marshalling/IntegerSerializerDeserializer.java
index bf40843..c2e7583 100644
--- a/hyracks-dataflow-common/src/main/java/edu/uci/ics/hyracks/dataflow/common/data/marshalling/IntegerSerializerDeserializer.java
+++ b/hyracks-dataflow-common/src/main/java/edu/uci/ics/hyracks/dataflow/common/data/marshalling/IntegerSerializerDeserializer.java
@@ -26,7 +26,7 @@
 
     public static final IntegerSerializerDeserializer INSTANCE = new IntegerSerializerDeserializer();
 
-    private IntegerSerializerDeserializer() {
+    protected IntegerSerializerDeserializer() {
     }
 
     @Override
diff --git a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/rtree/RTreeOperatorsTest.java b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/rtree/RTreeOperatorsTest.java
index 5f6eb3a..3ff6866 100644
--- a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/rtree/RTreeOperatorsTest.java
+++ b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/rtree/RTreeOperatorsTest.java
@@ -72,360 +72,464 @@
 import edu.uci.ics.hyracks.tests.integration.AbstractIntegrationTest;
 
 public class RTreeOperatorsTest extends AbstractIntegrationTest {
-    static {
-        TestStorageManagerComponentHolder.init(8192, 20, 20);
-    }
+	static {
+		TestStorageManagerComponentHolder.init(8192, 20, 20);
+	}
 
-    private IStorageManagerInterface storageManager = new TestStorageManagerInterface();
-    private IIndexRegistryProvider<ITreeIndex> treeIndexRegistryProvider = new TestTreeIndexRegistryProvider();
-    private ITreeIndexOpHelperFactory opHelperFactory = new RTreeOpHelperFactory();
-    private ITreeIndexOpHelperFactory bTreeopHelperFactory = new BTreeOpHelperFactory();
+	private IStorageManagerInterface storageManager = new TestStorageManagerInterface();
+	private IIndexRegistryProvider<ITreeIndex> treeIndexRegistryProvider = new TestTreeIndexRegistryProvider();
+	private ITreeIndexOpHelperFactory opHelperFactory = new RTreeOpHelperFactory();
+	private ITreeIndexOpHelperFactory bTreeopHelperFactory = new BTreeOpHelperFactory();
 
-    private final static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMyy-hhmmssSS");
-    private final static String sep = System.getProperty("file.separator");
+	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];
+	// 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 RTreeTypeAwareTupleWriterFactory primaryTupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(
-            primaryTypeTraits);
-    private ITreeIndexFrameFactory primaryInteriorFrameFactory = new RTreeNSMInteriorFrameFactory(
-            primaryTupleWriterFactory, primaryKeyFieldCount);
-    private ITreeIndexFrameFactory primaryLeafFrameFactory = new RTreeNSMLeafFrameFactory(primaryTupleWriterFactory,
-            primaryKeyFieldCount);
+	private RTreeTypeAwareTupleWriterFactory primaryTupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(
+			primaryTypeTraits);
 
-    private static String primaryRTreeName = "primary" + simpleDateFormat.format(new Date());
-    private static String primaryFileName = System.getProperty("java.io.tmpdir") + sep + primaryRTreeName;
+	private RecordDescriptor primaryRecDesc = new RecordDescriptor(
+			new ISerializerDeserializer[] {
+					DoubleSerializerDeserializer.INSTANCE,
+					DoubleSerializerDeserializer.INSTANCE,
+					DoubleSerializerDeserializer.INSTANCE,
+					DoubleSerializerDeserializer.INSTANCE,
+					UTF8StringSerializerDeserializer.INSTANCE });
 
-    private IFileSplitProvider primaryRTreeSplitProvider = new ConstantFileSplitProvider(
-            new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(primaryFileName))) });
+	private ITreeIndexFrameFactory primaryInteriorFrameFactory = new RTreeNSMInteriorFrameFactory(
+			primaryTupleWriterFactory, primaryRecDesc.getFields(),
+			primaryKeyFieldCount);
+	private ITreeIndexFrameFactory primaryLeafFrameFactory = new RTreeNSMLeafFrameFactory(
+			primaryTupleWriterFactory, primaryRecDesc.getFields(),
+			primaryKeyFieldCount);
 
-    private RecordDescriptor primaryRecDesc = new RecordDescriptor(new ISerializerDeserializer[] {
-            DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
-            DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
-            UTF8StringSerializerDeserializer.INSTANCE });
+	private static String primaryRTreeName = "primary"
+			+ simpleDateFormat.format(new Date());
+	private static String primaryFileName = System
+			.getProperty("java.io.tmpdir") + sep + primaryRTreeName;
 
-    // field, type and key declarations for primary B-tree index
-    private int primaryBTreeFieldCount = 10;
-    private ITypeTrait[] primaryBTreeTypeTraits = new ITypeTrait[primaryBTreeFieldCount];
-    private int primaryBTreeKeyFieldCount = 1;
-    private IBinaryComparatorFactory[] primaryBTreeComparatorFactories = new IBinaryComparatorFactory[primaryBTreeKeyFieldCount];
-    private TypeAwareTupleWriterFactory primaryBTreeTupleWriterFactory = new TypeAwareTupleWriterFactory(
-            primaryBTreeTypeTraits);
-    private ITreeIndexFrameFactory primaryBTreeInteriorFrameFactory = new BTreeNSMInteriorFrameFactory(
-            primaryBTreeTupleWriterFactory);
-    private ITreeIndexFrameFactory primaryBTreeLeafFrameFactory = new BTreeNSMLeafFrameFactory(
-            primaryBTreeTupleWriterFactory);
+	private IFileSplitProvider primaryRTreeSplitProvider = new ConstantFileSplitProvider(
+			new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(
+					primaryFileName))) });
 
-    private static String primaryBTreeName = "primaryBTree" + simpleDateFormat.format(new Date());
-    private static String primaryBTreeFileName = System.getProperty("java.io.tmpdir") + sep + primaryBTreeName;
+	// field, type and key declarations for primary B-tree index
+	private int primaryBTreeFieldCount = 10;
+	private ITypeTrait[] primaryBTreeTypeTraits = new ITypeTrait[primaryBTreeFieldCount];
+	private int primaryBTreeKeyFieldCount = 1;
+	private IBinaryComparatorFactory[] primaryBTreeComparatorFactories = new IBinaryComparatorFactory[primaryBTreeKeyFieldCount];
+	private TypeAwareTupleWriterFactory primaryBTreeTupleWriterFactory = new TypeAwareTupleWriterFactory(
+			primaryBTreeTypeTraits);
+	private ITreeIndexFrameFactory primaryBTreeInteriorFrameFactory = new BTreeNSMInteriorFrameFactory(
+			primaryBTreeTupleWriterFactory);
+	private ITreeIndexFrameFactory primaryBTreeLeafFrameFactory = new BTreeNSMLeafFrameFactory(
+			primaryBTreeTupleWriterFactory);
 
-    private IFileSplitProvider primaryBTreeSplitProvider = new ConstantFileSplitProvider(
-            new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(primaryBTreeFileName))) });
+	private static String primaryBTreeName = "primaryBTree"
+			+ simpleDateFormat.format(new Date());
+	private static String primaryBTreeFileName = System
+			.getProperty("java.io.tmpdir") + sep + primaryBTreeName;
 
-    private RecordDescriptor primaryBTreeRecDesc = new RecordDescriptor(new ISerializerDeserializer[] {
-            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
-            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
-            UTF8StringSerializerDeserializer.INSTANCE, UTF8StringSerializerDeserializer.INSTANCE,
-            DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
-            DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE, });
+	private IFileSplitProvider primaryBTreeSplitProvider = new ConstantFileSplitProvider(
+			new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(
+					primaryBTreeFileName))) });
 
-    // field, type and key declarations for secondary indexes
-    private int secondaryFieldCount = 5;
-    private ITypeTrait[] secondaryTypeTraits = new ITypeTrait[secondaryFieldCount];
-    private int secondaryKeyFieldCount = 4;
-    private IBinaryComparatorFactory[] secondaryComparatorFactories = new IBinaryComparatorFactory[secondaryKeyFieldCount];
-    private RTreeTypeAwareTupleWriterFactory secondaryTupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(
-            secondaryTypeTraits);
-    private ITreeIndexFrameFactory secondaryInteriorFrameFactory = new RTreeNSMInteriorFrameFactory(
-            secondaryTupleWriterFactory, secondaryKeyFieldCount);
-    private ITreeIndexFrameFactory secondaryLeafFrameFactory = new RTreeNSMLeafFrameFactory(
-            secondaryTupleWriterFactory, secondaryKeyFieldCount);
+	private RecordDescriptor primaryBTreeRecDesc = new RecordDescriptor(
+			new ISerializerDeserializer[] {
+					UTF8StringSerializerDeserializer.INSTANCE,
+					UTF8StringSerializerDeserializer.INSTANCE,
+					UTF8StringSerializerDeserializer.INSTANCE,
+					UTF8StringSerializerDeserializer.INSTANCE,
+					UTF8StringSerializerDeserializer.INSTANCE,
+					UTF8StringSerializerDeserializer.INSTANCE,
+					DoubleSerializerDeserializer.INSTANCE,
+					DoubleSerializerDeserializer.INSTANCE,
+					DoubleSerializerDeserializer.INSTANCE,
+					DoubleSerializerDeserializer.INSTANCE, });
 
-    private static String secondaryRTreeName = "secondary" + simpleDateFormat.format(new Date());
-    private static String secondaryFileName = System.getProperty("java.io.tmpdir") + sep + secondaryRTreeName;
+	// field, type and key declarations for secondary indexes
+	private int secondaryFieldCount = 5;
+	private ITypeTrait[] secondaryTypeTraits = new ITypeTrait[secondaryFieldCount];
+	private int secondaryKeyFieldCount = 4;
+	private IBinaryComparatorFactory[] secondaryComparatorFactories = new IBinaryComparatorFactory[secondaryKeyFieldCount];
+	private RTreeTypeAwareTupleWriterFactory secondaryTupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(
+			secondaryTypeTraits);
 
-    private IFileSplitProvider secondaryRTreeSplitProvider = new ConstantFileSplitProvider(
-            new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(secondaryFileName))) });
+	private RecordDescriptor secondaryRecDesc = new RecordDescriptor(
+			new ISerializerDeserializer[] {
+					DoubleSerializerDeserializer.INSTANCE,
+					DoubleSerializerDeserializer.INSTANCE,
+					DoubleSerializerDeserializer.INSTANCE,
+					DoubleSerializerDeserializer.INSTANCE,
+					UTF8StringSerializerDeserializer.INSTANCE });
 
-    private RecordDescriptor secondaryRecDesc = new RecordDescriptor(new ISerializerDeserializer[] {
-            DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
-            DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
-            UTF8StringSerializerDeserializer.INSTANCE });
+	private ITreeIndexFrameFactory secondaryInteriorFrameFactory = new RTreeNSMInteriorFrameFactory(
+			secondaryTupleWriterFactory, secondaryRecDesc.getFields(),
+			secondaryKeyFieldCount);
+	private ITreeIndexFrameFactory secondaryLeafFrameFactory = new RTreeNSMLeafFrameFactory(
+			secondaryTupleWriterFactory, secondaryRecDesc.getFields(),
+			secondaryKeyFieldCount);
 
-    @Before
-    public void setup() {
-        // 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];
+	private static String secondaryRTreeName = "secondary"
+			+ simpleDateFormat.format(new Date());
+	private static String secondaryFileName = System
+			.getProperty("java.io.tmpdir") + sep + secondaryRTreeName;
 
-        // field, type and key declarations for primary B-tree index
-        primaryBTreeTypeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-        primaryBTreeTypeTraits[1] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-        primaryBTreeTypeTraits[2] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-        primaryBTreeTypeTraits[3] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-        primaryBTreeTypeTraits[4] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-        primaryBTreeTypeTraits[5] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-        primaryBTreeTypeTraits[6] = new TypeTrait(8);
-        primaryBTreeTypeTraits[7] = new TypeTrait(8);
-        primaryBTreeTypeTraits[8] = new TypeTrait(8);
-        primaryBTreeTypeTraits[9] = new TypeTrait(8);
-        primaryBTreeComparatorFactories[0] = UTF8StringBinaryComparatorFactory.INSTANCE;
+	private IFileSplitProvider secondaryRTreeSplitProvider = new ConstantFileSplitProvider(
+			new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(
+					secondaryFileName))) });
 
-        // field, type and key declarations for secondary indexes
-        secondaryTypeTraits[0] = new TypeTrait(8);
-        secondaryTypeTraits[1] = new TypeTrait(8);
-        secondaryTypeTraits[2] = new TypeTrait(8);
-        secondaryTypeTraits[3] = new TypeTrait(8);
-        secondaryTypeTraits[4] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-        secondaryComparatorFactories[0] = DoubleBinaryComparatorFactory.INSTANCE;
-        secondaryComparatorFactories[1] = secondaryComparatorFactories[0];
-        secondaryComparatorFactories[2] = secondaryComparatorFactories[0];
-        secondaryComparatorFactories[3] = secondaryComparatorFactories[0];
-    }
+	@Before
+	public void setup() {
+		// 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];
 
-    @Test
-    public void loadPrimaryBTreeIndexTest() throws Exception {
-        JobSpecification spec = new JobSpecification();
+		// field, type and key declarations for primary B-tree index
+		primaryBTreeTypeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+		primaryBTreeTypeTraits[1] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+		primaryBTreeTypeTraits[2] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+		primaryBTreeTypeTraits[3] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+		primaryBTreeTypeTraits[4] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+		primaryBTreeTypeTraits[5] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+		primaryBTreeTypeTraits[6] = new TypeTrait(8);
+		primaryBTreeTypeTraits[7] = new TypeTrait(8);
+		primaryBTreeTypeTraits[8] = new TypeTrait(8);
+		primaryBTreeTypeTraits[9] = new TypeTrait(8);
+		primaryBTreeComparatorFactories[0] = UTF8StringBinaryComparatorFactory.INSTANCE;
 
-        FileSplit[] ordersSplits = new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(
-                "data/orders-with-locations.txt"))) };
-        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, DoubleSerializerDeserializer.INSTANCE,
-                DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
-                DoubleSerializerDeserializer.INSTANCE });
+		// field, type and key declarations for secondary indexes
+		secondaryTypeTraits[0] = new TypeTrait(8);
+		secondaryTypeTraits[1] = new TypeTrait(8);
+		secondaryTypeTraits[2] = new TypeTrait(8);
+		secondaryTypeTraits[3] = new TypeTrait(8);
+		secondaryTypeTraits[4] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+		secondaryComparatorFactories[0] = DoubleBinaryComparatorFactory.INSTANCE;
+		secondaryComparatorFactories[1] = secondaryComparatorFactories[0];
+		secondaryComparatorFactories[2] = secondaryComparatorFactories[0];
+		secondaryComparatorFactories[3] = secondaryComparatorFactories[0];
+	}
 
-        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,
-                        DoubleParserFactory.INSTANCE, DoubleParserFactory.INSTANCE, DoubleParserFactory.INSTANCE,
-                        DoubleParserFactory.INSTANCE }, '|'), ordersDesc);
-        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, ordScanner, NC1_ID);
+	@Test
+	public void loadPrimaryBTreeIndexTest() throws Exception {
+		JobSpecification spec = new JobSpecification();
 
-        ExternalSortOperatorDescriptor sorter = new ExternalSortOperatorDescriptor(spec, 1000, new int[] { 0 },
-                new IBinaryComparatorFactory[] { UTF8StringBinaryComparatorFactory.INSTANCE }, ordersDesc);
-        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, sorter, NC1_ID);
+		FileSplit[] ordersSplits = new FileSplit[] { new FileSplit(NC1_ID,
+				new FileReference(new File("data/orders-with-locations.txt"))) };
+		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,
+						DoubleSerializerDeserializer.INSTANCE,
+						DoubleSerializerDeserializer.INSTANCE,
+						DoubleSerializerDeserializer.INSTANCE,
+						DoubleSerializerDeserializer.INSTANCE });
 
-        int[] fieldPermutation = { 0, 1, 2, 4, 5, 7, 9, 10, 11, 12 };
-        TreeIndexBulkLoadOperatorDescriptor primaryBTreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(spec,
-                storageManager, treeIndexRegistryProvider, primaryBTreeSplitProvider, primaryBTreeInteriorFrameFactory,
-                primaryBTreeLeafFrameFactory, primaryBTreeTypeTraits, primaryBTreeComparatorFactories,
-                fieldPermutation, 0.7f, bTreeopHelperFactory);
-        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryBTreeBulkLoad, NC1_ID);
+		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,
+								DoubleParserFactory.INSTANCE,
+								DoubleParserFactory.INSTANCE,
+								DoubleParserFactory.INSTANCE,
+								DoubleParserFactory.INSTANCE }, '|'),
+				ordersDesc);
+		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
+				ordScanner, NC1_ID);
 
-        spec.connect(new OneToOneConnectorDescriptor(spec), ordScanner, 0, sorter, 0);
+		ExternalSortOperatorDescriptor sorter = new ExternalSortOperatorDescriptor(
+				spec,
+				1000,
+				new int[] { 0 },
+				new IBinaryComparatorFactory[] { UTF8StringBinaryComparatorFactory.INSTANCE },
+				ordersDesc);
+		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, sorter,
+				NC1_ID);
 
-        spec.connect(new OneToOneConnectorDescriptor(spec), sorter, 0, primaryBTreeBulkLoad, 0);
+		int[] fieldPermutation = { 0, 1, 2, 4, 5, 7, 9, 10, 11, 12 };
+		TreeIndexBulkLoadOperatorDescriptor primaryBTreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(
+				spec, storageManager, treeIndexRegistryProvider,
+				primaryBTreeSplitProvider, primaryBTreeInteriorFrameFactory,
+				primaryBTreeLeafFrameFactory, primaryBTreeTypeTraits,
+				primaryBTreeComparatorFactories, fieldPermutation, 0.7f,
+				bTreeopHelperFactory);
+		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
+				primaryBTreeBulkLoad, NC1_ID);
 
-        spec.addRoot(primaryBTreeBulkLoad);
-        runTest(spec);
-    }
+		spec.connect(new OneToOneConnectorDescriptor(spec), ordScanner, 0,
+				sorter, 0);
 
-    @Test
-    public void loadPrimaryIndexTest() throws Exception {
-        JobSpecification spec = new JobSpecification();
+		spec.connect(new OneToOneConnectorDescriptor(spec), sorter, 0,
+				primaryBTreeBulkLoad, 0);
+
+		spec.addRoot(primaryBTreeBulkLoad);
+		runTest(spec);
+	}
+
+	@Test
+	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 });
+		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);
+		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, fieldPermutation, 0.7f,
-                opHelperFactory);
-        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryRTreeBulkLoad, NC1_ID);
+		int[] fieldPermutation = { 0, 1, 2, 3, 4 };
+		TreeIndexBulkLoadOperatorDescriptor primaryRTreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(
+				spec, storageManager, treeIndexRegistryProvider,
+				primaryRTreeSplitProvider, primaryInteriorFrameFactory,
+				primaryLeafFrameFactory, primaryTypeTraits,
+				primaryComparatorFactories, fieldPermutation, 0.7f,
+				opHelperFactory);
+		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
+				primaryRTreeBulkLoad, NC1_ID);
 
-        spec.connect(new OneToOneConnectorDescriptor(spec), objScanner, 0, primaryRTreeBulkLoad, 0);
+		spec.connect(new OneToOneConnectorDescriptor(spec), objScanner, 0,
+				primaryRTreeBulkLoad, 0);
 
-        spec.addRoot(primaryRTreeBulkLoad);
-        runTest(spec);
-    }
+		spec.addRoot(primaryRTreeBulkLoad);
+		runTest(spec);
+	}
 
-    @Test
-    public void loadSecondaryIndexTest() throws Exception {
-        JobSpecification spec = new JobSpecification();
+	@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();
+		// build dummy tuple containing nothing
+		ArrayTupleBuilder tb = new ArrayTupleBuilder(primaryKeyFieldCount * 2);
+		DataOutput dos = tb.getDataOutput();
 
-        tb.reset();
-        UTF8StringSerializerDeserializer.INSTANCE.serialize("0", dos);
-        tb.addFieldEndOffset();
+		tb.reset();
+		UTF8StringSerializerDeserializer.INSTANCE.serialize("0", dos);
+		tb.addFieldEndOffset();
 
-        ISerializerDeserializer[] keyRecDescSers = { UTF8StringSerializerDeserializer.INSTANCE,
-                UTF8StringSerializerDeserializer.INSTANCE };
-        RecordDescriptor keyRecDesc = new RecordDescriptor(keyRecDescSers);
+		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);
+		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
+		int[] lowKeyFields = null; // - infinity
+		int[] highKeyFields = null; // + infinity
 
-        // scan primary index
-        BTreeSearchOperatorDescriptor primaryBTreeSearchOp = new BTreeSearchOperatorDescriptor(spec,
-                primaryBTreeRecDesc, storageManager, treeIndexRegistryProvider, primaryBTreeSplitProvider,
-                primaryBTreeInteriorFrameFactory, primaryBTreeLeafFrameFactory, primaryBTreeTypeTraits,
-                primaryBTreeComparatorFactories, true, lowKeyFields, highKeyFields, true, true, opHelperFactory);
-        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, primaryBTreeSearchOp, NC1_ID);
+		// scan primary index
+		BTreeSearchOperatorDescriptor primaryBTreeSearchOp = new BTreeSearchOperatorDescriptor(
+				spec, primaryBTreeRecDesc, storageManager,
+				treeIndexRegistryProvider, primaryBTreeSplitProvider,
+				primaryBTreeInteriorFrameFactory, primaryBTreeLeafFrameFactory,
+				primaryBTreeTypeTraits, primaryBTreeComparatorFactories, true,
+				lowKeyFields, highKeyFields, true, true, opHelperFactory);
+		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
+				primaryBTreeSearchOp, NC1_ID);
 
-        // load secondary index
-        int[] fieldPermutation = { 6, 7, 8, 9, 0 };
-        TreeIndexBulkLoadOperatorDescriptor secondaryRTreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(spec,
-                storageManager, treeIndexRegistryProvider, secondaryRTreeSplitProvider, secondaryInteriorFrameFactory,
-                secondaryLeafFrameFactory, secondaryTypeTraits, secondaryComparatorFactories, fieldPermutation, 0.7f,
-                opHelperFactory);
-        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, secondaryRTreeBulkLoad, NC1_ID);
+		// load secondary index
+		int[] fieldPermutation = { 6, 7, 8, 9, 0 };
+		TreeIndexBulkLoadOperatorDescriptor secondaryRTreeBulkLoad = new TreeIndexBulkLoadOperatorDescriptor(
+				spec, storageManager, treeIndexRegistryProvider,
+				secondaryRTreeSplitProvider, secondaryInteriorFrameFactory,
+				secondaryLeafFrameFactory, secondaryTypeTraits,
+				secondaryComparatorFactories, fieldPermutation, 0.7f,
+				opHelperFactory);
+		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
+				secondaryRTreeBulkLoad, NC1_ID);
 
-        spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0, primaryBTreeSearchOp, 0);
-        spec.connect(new OneToOneConnectorDescriptor(spec), primaryBTreeSearchOp, 0, secondaryRTreeBulkLoad, 0);
+		spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0,
+				primaryBTreeSearchOp, 0);
+		spec.connect(new OneToOneConnectorDescriptor(spec),
+				primaryBTreeSearchOp, 0, secondaryRTreeBulkLoad, 0);
 
-        spec.addRoot(secondaryRTreeBulkLoad);
-        runTest(spec);
-    }
+		spec.addRoot(secondaryRTreeBulkLoad);
+		runTest(spec);
+	}
 
-    @Test
-    public void showPrimaryIndexStats() throws Exception {
-        JobSpecification spec = new JobSpecification();
+	@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);
+		TreeIndexStatsOperatorDescriptor primaryStatsOp = new TreeIndexStatsOperatorDescriptor(
+				spec, storageManager, treeIndexRegistryProvider,
+				primaryRTreeSplitProvider, primaryInteriorFrameFactory,
+				primaryLeafFrameFactory, primaryTypeTraits,
+				primaryComparatorFactories, opHelperFactory);
+		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
+				primaryStatsOp, NC1_ID);
 
-        spec.addRoot(primaryStatsOp);
-        runTest(spec);
-    }
+		spec.addRoot(primaryStatsOp);
+		runTest(spec);
+	}
 
-    @Test
-    public void searchPrimaryIndexTest() throws Exception {
-        JobSpecification spec = new JobSpecification();
+	@Test
+	public void searchPrimaryIndexTest() throws Exception {
+		JobSpecification spec = new JobSpecification();
 
-        // build tuple
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(primaryKeyFieldCount);
-        DataOutput dos = tb.getDataOutput();
+		// 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();
+		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);
+		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);
+		ConstantTupleSourceOperatorDescriptor keyProviderOp = new ConstantTupleSourceOperatorDescriptor(
+				spec, keyRecDesc, tb.getFieldEndOffsets(), tb.getByteArray(),
+				tb.getSize());
+		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
+				keyProviderOp, NC1_ID);
 
-        int[] keyFields = { 0, 1, 2, 3 };
+		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);
+		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);
+		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.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0,
+				primaryRTreeSearchOp, 0);
+		spec.connect(new OneToOneConnectorDescriptor(spec),
+				primaryRTreeSearchOp, 0, printer, 0);
 
-        spec.addRoot(printer);
-        runTest(spec);
-    }
+		spec.addRoot(printer);
+		runTest(spec);
+	}
 
-    @Test
-    public void searchSecondaryIndexTest() throws Exception {
-        JobSpecification spec = new JobSpecification();
+	@Test
+	public void searchSecondaryIndexTest() throws Exception {
+		JobSpecification spec = new JobSpecification();
 
-        // build tuple
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(secondaryKeyFieldCount);
-        DataOutput dos = tb.getDataOutput();
+		// build tuple
+		ArrayTupleBuilder tb = new ArrayTupleBuilder(secondaryKeyFieldCount);
+		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();
+		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);
+		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);
+		ConstantTupleSourceOperatorDescriptor keyProviderOp = new ConstantTupleSourceOperatorDescriptor(
+				spec, keyRecDesc, tb.getFieldEndOffsets(), tb.getByteArray(),
+				tb.getSize());
+		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
+				keyProviderOp, NC1_ID);
 
-        int[] keyFields = { 0, 1, 2, 3 };
+		int[] keyFields = { 0, 1, 2, 3 };
 
-        RTreeSearchOperatorDescriptor secondaryRTreeSearchOp = new RTreeSearchOperatorDescriptor(spec,
-                secondaryRecDesc, storageManager, treeIndexRegistryProvider, secondaryRTreeSplitProvider,
-                secondaryInteriorFrameFactory, secondaryLeafFrameFactory, secondaryTypeTraits,
-                secondaryComparatorFactories, keyFields, opHelperFactory);
-        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, secondaryRTreeSearchOp, NC1_ID);
+		RTreeSearchOperatorDescriptor secondaryRTreeSearchOp = new RTreeSearchOperatorDescriptor(
+				spec, secondaryRecDesc, storageManager,
+				treeIndexRegistryProvider, secondaryRTreeSplitProvider,
+				secondaryInteriorFrameFactory, secondaryLeafFrameFactory,
+				secondaryTypeTraits, secondaryComparatorFactories, keyFields,
+				opHelperFactory);
+		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec,
+				secondaryRTreeSearchOp, NC1_ID);
 
-        PrinterOperatorDescriptor printer = new PrinterOperatorDescriptor(spec);
-        PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, printer, NC1_ID);
+		PrinterOperatorDescriptor printer = new PrinterOperatorDescriptor(spec);
+		PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, printer,
+				NC1_ID);
 
-        spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0, secondaryRTreeSearchOp, 0);
-        spec.connect(new OneToOneConnectorDescriptor(spec), secondaryRTreeSearchOp, 0, printer, 0);
+		spec.connect(new OneToOneConnectorDescriptor(spec), keyProviderOp, 0,
+				secondaryRTreeSearchOp, 0);
+		spec.connect(new OneToOneConnectorDescriptor(spec),
+				secondaryRTreeSearchOp, 0, printer, 0);
 
-        spec.addRoot(printer);
-        runTest(spec);
-    }
+		spec.addRoot(printer);
+		runTest(spec);
+	}
 
-    @AfterClass
-    public static void cleanup() throws Exception {
-        File primary = new File(primaryFileName);
-        primary.deleteOnExit();
+	@AfterClass
+	public static void cleanup() throws Exception {
+		File primary = new File(primaryFileName);
+		primary.deleteOnExit();
 
-        File primaryBTree = new File(primaryBTreeFileName);
-        primaryBTree.deleteOnExit();
+		File primaryBTree = new File(primaryBTreeFileName);
+		primaryBTree.deleteOnExit();
 
-        File secondary = new File(secondaryFileName);
-        secondary.deleteOnExit();
-    }
+		File secondary = new File(secondaryFileName);
+		secondary.deleteOnExit();
+	}
 }
\ No newline at end of file
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/api/IGenericPrimitiveSerializerDeserializer.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/api/IGenericPrimitiveSerializerDeserializer.java
new file mode 100644
index 0000000..fc3ae7c
--- /dev/null
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/api/IGenericPrimitiveSerializerDeserializer.java
@@ -0,0 +1,23 @@
+/*
+ * 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.api;
+
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+
+public interface IGenericPrimitiveSerializerDeserializer<T> extends
+		ISerializerDeserializer<T> {
+	public double getValue(byte[] bytes, int offset);
+}
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMFrame.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMFrame.java
index 17c10e5..63870df 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMFrame.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMFrame.java
@@ -17,190 +17,229 @@
 
 import java.util.ArrayList;
 
-import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
 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.FloatSerializerDeserializer;
 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.ITreeIndexTupleReference;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleWriter;
 import edu.uci.ics.hyracks.storage.am.common.frames.TreeIndexNSMFrame;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
+import edu.uci.ics.hyracks.storage.am.rtree.api.IGenericPrimitiveSerializerDeserializer;
 import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeFrame;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.DoubleGenericPrimitiveSerializerDeserializer;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.FloatGenericPrimitiveSerializerDeserializer;
+import edu.uci.ics.hyracks.storage.am.rtree.impls.IntegerGenericPrimitiveSerializerDeserializer;
 import edu.uci.ics.hyracks.storage.am.rtree.impls.RTreeSplitKey;
 import edu.uci.ics.hyracks.storage.am.rtree.impls.Rectangle;
 import edu.uci.ics.hyracks.storage.am.rtree.impls.TupleEntryArrayList;
 import edu.uci.ics.hyracks.storage.am.rtree.impls.UnorderedSlotManager;
 import edu.uci.ics.hyracks.storage.am.rtree.tuples.RTreeTypeAwareTupleWriter;
 
-public abstract class RTreeNSMFrame extends TreeIndexNSMFrame implements IRTreeFrame {
-    protected static final int pageNsnOff = smFlagOff + 1;
-    protected static final int rightPageOff = pageNsnOff + 4;
+public abstract class RTreeNSMFrame extends TreeIndexNSMFrame implements
+		IRTreeFrame {
+	protected static final int pageNsnOff = smFlagOff + 1;
+	protected static final int rightPageOff = pageNsnOff + 4;
 
-    protected ITreeIndexTupleReference[] tuples;
-    protected ITreeIndexTupleReference cmpFrameTuple;
-    protected TupleEntryArrayList tupleEntries1; // used for split and checking
-                                                 // enlargement
-    protected TupleEntryArrayList tupleEntries2; // used for split
+	protected ITreeIndexTupleReference[] tuples;
+	protected ITreeIndexTupleReference cmpFrameTuple;
+	protected TupleEntryArrayList tupleEntries1; // used for split and checking
+													// enlargement
+	protected TupleEntryArrayList tupleEntries2; // used for split
 
-    protected Rectangle[] rec;
+	protected Rectangle[] rec;
+	protected IGenericPrimitiveSerializerDeserializer[] recDescSers;
 
-    protected static final double splitFactor = 0.4;
-    protected static final int nearMinimumOverlapFactor = 32;
-    private static final double doubleEpsilon = computeDoubleEpsilon();
-    private static final int numTuplesEntries = 100;
+	protected static final double splitFactor = 0.4;
+	protected static final int nearMinimumOverlapFactor = 32;
+	private static final double doubleEpsilon = computeDoubleEpsilon();
+	private static final int numTuplesEntries = 100;
 
-    public RTreeNSMFrame(ITreeIndexTupleWriter tupleWriter, int keyFieldCount) {
-        super(tupleWriter, new UnorderedSlotManager());
-        this.tuples = new ITreeIndexTupleReference[keyFieldCount];
-        for (int i = 0; i < keyFieldCount; i++) {
-            this.tuples[i] = tupleWriter.createTupleReference();
-        }
-        cmpFrameTuple = tupleWriter.createTupleReference();
+	public RTreeNSMFrame(ITreeIndexTupleWriter tupleWriter,
+			ISerializerDeserializer[] recDescSers, int keyFieldCount) {
+		super(tupleWriter, new UnorderedSlotManager());
+		this.tuples = new ITreeIndexTupleReference[keyFieldCount];
+		this.recDescSers = new IGenericPrimitiveSerializerDeserializer[keyFieldCount];
+		for (int i = 0; i < keyFieldCount; i++) {
+			this.tuples[i] = tupleWriter.createTupleReference();
 
-        tupleEntries1 = new TupleEntryArrayList(numTuplesEntries, numTuplesEntries);
-        tupleEntries2 = new TupleEntryArrayList(numTuplesEntries, numTuplesEntries);
-        rec = new Rectangle[4];
-        for (int i = 0; i < 4; i++) {
-            rec[i] = new Rectangle(keyFieldCount / 2);
-        }
-    }
+			if (recDescSers[i].getClass().equals(
+					IntegerSerializerDeserializer.INSTANCE.getClass())) {
+				this.recDescSers[i] = IntegerGenericPrimitiveSerializerDeserializer.INSTANCE;
+			} else if (recDescSers[i].getClass().equals(
+					FloatSerializerDeserializer.INSTANCE.getClass())) {
+				this.recDescSers[i] = FloatGenericPrimitiveSerializerDeserializer.INSTANCE;
+			} else if (recDescSers[i].getClass().equals(
+					DoubleSerializerDeserializer.INSTANCE.getClass())) {
+				this.recDescSers[i] = DoubleGenericPrimitiveSerializerDeserializer.INSTANCE;
+			} else {
+				throw new RuntimeException(
+						"Key type not supported. The supported key types are int, float, and double ");
 
-    private static double computeDoubleEpsilon() {
-        double doubleEpsilon = 1.0;
+			}
+		}
+		cmpFrameTuple = tupleWriter.createTupleReference();
 
-        do {
-            doubleEpsilon /= 2.0;
-        } while (1.0 + (doubleEpsilon / 2.0) != 1.0);
-        return doubleEpsilon;
-    }
+		tupleEntries1 = new TupleEntryArrayList(numTuplesEntries,
+				numTuplesEntries);
+		tupleEntries2 = new TupleEntryArrayList(numTuplesEntries,
+				numTuplesEntries);
+		rec = new Rectangle[4];
+		for (int i = 0; i < 4; i++) {
+			rec[i] = new Rectangle(keyFieldCount / 2, this.recDescSers);
+		}
+	}
 
-    public static double doubleEpsilon() {
-        return doubleEpsilon;
-    }
+	private static double computeDoubleEpsilon() {
+		double doubleEpsilon = 1.0;
 
-    @Override
-    public void initBuffer(byte level) {
-        super.initBuffer(level);
-        buf.putInt(pageNsnOff, 0);
-        buf.putInt(rightPageOff, -1);
-    }
+		do {
+			doubleEpsilon /= 2.0;
+		} while (1.0 + (doubleEpsilon / 2.0) != 1.0);
+		return doubleEpsilon;
+	}
 
-    public void setTupleCount(int tupleCount) {
-        buf.putInt(tupleCountOff, tupleCount);
-    }
+	public static double doubleEpsilon() {
+		return doubleEpsilon;
+	}
 
-    @Override
-    public void setPageNsn(int pageNsn) {
-        buf.putInt(pageNsnOff, pageNsn);
-    }
+	@Override
+	public void initBuffer(byte level) {
+		super.initBuffer(level);
+		buf.putInt(pageNsnOff, 0);
+		buf.putInt(rightPageOff, -1);
+	}
 
-    @Override
-    public int getPageNsn() {
-        return buf.getInt(pageNsnOff);
-    }
+	public void setTupleCount(int tupleCount) {
+		buf.putInt(tupleCountOff, tupleCount);
+	}
 
-    @Override
-    protected void resetSpaceParams() {
-        buf.putInt(freeSpaceOff, rightPageOff + 4);
-        buf.putInt(totalFreeSpaceOff, buf.capacity() - (rightPageOff + 4));
-    }
+	@Override
+	public void setPageNsn(int pageNsn) {
+		buf.putInt(pageNsnOff, pageNsn);
+	}
 
-    @Override
-    public int getRightPage() {
-        return buf.getInt(rightPageOff);
-    }
+	@Override
+	public int getPageNsn() {
+		return buf.getInt(pageNsnOff);
+	}
 
-    @Override
-    public void setRightPage(int rightPage) {
-        buf.putInt(rightPageOff, rightPage);
-    }
+	@Override
+	protected void resetSpaceParams() {
+		buf.putInt(freeSpaceOff, rightPageOff + 4);
+		buf.putInt(totalFreeSpaceOff, buf.capacity() - (rightPageOff + 4));
+	}
 
-    protected ITreeIndexTupleReference[] getTuples() {
-        return tuples;
-    }
+	@Override
+	public int getRightPage() {
+		return buf.getInt(rightPageOff);
+	}
 
-    // for debugging
-    public ArrayList<Integer> getChildren(MultiComparator cmp) {
-        ArrayList<Integer> ret = new ArrayList<Integer>();
-        frameTuple.setFieldCount(cmp.getKeyFieldCount());
-        int tupleCount = buf.getInt(tupleCountOff);
-        for (int i = 0; i < tupleCount; i++) {
-            int tupleOff = slotManager.getTupleOff(slotManager.getSlotOff(i));
-            frameTuple.resetByTupleOffset(buf, tupleOff);
+	@Override
+	public void setRightPage(int rightPage) {
+		buf.putInt(rightPageOff, rightPage);
+	}
 
-            int intVal = IntegerSerializerDeserializer.getInt(
-                    buf.array(),
-                    frameTuple.getFieldStart(frameTuple.getFieldCount() - 1)
-                            + frameTuple.getFieldLength(frameTuple.getFieldCount() - 1));
-            ret.add(intVal);
-        }
-        return ret;
-    }
+	protected ITreeIndexTupleReference[] getTuples() {
+		return tuples;
+	}
 
-    public void generateDist(ITupleReference tuple, TupleEntryArrayList entries, Rectangle rec, int start, int end) {
-        int j = 0;
-        while (entries.get(j).getTupleIndex() == -1) {
-            j++;
-        }
-        frameTuple.resetByTupleIndex(this, entries.get(j).getTupleIndex());
-        rec.set(frameTuple);
-        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);
-                } else {
-                    rec.enlarge(tuple);
-                }
-            }
-        }
-    }
+	// for debugging
+	public ArrayList<Integer> getChildren(MultiComparator cmp) {
+		ArrayList<Integer> ret = new ArrayList<Integer>();
+		frameTuple.setFieldCount(cmp.getKeyFieldCount());
+		int tupleCount = buf.getInt(tupleCountOff);
+		for (int i = 0; i < tupleCount; i++) {
+			int tupleOff = slotManager.getTupleOff(slotManager.getSlotOff(i));
+			frameTuple.resetByTupleOffset(buf, tupleOff);
 
-    @Override
-    public ITreeIndexTupleReference createTupleReference() {
-        return tupleWriter.createTupleReference();
-    }
+			int intVal = IntegerSerializerDeserializer.getInt(
+					buf.array(),
+					frameTuple.getFieldStart(frameTuple.getFieldCount() - 1)
+							+ frameTuple.getFieldLength(frameTuple
+									.getFieldCount() - 1));
+			ret.add(intVal);
+		}
+		return ret;
+	}
 
-    public void adjustMBRImpl(ITreeIndexTupleReference[] tuples, MultiComparator cmp) {
-        int maxFieldPos = cmp.getKeyFieldCount() / 2;
-        for (int i = 1; i < getTupleCount(); i++) {
-            frameTuple.resetByTupleIndex(this, i);
-            for (int j = 0; j < maxFieldPos; j++) {
-                int k = maxFieldPos + j;
-                int c = cmp.getComparators()[j].compare(frameTuple.getFieldData(j), frameTuple.getFieldStart(j),
-                        frameTuple.getFieldLength(j), tuples[j].getFieldData(j), tuples[j].getFieldStart(j),
-                        tuples[j].getFieldLength(j));
-                if (c < 0) {
-                    tuples[j].resetByTupleIndex(this, i);
-                }
-                c = cmp.getComparators()[k].compare(frameTuple.getFieldData(k), frameTuple.getFieldStart(k),
-                        frameTuple.getFieldLength(k), tuples[k].getFieldData(k), tuples[k].getFieldStart(k),
-                        tuples[k].getFieldLength(k));
-                if (c > 0) {
-                    tuples[k].resetByTupleIndex(this, i);
-                }
-            }
-        }
-    }
+	public void generateDist(ITupleReference tuple,
+			TupleEntryArrayList entries, Rectangle rec, int start, int end) {
+		int j = 0;
+		while (entries.get(j).getTupleIndex() == -1) {
+			j++;
+		}
+		frameTuple.resetByTupleIndex(this, entries.get(j).getTupleIndex());
+		rec.set(frameTuple);
+		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);
+				} else {
+					rec.enlarge(tuple);
+				}
+			}
+		}
+	}
 
-    @Override
-    public void computeMBR(ISplitKey splitKey, MultiComparator cmp) {
-        RTreeSplitKey rTreeSplitKey = ((RTreeSplitKey) splitKey);
-        RTreeTypeAwareTupleWriter rTreeTupleWriterLeftFrame = ((RTreeTypeAwareTupleWriter) tupleWriter);
-        frameTuple.setFieldCount(cmp.getFieldCount());
+	@Override
+	public ITreeIndexTupleReference createTupleReference() {
+		return tupleWriter.createTupleReference();
+	}
 
-        int tupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff());
-        frameTuple.resetByTupleOffset(buf, tupleOff);
-        int splitKeySize = tupleWriter.bytesRequired(frameTuple, 0, cmp.getKeyFieldCount());
+	public void adjustMBRImpl(ITreeIndexTupleReference[] tuples,
+			MultiComparator cmp) {
+		int maxFieldPos = cmp.getKeyFieldCount() / 2;
+		for (int i = 1; i < getTupleCount(); i++) {
+			frameTuple.resetByTupleIndex(this, i);
+			for (int j = 0; j < maxFieldPos; j++) {
+				int k = maxFieldPos + j;
+				int c = cmp.getComparators()[j].compare(
+						frameTuple.getFieldData(j),
+						frameTuple.getFieldStart(j),
+						frameTuple.getFieldLength(j),
+						tuples[j].getFieldData(j), tuples[j].getFieldStart(j),
+						tuples[j].getFieldLength(j));
+				if (c < 0) {
+					tuples[j].resetByTupleIndex(this, i);
+				}
+				c = cmp.getComparators()[k].compare(frameTuple.getFieldData(k),
+						frameTuple.getFieldStart(k),
+						frameTuple.getFieldLength(k),
+						tuples[k].getFieldData(k), tuples[k].getFieldStart(k),
+						tuples[k].getFieldLength(k));
+				if (c > 0) {
+					tuples[k].resetByTupleIndex(this, i);
+				}
+			}
+		}
+	}
 
-        splitKey.initData(splitKeySize);
-        this.adjustMBR(tuples, cmp);
-        rTreeTupleWriterLeftFrame.writeTupleFields(tuples, 0, rTreeSplitKey.getLeftPageBuffer(), 0);
-        rTreeSplitKey.getLeftTuple().resetByTupleOffset(rTreeSplitKey.getLeftPageBuffer(), 0);
-    }
+	@Override
+	public void computeMBR(ISplitKey splitKey, MultiComparator cmp) {
+		RTreeSplitKey rTreeSplitKey = ((RTreeSplitKey) splitKey);
+		RTreeTypeAwareTupleWriter rTreeTupleWriterLeftFrame = ((RTreeTypeAwareTupleWriter) tupleWriter);
+		frameTuple.setFieldCount(cmp.getFieldCount());
 
-    @Override
-    public int getPageHeaderSize() {
-        return rightPageOff;
-    }
-}
+		int tupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff());
+		frameTuple.resetByTupleOffset(buf, tupleOff);
+		int splitKeySize = tupleWriter.bytesRequired(frameTuple, 0,
+				cmp.getKeyFieldCount());
+
+		splitKey.initData(splitKeySize);
+		this.adjustMBR(tuples, cmp);
+		rTreeTupleWriterLeftFrame.writeTupleFields(tuples, 0,
+				rTreeSplitKey.getLeftPageBuffer(), 0);
+		rTreeSplitKey.getLeftTuple().resetByTupleOffset(
+				rTreeSplitKey.getLeftPageBuffer(), 0);
+	}
+
+	@Override
+	public int getPageHeaderSize() {
+		return rightPageOff;
+	}
+}
\ No newline at end of file
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrame.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrame.java
index d03c5e9..d7ddf66 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrame.java
+++ b/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;
@@ -41,605 +40,686 @@
 import edu.uci.ics.hyracks.storage.am.rtree.impls.UnorderedSlotManager;
 import edu.uci.ics.hyracks.storage.am.rtree.tuples.RTreeTypeAwareTupleWriter;
 
-public class RTreeNSMInteriorFrame extends RTreeNSMFrame implements IRTreeInteriorFrame {
+public class RTreeNSMInteriorFrame extends RTreeNSMFrame implements
+		IRTreeInteriorFrame {
 
-    private static final int childPtrSize = 4;
+	private static final int childPtrSize = 4;
 
-    public RTreeNSMInteriorFrame(ITreeIndexTupleWriter tupleWriter, int keyFieldCount) {
-        super(tupleWriter, keyFieldCount);
-    }
+	public RTreeNSMInteriorFrame(ITreeIndexTupleWriter tupleWriter,
+			ISerializerDeserializer[] recDescSers, int keyFieldCount) {
+		super(tupleWriter, recDescSers, keyFieldCount);
+	}
 
-    @Override
-    public String printKeys(MultiComparator cmp, ISerializerDeserializer[] fields) throws HyracksDataException {
-        StringBuilder strBuilder = new StringBuilder();
-        int tupleCount = buf.getInt(tupleCountOff);
-        frameTuple.setFieldCount(cmp.getKeyFieldCount());
-        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));
-                DataInput dataIn = new DataInputStream(inStream);
-                Object o = fields[j].deserialize(dataIn);
-                strBuilder.append(o.toString() + " ");
-            }
-            strBuilder.append(" | ");
-        }
-        strBuilder.append("\n");
-        return strBuilder.toString();
-    }
+	@Override
+	public String printKeys(MultiComparator cmp,
+			ISerializerDeserializer[] fields) throws HyracksDataException {
+		StringBuilder strBuilder = new StringBuilder();
+		int tupleCount = buf.getInt(tupleCountOff);
+		frameTuple.setFieldCount(cmp.getKeyFieldCount());
+		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));
+				DataInput dataIn = new DataInputStream(inStream);
+				Object o = fields[j].deserialize(dataIn);
+				strBuilder.append(o.toString() + " ");
+			}
+			strBuilder.append(" | ");
+		}
+		strBuilder.append("\n");
+		return strBuilder.toString();
+	}
 
-    @Override
-    public boolean findBestChild(ITupleReference tuple, MultiComparator cmp) {
-        cmpFrameTuple.setFieldCount(cmp.getKeyFieldCount());
-        frameTuple.setFieldCount(cmp.getKeyFieldCount());
+	@Override
+	public boolean findBestChild(ITupleReference tuple, MultiComparator cmp) {
+		cmpFrameTuple.setFieldCount(cmp.getKeyFieldCount());
+		frameTuple.setFieldCount(cmp.getKeyFieldCount());
 
-        int bestChild = 0;
-        double minEnlargedArea = Double.MAX_VALUE;
+		int bestChild = 0;
+		double minEnlargedArea = Double.MAX_VALUE;
 
-        // the children pointers in the node point to leaves
-        if (getLevel() == 1) {
-            // find least overlap enlargement, use minimum enlarged area to
-            // break tie, if tie still exists use minimum area to break it
-            for (int i = 0; i < getTupleCount(); ++i) {
-                frameTuple.resetByTupleIndex(this, i);
-                double enlargedArea = enlargedArea(frameTuple, tuple, cmp);
-                tupleEntries1.add(i, enlargedArea);
-                if (enlargedArea < minEnlargedArea) {
-                    minEnlargedArea = enlargedArea;
-                    bestChild = i;
-                }
-            }
-            if (minEnlargedArea < RTreeNSMFrame.doubleEpsilon() || minEnlargedArea > RTreeNSMFrame.doubleEpsilon()) {
-                minEnlargedArea = Double.MAX_VALUE;
-                int k;
-                if (getTupleCount() > nearMinimumOverlapFactor) {
-                    // sort the entries based on their area enlargement needed
-                    // to include the object
-                    tupleEntries1.sort(EntriesOrder.ASCENDING, getTupleCount());
-                    k = nearMinimumOverlapFactor;
-                } else {
-                    k = getTupleCount();
-                }
+		// the children pointers in the node point to leaves
+		if (getLevel() == 1) {
+			// find least overlap enlargement, use minimum enlarged area to
+			// break tie, if tie still exists use minimum area to break it
+			for (int i = 0; i < getTupleCount(); ++i) {
+				frameTuple.resetByTupleIndex(this, i);
+				double enlargedArea = enlargedArea(frameTuple, tuple, cmp);
+				tupleEntries1.add(i, enlargedArea);
+				if (enlargedArea < minEnlargedArea) {
+					minEnlargedArea = enlargedArea;
+					bestChild = i;
+				}
+			}
+			if (minEnlargedArea < RTreeNSMFrame.doubleEpsilon()
+					|| minEnlargedArea > RTreeNSMFrame.doubleEpsilon()) {
+				minEnlargedArea = Double.MAX_VALUE;
+				int k;
+				if (getTupleCount() > nearMinimumOverlapFactor) {
+					// sort the entries based on their area enlargement needed
+					// to include the object
+					tupleEntries1.sort(EntriesOrder.ASCENDING, getTupleCount());
+					k = nearMinimumOverlapFactor;
+				} else {
+					k = getTupleCount();
+				}
 
-                double minOverlap = Double.MAX_VALUE;
-                int id = 0;
-                for (int i = 0; i < k; ++i) {
-                    double difference = 0.0;
-                    for (int j = 0; j < getTupleCount(); ++j) {
-                        frameTuple.resetByTupleIndex(this, j);
-                        cmpFrameTuple.resetByTupleIndex(this, tupleEntries1.get(i).getTupleIndex());
+				double minOverlap = Double.MAX_VALUE;
+				int id = 0;
+				for (int i = 0; i < k; ++i) {
+					double difference = 0.0;
+					for (int j = 0; j < getTupleCount(); ++j) {
+						frameTuple.resetByTupleIndex(this, j);
+						cmpFrameTuple.resetByTupleIndex(this, tupleEntries1
+								.get(i).getTupleIndex());
 
-                        int c = pointerCmp(frameTuple, cmpFrameTuple, cmp);
-                        if (c != 0) {
-                            double intersection = overlappedArea(frameTuple, tuple, cmpFrameTuple, cmp);
-                            if (intersection != 0.0) {
-                                difference += intersection - overlappedArea(frameTuple, null, cmpFrameTuple, cmp);
-                            }
-                        } else {
-                            id = j;
-                        }
-                    }
+						int c = pointerCmp(frameTuple, cmpFrameTuple, cmp);
+						if (c != 0) {
+							double intersection = overlappedArea(frameTuple,
+									tuple, cmpFrameTuple, cmp);
+							if (intersection != 0.0) {
+								difference += intersection
+										- overlappedArea(frameTuple, null,
+												cmpFrameTuple, cmp);
+							}
+						} else {
+							id = j;
+						}
+					}
 
-                    double enlargedArea = enlargedArea(cmpFrameTuple, tuple, cmp);
-                    if (difference < minOverlap) {
-                        minOverlap = difference;
-                        minEnlargedArea = enlargedArea;
-                        bestChild = id;
-                    } else if (difference == minOverlap) {
-                        if (enlargedArea < minEnlargedArea) {
-                            minEnlargedArea = enlargedArea;
-                            bestChild = id;
-                        } else if (enlargedArea == minEnlargedArea) {
-                            double area = area(cmpFrameTuple, cmp);
-                            frameTuple.resetByTupleIndex(this, bestChild);
-                            double minArea = area(frameTuple, cmp);
-                            if (area < minArea) {
-                                bestChild = id;
-                            }
-                        }
-                    }
-                }
-            }
-        } else { // find minimum enlarged area, use minimum area to break tie
-            for (int i = 0; i < getTupleCount(); i++) {
-                frameTuple.resetByTupleIndex(this, i);
-                double enlargedArea = enlargedArea(frameTuple, tuple, cmp);
-                if (enlargedArea < minEnlargedArea) {
-                    minEnlargedArea = enlargedArea;
-                    bestChild = i;
-                } else if (enlargedArea == minEnlargedArea) {
-                    double area = area(frameTuple, cmp);
-                    frameTuple.resetByTupleIndex(this, bestChild);
-                    double minArea = area(frameTuple, cmp);
-                    if (area < minArea) {
-                        bestChild = i;
-                    }
-                }
-            }
-        }
-        tupleEntries1.clear();
+					double enlargedArea = enlargedArea(cmpFrameTuple, tuple,
+							cmp);
+					if (difference < minOverlap) {
+						minOverlap = difference;
+						minEnlargedArea = enlargedArea;
+						bestChild = id;
+					} else if (difference == minOverlap) {
+						if (enlargedArea < minEnlargedArea) {
+							minEnlargedArea = enlargedArea;
+							bestChild = id;
+						} else if (enlargedArea == minEnlargedArea) {
+							double area = area(cmpFrameTuple, cmp);
+							frameTuple.resetByTupleIndex(this, bestChild);
+							double minArea = area(frameTuple, cmp);
+							if (area < minArea) {
+								bestChild = id;
+							}
+						}
+					}
+				}
+			}
+		} else { // find minimum enlarged area, use minimum area to break tie
+			for (int i = 0; i < getTupleCount(); i++) {
+				frameTuple.resetByTupleIndex(this, i);
+				double enlargedArea = enlargedArea(frameTuple, tuple, cmp);
+				if (enlargedArea < minEnlargedArea) {
+					minEnlargedArea = enlargedArea;
+					bestChild = i;
+				} else if (enlargedArea == minEnlargedArea) {
+					double area = area(frameTuple, cmp);
+					frameTuple.resetByTupleIndex(this, bestChild);
+					double minArea = area(frameTuple, cmp);
+					if (area < minArea) {
+						bestChild = i;
+					}
+				}
+			}
+		}
+		tupleEntries1.clear();
 
-        frameTuple.resetByTupleIndex(this, bestChild);
-        if (minEnlargedArea > 0.0) {
-            return true;
-        } else {
-            return false;
-        }
-    }
+		frameTuple.resetByTupleIndex(this, bestChild);
+		if (minEnlargedArea > 0.0) {
+			return true;
+		} else {
+			return false;
+		}
+	}
 
-    @Override
-    public int getBestChildPageId(MultiComparator cmp) {
-        return buf.getInt(getChildPointerOff(frameTuple, cmp));
-    }
+	@Override
+	public int getBestChildPageId(MultiComparator cmp) {
+		return buf.getInt(getChildPointerOff(frameTuple, cmp));
+	}
 
-    @Override
-    public int findTupleByPointer(ITupleReference tuple, MultiComparator cmp) {
-        frameTuple.setFieldCount(cmp.getKeyFieldCount());
-        for (int i = 0; i < getTupleCount(); i++) {
-            frameTuple.resetByTupleIndex(this, i);
-            int c = pointerCmp(frameTuple, tuple, cmp);
-            if (c == 0) {
-                return i;
-            }
-        }
-        return -1;
-    }
+	@Override
+	public int findTupleByPointer(ITupleReference tuple, MultiComparator cmp) {
+		frameTuple.setFieldCount(cmp.getKeyFieldCount());
+		for (int i = 0; i < getTupleCount(); i++) {
+			frameTuple.resetByTupleIndex(this, i);
+			int c = pointerCmp(frameTuple, tuple, cmp);
+			if (c == 0) {
+				return i;
+			}
+		}
+		return -1;
+	}
 
-    @Override
-    public int getChildPageIdIfIntersect(ITupleReference tuple, int tupleIndex, MultiComparator cmp) {
-        frameTuple.setFieldCount(cmp.getKeyFieldCount());
-        frameTuple.resetByTupleIndex(this, tupleIndex);
-        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), frameTuple.getFieldData(j), frameTuple.getFieldStart(j),
-                    frameTuple.getFieldLength(j));
-            if (c > 0) {
-                return -1;
-            }
-            c = cmp.getComparators()[i].compare(tuple.getFieldData(j), tuple.getFieldStart(j), tuple.getFieldLength(j),
-                    frameTuple.getFieldData(i), frameTuple.getFieldStart(i), frameTuple.getFieldLength(i));
-            if (c < 0) {
-                return -1;
-            }
-        }
-        // return buf.getInt(frameTuple.getFieldStart(cmp.getKeyFieldCount()));
-        return buf.getInt(getChildPointerOff(frameTuple, cmp));
-    }
+	@Override
+	public int getChildPageIdIfIntersect(ITupleReference tuple, int tupleIndex,
+			MultiComparator cmp) {
+		frameTuple.setFieldCount(cmp.getKeyFieldCount());
+		frameTuple.resetByTupleIndex(this, tupleIndex);
+		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),
+					frameTuple.getFieldData(j), frameTuple.getFieldStart(j),
+					frameTuple.getFieldLength(j));
+			if (c > 0) {
+				return -1;
+			}
+			c = cmp.getComparators()[i].compare(tuple.getFieldData(j),
+					tuple.getFieldStart(j), tuple.getFieldLength(j),
+					frameTuple.getFieldData(i), frameTuple.getFieldStart(i),
+					frameTuple.getFieldLength(i));
+			if (c < 0) {
+				return -1;
+			}
+		}
+		// return buf.getInt(frameTuple.getFieldStart(cmp.getKeyFieldCount()));
+		return buf.getInt(getChildPointerOff(frameTuple, cmp));
+	}
 
-    @Override
-    public int findTupleByPointer(ITupleReference tuple, PathList traverseList, int parentIndex, MultiComparator cmp) {
-        frameTuple.setFieldCount(cmp.getKeyFieldCount());
-        for (int i = 0; i < getTupleCount(); i++) {
-            frameTuple.resetByTupleIndex(this, i);
+	@Override
+	public int findTupleByPointer(ITupleReference tuple, PathList traverseList,
+			int parentIndex, MultiComparator cmp) {
+		frameTuple.setFieldCount(cmp.getKeyFieldCount());
+		for (int i = 0; i < getTupleCount(); i++) {
+			frameTuple.resetByTupleIndex(this, i);
 
-            int c = pointerCmp(frameTuple, tuple, cmp);
-            if (c == 0) {
-                return i;
-            } else {
-                int pageId = IntegerSerializerDeserializer.getInt(frameTuple.getFieldData(cmp.getKeyFieldCount() - 1),
-                        getChildPointerOff(frameTuple, cmp));
-                traverseList.add(pageId, -1, parentIndex);
-            }
-        }
-        return -1;
-    }
+			int c = pointerCmp(frameTuple, tuple, cmp);
+			if (c == 0) {
+				return i;
+			} else {
+				int pageId = IntegerSerializerDeserializer.getInt(
+						frameTuple.getFieldData(cmp.getKeyFieldCount() - 1),
+						getChildPointerOff(frameTuple, cmp));
+				traverseList.add(pageId, -1, parentIndex);
+			}
+		}
+		return -1;
+	}
 
-    @Override
-    public boolean compact(MultiComparator cmp) {
-        resetSpaceParams();
-        frameTuple.setFieldCount(cmp.getKeyFieldCount());
+	@Override
+	public boolean compact(MultiComparator cmp) {
+		resetSpaceParams();
+		frameTuple.setFieldCount(cmp.getKeyFieldCount());
 
-        int tupleCount = buf.getInt(tupleCountOff);
-        int freeSpace = buf.getInt(freeSpaceOff);
+		int tupleCount = buf.getInt(tupleCountOff);
+		int freeSpace = buf.getInt(freeSpaceOff);
 
-        ArrayList<SlotOffTupleOff> sortedTupleOffs = new ArrayList<SlotOffTupleOff>();
-        sortedTupleOffs.ensureCapacity(tupleCount);
-        for (int i = 0; i < tupleCount; i++) {
-            int slotOff = slotManager.getSlotOff(i);
-            int tupleOff = slotManager.getTupleOff(slotOff);
-            sortedTupleOffs.add(new SlotOffTupleOff(i, slotOff, tupleOff));
-        }
-        Collections.sort(sortedTupleOffs);
+		ArrayList<SlotOffTupleOff> sortedTupleOffs = new ArrayList<SlotOffTupleOff>();
+		sortedTupleOffs.ensureCapacity(tupleCount);
+		for (int i = 0; i < tupleCount; i++) {
+			int slotOff = slotManager.getSlotOff(i);
+			int tupleOff = slotManager.getTupleOff(slotOff);
+			sortedTupleOffs.add(new SlotOffTupleOff(i, slotOff, tupleOff));
+		}
+		Collections.sort(sortedTupleOffs);
 
-        for (int i = 0; i < sortedTupleOffs.size(); i++) {
-            int tupleOff = sortedTupleOffs.get(i).tupleOff;
-            frameTuple.resetByTupleOffset(buf, tupleOff);
+		for (int i = 0; i < sortedTupleOffs.size(); i++) {
+			int tupleOff = sortedTupleOffs.get(i).tupleOff;
+			frameTuple.resetByTupleOffset(buf, tupleOff);
 
-            int tupleEndOff = frameTuple.getFieldStart(frameTuple.getFieldCount() - 1)
-                    + frameTuple.getFieldLength(frameTuple.getFieldCount() - 1);
-            int tupleLength = tupleEndOff - tupleOff + childPtrSize;
-            System.arraycopy(buf.array(), tupleOff, buf.array(), freeSpace, tupleLength);
+			int tupleEndOff = frameTuple.getFieldStart(frameTuple
+					.getFieldCount() - 1)
+					+ frameTuple.getFieldLength(frameTuple.getFieldCount() - 1);
+			int tupleLength = tupleEndOff - tupleOff + childPtrSize;
+			System.arraycopy(buf.array(), tupleOff, buf.array(), freeSpace,
+					tupleLength);
 
-            slotManager.setSlot(sortedTupleOffs.get(i).slotOff, freeSpace);
-            freeSpace += tupleLength;
-        }
+			slotManager.setSlot(sortedTupleOffs.get(i).slotOff, freeSpace);
+			freeSpace += tupleLength;
+		}
 
-        buf.putInt(freeSpaceOff, freeSpace);
-        buf.putInt(totalFreeSpaceOff, buf.capacity() - freeSpace - tupleCount * slotManager.getSlotSize());
+		buf.putInt(freeSpaceOff, freeSpace);
+		buf.putInt(totalFreeSpaceOff, buf.capacity() - freeSpace - tupleCount
+				* slotManager.getSlotSize());
 
-        return false;
-    }
+		return false;
+	}
 
-    @Override
-    public FrameOpSpaceStatus hasSpaceInsert(ITupleReference tuple, MultiComparator cmp) {
-        int bytesRequired = tupleWriter.bytesRequired(tuple) + childPtrSize; // for
-                                                                             // the
-                                                                             // child
-                                                                             // pointer
-        if (bytesRequired + slotManager.getSlotSize() <= buf.capacity() - buf.getInt(freeSpaceOff)
-                - (buf.getInt(tupleCountOff) * slotManager.getSlotSize()))
-            return FrameOpSpaceStatus.SUFFICIENT_CONTIGUOUS_SPACE;
-        else if (bytesRequired + slotManager.getSlotSize() <= buf.getInt(totalFreeSpaceOff))
-            return FrameOpSpaceStatus.SUFFICIENT_SPACE;
-        else
-            return FrameOpSpaceStatus.INSUFFICIENT_SPACE;
-    }
+	@Override
+	public FrameOpSpaceStatus hasSpaceInsert(ITupleReference tuple,
+			MultiComparator cmp) {
+		int bytesRequired = tupleWriter.bytesRequired(tuple) + childPtrSize; // for
+																				// the
+																				// child
+																				// pointer
+		if (bytesRequired + slotManager.getSlotSize() <= buf.capacity()
+				- buf.getInt(freeSpaceOff)
+				- (buf.getInt(tupleCountOff) * slotManager.getSlotSize()))
+			return FrameOpSpaceStatus.SUFFICIENT_CONTIGUOUS_SPACE;
+		else if (bytesRequired + slotManager.getSlotSize() <= buf
+				.getInt(totalFreeSpaceOff))
+			return FrameOpSpaceStatus.SUFFICIENT_SPACE;
+		else
+			return FrameOpSpaceStatus.INSUFFICIENT_SPACE;
+	}
 
-    @Override
-    public void adjustKey(ITupleReference tuple, int tupleIndex, MultiComparator cmp) {
-        frameTuple.setFieldCount(cmp.getKeyFieldCount());
-        if (tupleIndex == -1) {
-            tupleIndex = findTupleByPointer(tuple, cmp);
-        }
-        if (tupleIndex != -1) {
-            tupleWriter.writeTuple(tuple, buf, getTupleOffset(tupleIndex));
-        }
-    }
+	@Override
+	public void adjustKey(ITupleReference tuple, int tupleIndex,
+			MultiComparator cmp) {
+		frameTuple.setFieldCount(cmp.getKeyFieldCount());
+		if (tupleIndex == -1) {
+			tupleIndex = findTupleByPointer(tuple, cmp);
+		}
+		if (tupleIndex != -1) {
+			tupleWriter.writeTuple(tuple, buf, getTupleOffset(tupleIndex));
+		}
+	}
 
-    private int pointerCmp(ITupleReference tupleA, ITupleReference tupleB, MultiComparator cmp) {
-        return cmp.getIntCmp().compare(tupleA.getFieldData(cmp.getKeyFieldCount() - 1),
-                getChildPointerOff(tupleA, cmp), childPtrSize, tupleB.getFieldData(cmp.getKeyFieldCount() - 1),
-                getChildPointerOff(tupleB, cmp), childPtrSize);
-    }
+	private int pointerCmp(ITupleReference tupleA, ITupleReference tupleB,
+			MultiComparator cmp) {
+		return cmp.getIntCmp().compare(
+				tupleA.getFieldData(cmp.getKeyFieldCount() - 1),
+				getChildPointerOff(tupleA, cmp), childPtrSize,
+				tupleB.getFieldData(cmp.getKeyFieldCount() - 1),
+				getChildPointerOff(tupleB, cmp), childPtrSize);
+	}
 
-    @Override
-    public int split(ITreeIndexFrame rightFrame, ITupleReference tuple, MultiComparator cmp, ISplitKey splitKey)
-            throws Exception {
+	@Override
+	public int split(ITreeIndexFrame rightFrame, ITupleReference tuple,
+			MultiComparator cmp, ISplitKey splitKey) throws Exception {
 
-        rightFrame.setPageTupleFieldCount(cmp.getKeyFieldCount());
-        frameTuple.setFieldCount(cmp.getKeyFieldCount());
+		rightFrame.setPageTupleFieldCount(cmp.getKeyFieldCount());
+		frameTuple.setFieldCount(cmp.getKeyFieldCount());
 
-        RTreeSplitKey rTreeSplitKey = ((RTreeSplitKey) splitKey);
-        RTreeTypeAwareTupleWriter rTreeTupleWriterLeftFrame = ((RTreeTypeAwareTupleWriter) tupleWriter);
-        RTreeTypeAwareTupleWriter rTreeTupleWriterRightFrame = ((RTreeTypeAwareTupleWriter) rightFrame.getTupleWriter());
+		RTreeSplitKey rTreeSplitKey = ((RTreeSplitKey) splitKey);
+		RTreeTypeAwareTupleWriter rTreeTupleWriterLeftFrame = ((RTreeTypeAwareTupleWriter) tupleWriter);
+		RTreeTypeAwareTupleWriter rTreeTupleWriterRightFrame = ((RTreeTypeAwareTupleWriter) rightFrame
+				.getTupleWriter());
 
-        // calculations are based on the R*-tree paper
-        int m = (int) Math.floor((getTupleCount() + 1) * splitFactor);
-        int splitDistribution = getTupleCount() - (2 * m) + 2;
+		// calculations are based on the R*-tree paper
+		int m = (int) Math.floor((getTupleCount() + 1) * splitFactor);
+		int splitDistribution = getTupleCount() - (2 * m) + 2;
 
-        // to calculate the minimum margin in order to pick the split axis
-        double minMargin = Double.MAX_VALUE;
-        int splitAxis = 0, sortOrder = 0;
+		// to calculate the minimum margin in order to pick the split axis
+		double minMargin = Double.MAX_VALUE;
+		int splitAxis = 0, sortOrder = 0;
 
-        int maxFieldPos = cmp.getKeyFieldCount() / 2;
-        for (int i = 0; i < maxFieldPos; i++) {
-            int j = maxFieldPos + i;
-            for (int k = 0; k < getTupleCount(); ++k) {
+		int maxFieldPos = cmp.getKeyFieldCount() / 2;
+		for (int i = 0; i < maxFieldPos; i++) {
+			int j = maxFieldPos + i;
+			for (int k = 0; k < getTupleCount(); ++k) {
 
-                frameTuple.resetByTupleIndex(this, k);
+				frameTuple.resetByTupleIndex(this, k);
 
-                double LowerKey = DoubleSerializerDeserializer.getDouble(frameTuple.getFieldData(i),
-                        frameTuple.getFieldStart(i));
-                double UpperKey = DoubleSerializerDeserializer.getDouble(frameTuple.getFieldData(j),
-                        frameTuple.getFieldStart(j));
+				double LowerKey = recDescSers[i]
+						.getValue(frameTuple.getFieldData(i),
+								frameTuple.getFieldStart(i));
+				double UpperKey = recDescSers[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));
+				tupleEntries1.add(k, LowerKey);
+				tupleEntries2.add(k, UpperKey);
+			}
+			double LowerKey = recDescSers[i].getValue(tuple.getFieldData(i),
+					tuple.getFieldStart(i));
+			double UpperKey = recDescSers[j].getValue(tuple.getFieldData(j),
+					tuple.getFieldStart(j));
 
-            tupleEntries1.add(-1, LowerKey);
-            tupleEntries2.add(-1, UpperKey);
+			tupleEntries1.add(-1, LowerKey);
+			tupleEntries2.add(-1, UpperKey);
 
-            tupleEntries1.sort(EntriesOrder.ASCENDING, getTupleCount() + 1);
-            tupleEntries2.sort(EntriesOrder.ASCENDING, getTupleCount() + 1);
+			tupleEntries1.sort(EntriesOrder.ASCENDING, getTupleCount() + 1);
+			tupleEntries2.sort(EntriesOrder.ASCENDING, getTupleCount() + 1);
 
-            double lowerMargin = 0.0, upperMargin = 0.0;
-            // generate distribution
-            for (int k = 1; k <= splitDistribution; ++k) {
-                int d = m - 1 + k;
+			double lowerMargin = 0.0, upperMargin = 0.0;
+			// generate distribution
+			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);
+				generateDist(tuple, tupleEntries2, rec[1], 0, d);
+				generateDist(tuple, tupleEntries1, rec[2], d,
+						getTupleCount() + 1);
+				generateDist(tuple, tupleEntries2, rec[3], d,
+						getTupleCount() + 1);
 
-                // calculate the margin of the distributions
-                lowerMargin += rec[0].margin() + rec[2].margin();
-                upperMargin += rec[1].margin() + rec[3].margin();
-            }
-            double margin = Math.min(lowerMargin, upperMargin);
+				// calculate the margin of the distributions
+				lowerMargin += rec[0].margin() + rec[2].margin();
+				upperMargin += rec[1].margin() + rec[3].margin();
+			}
+			double margin = Math.min(lowerMargin, upperMargin);
 
-            // store minimum margin as split axis
-            if (margin < minMargin) {
-                minMargin = margin;
-                splitAxis = i;
-                sortOrder = (lowerMargin < upperMargin) ? 0 : 2;
-            }
+			// store minimum margin as split axis
+			if (margin < minMargin) {
+				minMargin = margin;
+				splitAxis = i;
+				sortOrder = (lowerMargin < upperMargin) ? 0 : 2;
+			}
 
-            tupleEntries1.clear();
-            tupleEntries2.clear();
-        }
+			tupleEntries1.clear();
+			tupleEntries2.clear();
+		}
 
-        for (int i = 0; i < getTupleCount(); ++i) {
-            frameTuple.resetByTupleIndex(this, i);
-            double key = DoubleSerializerDeserializer.getDouble(frameTuple.getFieldData(splitAxis + sortOrder),
-                    frameTuple.getFieldStart(splitAxis + sortOrder));
-            tupleEntries1.add(i, key);
-        }
-        double key = DoubleSerializerDeserializer.getDouble(tuple.getFieldData(splitAxis + sortOrder),
-                tuple.getFieldStart(splitAxis + sortOrder));
-        tupleEntries1.add(-1, key);
-        tupleEntries1.sort(EntriesOrder.ASCENDING, getTupleCount() + 1);
+		for (int i = 0; i < getTupleCount(); ++i) {
+			frameTuple.resetByTupleIndex(this, i);
+			double key = recDescSers[splitAxis + sortOrder].getValue(
+					frameTuple.getFieldData(splitAxis + sortOrder),
+					frameTuple.getFieldStart(splitAxis + sortOrder));
+			tupleEntries1.add(i, key);
+		}
+		double key = recDescSers[splitAxis + sortOrder].getValue(
+				tuple.getFieldData(splitAxis + sortOrder),
+				tuple.getFieldStart(splitAxis + sortOrder));
+		tupleEntries1.add(-1, key);
+		tupleEntries1.sort(EntriesOrder.ASCENDING, getTupleCount() + 1);
 
-        double minArea = Double.MAX_VALUE;
-        double minOverlap = Double.MAX_VALUE;
-        int splitPoint = 0;
-        for (int i = 1; i <= splitDistribution; ++i) {
-            int d = m - 1 + i;
+		double minArea = Double.MAX_VALUE;
+		double minOverlap = Double.MAX_VALUE;
+		int splitPoint = 0;
+		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);
+			generateDist(tuple, tupleEntries1, rec[2], d, getTupleCount() + 1);
 
-            double overlap = rec[0].overlappedArea(rec[2]);
-            if (overlap < minOverlap) {
-                splitPoint = d;
-                minOverlap = overlap;
-                minArea = rec[0].area() + rec[2].area();
-            } else if (overlap == minOverlap) {
-                double area = rec[0].area() + rec[2].area();
-                if (area < minArea) {
-                    splitPoint = d;
-                    minArea = area;
-                }
-            }
-        }
-        int startIndex, endIndex;
-        if (splitPoint < (getTupleCount() + 1) / 2) {
-            startIndex = 0;
-            endIndex = splitPoint;
-        } else {
-            startIndex = splitPoint;
-            endIndex = (getTupleCount() + 1);
-        }
-        boolean tupleInserted = false;
-        int totalBytes = 0, numOfDeletedTuples = 0;
-        for (int i = startIndex; i < endIndex; i++) {
-            if (tupleEntries1.get(i).getTupleIndex() != -1) {
-                frameTuple.resetByTupleIndex(this, tupleEntries1.get(i).getTupleIndex());
-                rightFrame.insert(frameTuple, cmp, -1);
-                ((UnorderedSlotManager) slotManager).modifySlot(
-                        slotManager.getSlotOff(tupleEntries1.get(i).getTupleIndex()), -1);
-                totalBytes += tupleWriter.bytesRequired(frameTuple) + childPtrSize;
-                numOfDeletedTuples++;
-            } else {
-                rightFrame.insert(tuple, cmp, -1);
-                tupleInserted = true;
-            }
-        }
+			double overlap = rec[0].overlappedArea(rec[2]);
+			if (overlap < minOverlap) {
+				splitPoint = d;
+				minOverlap = overlap;
+				minArea = rec[0].area() + rec[2].area();
+			} else if (overlap == minOverlap) {
+				double area = rec[0].area() + rec[2].area();
+				if (area < minArea) {
+					splitPoint = d;
+					minArea = area;
+				}
+			}
+		}
+		int startIndex, endIndex;
+		if (splitPoint < (getTupleCount() + 1) / 2) {
+			startIndex = 0;
+			endIndex = splitPoint;
+		} else {
+			startIndex = splitPoint;
+			endIndex = (getTupleCount() + 1);
+		}
+		boolean tupleInserted = false;
+		int totalBytes = 0, numOfDeletedTuples = 0;
+		for (int i = startIndex; i < endIndex; i++) {
+			if (tupleEntries1.get(i).getTupleIndex() != -1) {
+				frameTuple.resetByTupleIndex(this, tupleEntries1.get(i)
+						.getTupleIndex());
+				rightFrame.insert(frameTuple, cmp, -1);
+				((UnorderedSlotManager) slotManager).modifySlot(slotManager
+						.getSlotOff(tupleEntries1.get(i).getTupleIndex()), -1);
+				totalBytes += tupleWriter.bytesRequired(frameTuple)
+						+ childPtrSize;
+				numOfDeletedTuples++;
+			} else {
+				rightFrame.insert(tuple, cmp, -1);
+				tupleInserted = true;
+			}
+		}
 
-        ((UnorderedSlotManager) slotManager).deleteEmptySlots();
+		((UnorderedSlotManager) slotManager).deleteEmptySlots();
 
-        // maintain space information
-        buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) + totalBytes
-                + (slotManager.getSlotSize() * numOfDeletedTuples));
+		// maintain space information
+		buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff)
+				+ totalBytes + (slotManager.getSlotSize() * numOfDeletedTuples));
 
-        // compact both pages
-        rightFrame.compact(cmp);
-        compact(cmp);
+		// compact both pages
+		rightFrame.compact(cmp);
+		compact(cmp);
 
-        if (!tupleInserted) {
-            insert(tuple, cmp, -1);
-        }
+		if (!tupleInserted) {
+			insert(tuple, cmp, -1);
+		}
 
-        int tupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff());
-        frameTuple.resetByTupleOffset(buf, tupleOff);
-        int splitKeySize = tupleWriter.bytesRequired(frameTuple, 0, cmp.getKeyFieldCount());
+		int tupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff());
+		frameTuple.resetByTupleOffset(buf, tupleOff);
+		int splitKeySize = tupleWriter.bytesRequired(frameTuple, 0,
+				cmp.getKeyFieldCount());
 
-        splitKey.initData(splitKeySize);
-        this.adjustMBR(tuples, cmp);
-        rTreeTupleWriterLeftFrame.writeTupleFields(tuples, 0, rTreeSplitKey.getLeftPageBuffer(), 0);
-        rTreeSplitKey.getLeftTuple().resetByTupleOffset(rTreeSplitKey.getLeftPageBuffer(), 0);
+		splitKey.initData(splitKeySize);
+		this.adjustMBR(tuples, cmp);
+		rTreeTupleWriterLeftFrame.writeTupleFields(tuples, 0,
+				rTreeSplitKey.getLeftPageBuffer(), 0);
+		rTreeSplitKey.getLeftTuple().resetByTupleOffset(
+				rTreeSplitKey.getLeftPageBuffer(), 0);
 
-        ((IRTreeFrame) rightFrame).adjustMBR(((RTreeNSMFrame) rightFrame).getTuples(), cmp);
-        rTreeTupleWriterRightFrame.writeTupleFields(((RTreeNSMFrame) rightFrame).getTuples(), 0,
-                rTreeSplitKey.getRightPageBuffer(), 0);
-        rTreeSplitKey.getRightTuple().resetByTupleOffset(rTreeSplitKey.getRightPageBuffer(), 0);
+		((IRTreeFrame) rightFrame).adjustMBR(
+				((RTreeNSMFrame) rightFrame).getTuples(), cmp);
+		rTreeTupleWriterRightFrame.writeTupleFields(
+				((RTreeNSMFrame) rightFrame).getTuples(), 0,
+				rTreeSplitKey.getRightPageBuffer(), 0);
+		rTreeSplitKey.getRightTuple().resetByTupleOffset(
+				rTreeSplitKey.getRightPageBuffer(), 0);
 
-        tupleEntries1.clear();
-        tupleEntries2.clear();
-        return 0;
-    }
+		tupleEntries1.clear();
+		tupleEntries2.clear();
+		return 0;
+	}
 
-    private int getChildPointerOff(ITupleReference tuple, MultiComparator cmp) {
-        return tuple.getFieldStart(cmp.getKeyFieldCount() - 1) + tuple.getFieldLength(cmp.getKeyFieldCount() - 1);
-    }
+	private int getChildPointerOff(ITupleReference tuple, MultiComparator cmp) {
+		return tuple.getFieldStart(cmp.getKeyFieldCount() - 1)
+				+ tuple.getFieldLength(cmp.getKeyFieldCount() - 1);
+	}
 
-    @Override
-    public void insert(ITupleReference tuple, MultiComparator cmp, int tupleIndex) throws Exception {
-        frameTuple.setFieldCount(cmp.getKeyFieldCount());
-        slotManager.insertSlot(-1, 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), getChildPointerOff(tuple, cmp), buf.array(),
-                freeSpace + bytesWritten, childPtrSize);
-        int tupleSize = bytesWritten + childPtrSize;
+	@Override
+	public void insert(ITupleReference tuple, MultiComparator cmp,
+			int tupleIndex) throws Exception {
+		frameTuple.setFieldCount(cmp.getKeyFieldCount());
+		slotManager.insertSlot(-1, 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),
+				getChildPointerOff(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());
 
-    }
+	}
 
-    @Override
-    public void delete(int tupleIndex, MultiComparator cmp) throws Exception {
-        frameTuple.setFieldCount(cmp.getKeyFieldCount());
-        int slotOff = slotManager.getSlotOff(tupleIndex);
+	@Override
+	public void delete(int tupleIndex, MultiComparator cmp) throws Exception {
+		frameTuple.setFieldCount(cmp.getKeyFieldCount());
+		int slotOff = slotManager.getSlotOff(tupleIndex);
 
-        int tupleOff = slotManager.getTupleOff(slotOff);
-        frameTuple.resetByTupleOffset(buf, tupleOff);
-        int tupleSize = tupleWriter.bytesRequired(frameTuple);
+		int tupleOff = slotManager.getTupleOff(slotOff);
+		frameTuple.resetByTupleOffset(buf, tupleOff);
+		int tupleSize = tupleWriter.bytesRequired(frameTuple);
 
-        // perform deletion (we just do a memcpy to overwrite the slot)
-        int slotStartOff = slotManager.getSlotEndOff();
-        int length = slotOff - slotStartOff;
-        System.arraycopy(buf.array(), slotStartOff, buf.array(), slotStartOff + slotManager.getSlotSize(), length);
+		// perform deletion (we just do a memcpy to overwrite the slot)
+		int slotStartOff = slotManager.getSlotEndOff();
+		int length = slotOff - slotStartOff;
+		System.arraycopy(buf.array(), slotStartOff, buf.array(), slotStartOff
+				+ slotManager.getSlotSize(), length);
 
-        // maintain space information
-        buf.putInt(tupleCountOff, buf.getInt(tupleCountOff) - 1);
-        buf.putInt(totalFreeSpaceOff,
-                buf.getInt(totalFreeSpaceOff) + tupleSize + childPtrSize + slotManager.getSlotSize());
-    }
+		// maintain space information
+		buf.putInt(tupleCountOff, buf.getInt(tupleCountOff) - 1);
+		buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) + tupleSize
+				+ childPtrSize + slotManager.getSlotSize());
+	}
 
-    @Override
-    public boolean recomputeMBR(ITupleReference tuple, int tupleIndex, MultiComparator cmp) {
-        frameTuple.setFieldCount(cmp.getKeyFieldCount());
-        frameTuple.resetByTupleIndex(this, tupleIndex);
+	@Override
+	public boolean recomputeMBR(ITupleReference tuple, int tupleIndex,
+			MultiComparator cmp) {
+		frameTuple.setFieldCount(cmp.getKeyFieldCount());
+		frameTuple.resetByTupleIndex(this, tupleIndex);
 
-        int maxFieldPos = cmp.getKeyFieldCount() / 2;
-        for (int i = 0; i < maxFieldPos; i++) {
-            int j = maxFieldPos + i;
-            int c = cmp.getComparators()[i].compare(frameTuple.getFieldData(i), frameTuple.getFieldStart(i),
-                    frameTuple.getFieldLength(i), tuple.getFieldData(i), tuple.getFieldStart(i),
-                    tuple.getFieldLength(i));
-            if (c != 0) {
-                return true;
-            }
-            c = cmp.getComparators()[j].compare(frameTuple.getFieldData(j), frameTuple.getFieldStart(j),
-                    frameTuple.getFieldLength(j), tuple.getFieldData(j), tuple.getFieldStart(j),
-                    tuple.getFieldLength(j));
+		int maxFieldPos = cmp.getKeyFieldCount() / 2;
+		for (int i = 0; i < maxFieldPos; i++) {
+			int j = maxFieldPos + i;
+			int c = cmp.getComparators()[i].compare(frameTuple.getFieldData(i),
+					frameTuple.getFieldStart(i), frameTuple.getFieldLength(i),
+					tuple.getFieldData(i), tuple.getFieldStart(i),
+					tuple.getFieldLength(i));
+			if (c != 0) {
+				return true;
+			}
+			c = cmp.getComparators()[j].compare(frameTuple.getFieldData(j),
+					frameTuple.getFieldStart(j), frameTuple.getFieldLength(j),
+					tuple.getFieldData(j), tuple.getFieldStart(j),
+					tuple.getFieldLength(j));
 
-            if (c != 0) {
-                return true;
-            }
-        }
-        return false;
-    }
+			if (c != 0) {
+				return true;
+			}
+		}
+		return false;
+	}
 
-    private double overlappedArea(ITupleReference tuple1, ITupleReference tupleToBeInserted, ITupleReference tuple2,
-            MultiComparator cmp) {
-        double area = 1.0;
-        double f1, f2;
+	private double overlappedArea(ITupleReference tuple1,
+			ITupleReference tupleToBeInserted, ITupleReference tuple2,
+			MultiComparator cmp) {
+		double area = 1.0;
+		double f1, f2;
 
-        int maxFieldPos = cmp.getKeyFieldCount() / 2;
-        for (int i = 0; i < maxFieldPos; i++) {
-            int j = maxFieldPos + i;
-            double pHigh1, pLow1;
-            if (tupleToBeInserted != null) {
-                int c = cmp.getComparators()[i].compare(tuple1.getFieldData(i), tuple1.getFieldStart(i),
-                        tuple1.getFieldLength(i), tupleToBeInserted.getFieldData(i),
-                        tupleToBeInserted.getFieldStart(i), tupleToBeInserted.getFieldLength(i));
-                if (c < 0) {
-                    pLow1 = DoubleSerializerDeserializer.getDouble(tuple1.getFieldData(i), tuple1.getFieldStart(i));
-                } else {
-                    pLow1 = DoubleSerializerDeserializer.getDouble(tupleToBeInserted.getFieldData(i),
-                            tupleToBeInserted.getFieldStart(i));
-                }
+		int maxFieldPos = cmp.getKeyFieldCount() / 2;
+		for (int i = 0; i < maxFieldPos; i++) {
+			int j = maxFieldPos + i;
+			double pHigh1, pLow1;
+			if (tupleToBeInserted != null) {
+				int c = cmp.getComparators()[i].compare(tuple1.getFieldData(i),
+						tuple1.getFieldStart(i), tuple1.getFieldLength(i),
+						tupleToBeInserted.getFieldData(i),
+						tupleToBeInserted.getFieldStart(i),
+						tupleToBeInserted.getFieldLength(i));
+				if (c < 0) {
+					pLow1 = recDescSers[i].getValue(tuple1.getFieldData(i),
+							tuple1.getFieldStart(i));
+				} else {
+					pLow1 = recDescSers[i].getValue(
+							tupleToBeInserted.getFieldData(i),
+							tupleToBeInserted.getFieldStart(i));
+				}
 
-                c = cmp.getComparators()[j].compare(tuple1.getFieldData(j), tuple1.getFieldStart(j),
-                        tuple1.getFieldLength(j), tupleToBeInserted.getFieldData(j),
-                        tupleToBeInserted.getFieldStart(j), tupleToBeInserted.getFieldLength(j));
-                if (c > 0) {
-                    pHigh1 = DoubleSerializerDeserializer.getDouble(tuple1.getFieldData(j), tuple1.getFieldStart(j));
-                } else {
-                    pHigh1 = DoubleSerializerDeserializer.getDouble(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));
-            }
+				c = cmp.getComparators()[j].compare(tuple1.getFieldData(j),
+						tuple1.getFieldStart(j), tuple1.getFieldLength(j),
+						tupleToBeInserted.getFieldData(j),
+						tupleToBeInserted.getFieldStart(j),
+						tupleToBeInserted.getFieldLength(j));
+				if (c > 0) {
+					pHigh1 = recDescSers[j].getValue(tuple1.getFieldData(j),
+							tuple1.getFieldStart(j));
+				} else {
+					pHigh1 = recDescSers[j].getValue(
+							tupleToBeInserted.getFieldData(j),
+							tupleToBeInserted.getFieldStart(j));
+				}
+			} else {
+				pLow1 = recDescSers[i].getValue(tuple1.getFieldData(i),
+						tuple1.getFieldStart(i));
+				pHigh1 = recDescSers[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 = recDescSers[i].getValue(tuple2.getFieldData(i),
+					tuple2.getFieldStart(i));
+			double pHigh2 = recDescSers[j].getValue(tuple2.getFieldData(j),
+					tuple2.getFieldStart(j));
 
-            if (pLow1 > pHigh2 || pHigh1 < pLow2) {
-                return 0.0;
-            }
+			if (pLow1 > pHigh2 || pHigh1 < pLow2) {
+				return 0.0;
+			}
 
-            f1 = Math.max(pLow1, pLow2);
-            f2 = Math.min(pHigh1, pHigh2);
-            area *= f2 - f1;
-        }
-        return area;
-    }
+			f1 = Math.max(pLow1, pLow2);
+			f2 = Math.min(pHigh1, pHigh2);
+			area *= f2 - f1;
+		}
+		return area;
+	}
 
-    private double enlargedArea(ITupleReference tuple, ITupleReference tupleToBeInserted, MultiComparator cmp) {
-        double areaBeforeEnlarge = area(tuple, cmp);
-        double areaAfterEnlarge = 1.0;
+	private double enlargedArea(ITupleReference tuple,
+			ITupleReference tupleToBeInserted, MultiComparator cmp) {
+		double areaBeforeEnlarge = area(tuple, cmp);
+		double areaAfterEnlarge = 1.0;
 
-        int maxFieldPos = cmp.getKeyFieldCount() / 2;
-        for (int i = 0; i < maxFieldPos; i++) {
-            int j = maxFieldPos + i;
-            double pHigh, pLow;
-            int c = cmp.getComparators()[i].compare(tuple.getFieldData(i), tuple.getFieldStart(i),
-                    tuple.getFieldLength(i), tupleToBeInserted.getFieldData(i), tupleToBeInserted.getFieldStart(i),
-                    tupleToBeInserted.getFieldLength(i));
-            if (c < 0) {
-                pLow = DoubleSerializerDeserializer.getDouble(tuple.getFieldData(i), tuple.getFieldStart(i));
-            } else {
-                pLow = DoubleSerializerDeserializer.getDouble(tupleToBeInserted.getFieldData(i),
-                        tupleToBeInserted.getFieldStart(i));
-            }
+		int maxFieldPos = cmp.getKeyFieldCount() / 2;
+		for (int i = 0; i < maxFieldPos; i++) {
+			int j = maxFieldPos + i;
+			double pHigh, pLow;
+			int c = cmp.getComparators()[i].compare(tuple.getFieldData(i),
+					tuple.getFieldStart(i), tuple.getFieldLength(i),
+					tupleToBeInserted.getFieldData(i),
+					tupleToBeInserted.getFieldStart(i),
+					tupleToBeInserted.getFieldLength(i));
+			if (c < 0) {
+				pLow = recDescSers[i].getValue(tuple.getFieldData(i),
+						tuple.getFieldStart(i));
+			} else {
+				pLow = recDescSers[i].getValue(
+						tupleToBeInserted.getFieldData(i),
+						tupleToBeInserted.getFieldStart(i));
+			}
 
-            c = cmp.getComparators()[j].compare(tuple.getFieldData(j), tuple.getFieldStart(j), tuple.getFieldLength(j),
-                    tupleToBeInserted.getFieldData(j), tupleToBeInserted.getFieldStart(j),
-                    tupleToBeInserted.getFieldLength(j));
-            if (c > 0) {
-                pHigh = DoubleSerializerDeserializer.getDouble(tuple.getFieldData(j), tuple.getFieldStart(j));
-            } else {
-                pHigh = DoubleSerializerDeserializer.getDouble(tupleToBeInserted.getFieldData(j),
-                        tupleToBeInserted.getFieldStart(j));
-            }
-            areaAfterEnlarge *= pHigh - pLow;
-        }
-        return areaAfterEnlarge - areaBeforeEnlarge;
-    }
+			c = cmp.getComparators()[j].compare(tuple.getFieldData(j),
+					tuple.getFieldStart(j), tuple.getFieldLength(j),
+					tupleToBeInserted.getFieldData(j),
+					tupleToBeInserted.getFieldStart(j),
+					tupleToBeInserted.getFieldLength(j));
+			if (c > 0) {
+				pHigh = recDescSers[j].getValue(tuple.getFieldData(j),
+						tuple.getFieldStart(j));
+			} else {
+				pHigh = recDescSers[j].getValue(
+						tupleToBeInserted.getFieldData(j),
+						tupleToBeInserted.getFieldStart(j));
+			}
+			areaAfterEnlarge *= pHigh - pLow;
+		}
+		return areaAfterEnlarge - areaBeforeEnlarge;
+	}
 
-    private double area(ITupleReference tuple, MultiComparator cmp) {
-        double area = 1.0;
-        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));
-        }
-        return area;
-    }
+	private double area(ITupleReference tuple, MultiComparator cmp) {
+		double area = 1.0;
+		int maxFieldPos = cmp.getKeyFieldCount() / 2;
+		for (int i = 0; i < maxFieldPos; i++) {
+			int j = maxFieldPos + i;
+			area *= recDescSers[j].getValue(tuple.getFieldData(j),
+					tuple.getFieldStart(j))
+					- recDescSers[i].getValue(tuple.getFieldData(i),
+							tuple.getFieldStart(i));
+		}
+		return area;
+	}
 
-    @Override
-    public void enlarge(ITupleReference tuple, MultiComparator cmp) {
-        int maxFieldPos = cmp.getKeyFieldCount() / 2;
-        for (int i = 0; i < maxFieldPos; i++) {
-            int j = maxFieldPos + i;
-            int c = cmp.getComparators()[i].compare(frameTuple.getFieldData(i), frameTuple.getFieldStart(i),
-                    frameTuple.getFieldLength(i), tuple.getFieldData(i), tuple.getFieldStart(i),
-                    tuple.getFieldLength(i));
-            if (c > 0) {
-                System.arraycopy(tuple.getFieldData(i), tuple.getFieldStart(i), frameTuple.getFieldData(i),
-                        frameTuple.getFieldStart(i), tuple.getFieldLength(i));
-            }
-            c = cmp.getComparators()[j].compare(frameTuple.getFieldData(j), frameTuple.getFieldStart(j),
-                    frameTuple.getFieldLength(j), tuple.getFieldData(j), tuple.getFieldStart(j),
-                    tuple.getFieldLength(j));
-            if (c < 0) {
-                System.arraycopy(tuple.getFieldData(j), tuple.getFieldStart(j), frameTuple.getFieldData(j),
-                        frameTuple.getFieldStart(j), tuple.getFieldLength(j));
-            }
-        }
-    }
+	@Override
+	public void enlarge(ITupleReference tuple, MultiComparator cmp) {
+		int maxFieldPos = cmp.getKeyFieldCount() / 2;
+		for (int i = 0; i < maxFieldPos; i++) {
+			int j = maxFieldPos + i;
+			int c = cmp.getComparators()[i].compare(frameTuple.getFieldData(i),
+					frameTuple.getFieldStart(i), frameTuple.getFieldLength(i),
+					tuple.getFieldData(i), tuple.getFieldStart(i),
+					tuple.getFieldLength(i));
+			if (c > 0) {
+				System.arraycopy(tuple.getFieldData(i), tuple.getFieldStart(i),
+						frameTuple.getFieldData(i),
+						frameTuple.getFieldStart(i), tuple.getFieldLength(i));
+			}
+			c = cmp.getComparators()[j].compare(frameTuple.getFieldData(j),
+					frameTuple.getFieldStart(j), frameTuple.getFieldLength(j),
+					tuple.getFieldData(j), tuple.getFieldStart(j),
+					tuple.getFieldLength(j));
+			if (c < 0) {
+				System.arraycopy(tuple.getFieldData(j), tuple.getFieldStart(j),
+						frameTuple.getFieldData(j),
+						frameTuple.getFieldStart(j), tuple.getFieldLength(j));
+			}
+		}
+	}
 
-    @Override
-    public void adjustMBR(ITreeIndexTupleReference[] tuples, MultiComparator cmp) {
-        for (int i = 0; i < tuples.length; i++) {
-            tuples[i].setFieldCount(cmp.getKeyFieldCount());
-            tuples[i].resetByTupleIndex(this, 0);
-        }
+	@Override
+	public void adjustMBR(ITreeIndexTupleReference[] tuples, MultiComparator cmp) {
+		for (int i = 0; i < tuples.length; i++) {
+			tuples[i].setFieldCount(cmp.getKeyFieldCount());
+			tuples[i].resetByTupleIndex(this, 0);
+		}
 
-        adjustMBRImpl(tuples, cmp);
-    }
-}
+		adjustMBRImpl(tuples, cmp);
+	}
+}
\ No newline at end of file
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrameFactory.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrameFactory.java
index 9fd5a54..004c519 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrameFactory.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMInteriorFrameFactory.java
@@ -15,23 +15,30 @@
 
 package edu.uci.ics.hyracks.storage.am.rtree.frames;
 
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleWriterFactory;
 import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeInteriorFrame;
 
 public class RTreeNSMInteriorFrameFactory implements ITreeIndexFrameFactory {
 
-    private static final long serialVersionUID = 1L;
-    private ITreeIndexTupleWriterFactory tupleWriterFactory;
-    private int keyFieldCount;
+	private static final long serialVersionUID = 1L;
+	private ITreeIndexTupleWriterFactory tupleWriterFactory;
+	private ISerializerDeserializer[] recDescSers;
+	private int keyFieldCount;
 
-    public RTreeNSMInteriorFrameFactory(ITreeIndexTupleWriterFactory tupleWriterFactory, int keyFieldCount) {
-        this.tupleWriterFactory = tupleWriterFactory;
-        this.keyFieldCount = keyFieldCount;
-    }
+	public RTreeNSMInteriorFrameFactory(
+			ITreeIndexTupleWriterFactory tupleWriterFactory,
+			ISerializerDeserializer[] recDescSers, int keyFieldCount) {
+		this.tupleWriterFactory = tupleWriterFactory;
+		this.recDescSers = recDescSers;
+		this.keyFieldCount = keyFieldCount;
+	}
 
-    @Override
-    public IRTreeInteriorFrame createFrame() {
-        return new RTreeNSMInteriorFrame(tupleWriterFactory.createTupleWriter(), keyFieldCount);
-    }
-}
+	@Override
+	public IRTreeInteriorFrame createFrame() {
+		return new RTreeNSMInteriorFrame(
+				tupleWriterFactory.createTupleWriter(), recDescSers,
+				keyFieldCount);
+	}
+}
\ No newline at end of file
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrame.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrame.java
index 7ebe974..29536a8 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrame.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrame.java
@@ -15,8 +15,8 @@
 
 package edu.uci.ics.hyracks.storage.am.rtree.frames;
 
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
 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;
@@ -31,236 +31,262 @@
 
 public class RTreeNSMLeafFrame extends RTreeNSMFrame implements IRTreeLeafFrame {
 
-    public RTreeNSMLeafFrame(ITreeIndexTupleWriter tupleWriter, int keyFieldCount) {
-        super(tupleWriter, keyFieldCount);
-    }
+	public RTreeNSMLeafFrame(ITreeIndexTupleWriter tupleWriter,
+			ISerializerDeserializer[] recDescSers, int keyFieldCount) {
+		super(tupleWriter, recDescSers, keyFieldCount);
+	}
 
-    @Override
-    public int findTupleIndex(ITupleReference tuple, MultiComparator cmp) {
-        frameTuple.setFieldCount(cmp.getFieldCount());
-        return slotManager.findTupleIndex(tuple, frameTuple, cmp, null, null);
-    }
+	@Override
+	public int findTupleIndex(ITupleReference tuple, MultiComparator cmp) {
+		frameTuple.setFieldCount(cmp.getFieldCount());
+		return slotManager.findTupleIndex(tuple, frameTuple, cmp, null, null);
+	}
 
-    @Override
-    public boolean intersect(ITupleReference tuple, int tupleIndex, MultiComparator cmp) {
-        frameTuple.setFieldCount(cmp.getFieldCount());
-        frameTuple.resetByTupleIndex(this, tupleIndex);
-        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), frameTuple.getFieldData(j), frameTuple.getFieldStart(j),
-                    frameTuple.getFieldLength(j));
-            if (c > 0) {
-                return false;
-            }
-            c = cmp.getComparators()[i].compare(tuple.getFieldData(j), tuple.getFieldStart(j), tuple.getFieldLength(j),
-                    frameTuple.getFieldData(i), frameTuple.getFieldStart(i), frameTuple.getFieldLength(i));
+	@Override
+	public boolean intersect(ITupleReference tuple, int tupleIndex,
+			MultiComparator cmp) {
+		frameTuple.setFieldCount(cmp.getFieldCount());
+		frameTuple.resetByTupleIndex(this, tupleIndex);
+		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),
+					frameTuple.getFieldData(j), frameTuple.getFieldStart(j),
+					frameTuple.getFieldLength(j));
+			if (c > 0) {
+				return false;
+			}
+			c = cmp.getComparators()[i].compare(tuple.getFieldData(j),
+					tuple.getFieldStart(j), tuple.getFieldLength(j),
+					frameTuple.getFieldData(i), frameTuple.getFieldStart(i),
+					frameTuple.getFieldLength(i));
 
-            if (c < 0) {
-                return false;
-            }
-        }
-        return true;
-    }
+			if (c < 0) {
+				return false;
+			}
+		}
+		return true;
+	}
 
-    @Override
-    public int split(ITreeIndexFrame rightFrame, ITupleReference tuple, MultiComparator cmp, ISplitKey splitKey)
-            throws Exception {
+	@Override
+	public int split(ITreeIndexFrame rightFrame, ITupleReference tuple,
+			MultiComparator cmp, ISplitKey splitKey) throws Exception {
 
-        rightFrame.setPageTupleFieldCount(cmp.getFieldCount());
-        frameTuple.setFieldCount(cmp.getFieldCount());
+		rightFrame.setPageTupleFieldCount(cmp.getFieldCount());
+		frameTuple.setFieldCount(cmp.getFieldCount());
 
-        RTreeSplitKey rTreeSplitKey = ((RTreeSplitKey) splitKey);
-        RTreeTypeAwareTupleWriter rTreeTupleWriterLeftFrame = ((RTreeTypeAwareTupleWriter) tupleWriter);
-        RTreeTypeAwareTupleWriter rTreeTupleWriterRightFrame = ((RTreeTypeAwareTupleWriter) rightFrame.getTupleWriter());
+		RTreeSplitKey rTreeSplitKey = ((RTreeSplitKey) splitKey);
+		RTreeTypeAwareTupleWriter rTreeTupleWriterLeftFrame = ((RTreeTypeAwareTupleWriter) tupleWriter);
+		RTreeTypeAwareTupleWriter rTreeTupleWriterRightFrame = ((RTreeTypeAwareTupleWriter) rightFrame
+				.getTupleWriter());
 
-        // calculations are based on the R*-tree paper
-        int m = (int) Math.floor((getTupleCount() + 1) * splitFactor);
-        int splitDistribution = getTupleCount() - (2 * m) + 2;
+		// calculations are based on the R*-tree paper
+		int m = (int) Math.floor((getTupleCount() + 1) * splitFactor);
+		int splitDistribution = getTupleCount() - (2 * m) + 2;
 
-        // to calculate the minimum margin in order to pick the split axis
-        double minMargin = Double.MAX_VALUE;
-        int splitAxis = 0, sortOrder = 0;
+		// to calculate the minimum margin in order to pick the split axis
+		double minMargin = Double.MAX_VALUE;
+		int splitAxis = 0, sortOrder = 0;
 
-        int maxFieldPos = cmp.getKeyFieldCount() / 2;
-        for (int i = 0; i < maxFieldPos; i++) {
-            int j = maxFieldPos + i;
-            for (int k = 0; k < getTupleCount(); ++k) {
+		int maxFieldPos = cmp.getKeyFieldCount() / 2;
+		for (int i = 0; i < maxFieldPos; i++) {
+			int j = maxFieldPos + i;
+			for (int k = 0; k < getTupleCount(); ++k) {
 
-                frameTuple.resetByTupleIndex(this, k);
+				frameTuple.resetByTupleIndex(this, k);
 
-                double LowerKey = DoubleSerializerDeserializer.getDouble(frameTuple.getFieldData(i),
-                        frameTuple.getFieldStart(i));
-                double UpperKey = DoubleSerializerDeserializer.getDouble(frameTuple.getFieldData(j),
-                        frameTuple.getFieldStart(j));
+				double LowerKey = recDescSers[i]
+						.getValue(frameTuple.getFieldData(i),
+								frameTuple.getFieldStart(i));
+				double UpperKey = recDescSers[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));
+				tupleEntries1.add(k, LowerKey);
+				tupleEntries2.add(k, UpperKey);
+			}
+			double LowerKey = recDescSers[i].getValue(tuple.getFieldData(i),
+					tuple.getFieldStart(i));
+			double UpperKey = recDescSers[j].getValue(tuple.getFieldData(j),
+					tuple.getFieldStart(j));
 
-            tupleEntries1.add(-1, LowerKey);
-            tupleEntries2.add(-1, UpperKey);
+			tupleEntries1.add(-1, LowerKey);
+			tupleEntries2.add(-1, UpperKey);
 
-            tupleEntries1.sort(EntriesOrder.ASCENDING, getTupleCount() + 1);
-            tupleEntries2.sort(EntriesOrder.ASCENDING, getTupleCount() + 1);
+			tupleEntries1.sort(EntriesOrder.ASCENDING, getTupleCount() + 1);
+			tupleEntries2.sort(EntriesOrder.ASCENDING, getTupleCount() + 1);
 
-            double lowerMargin = 0.0, upperMargin = 0.0;
-            // generate distribution
-            for (int k = 1; k <= splitDistribution; ++k) {
-                int d = m - 1 + k;
+			double lowerMargin = 0.0, upperMargin = 0.0;
+			// generate distribution
+			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);
+				generateDist(tuple, tupleEntries2, rec[1], 0, d);
+				generateDist(tuple, tupleEntries1, rec[2], d,
+						getTupleCount() + 1);
+				generateDist(tuple, tupleEntries2, rec[3], d,
+						getTupleCount() + 1);
 
-                // calculate the margin of the distributions
-                lowerMargin += rec[0].margin() + rec[2].margin();
-                upperMargin += rec[1].margin() + rec[3].margin();
-            }
-            double margin = Math.min(lowerMargin, upperMargin);
+				// calculate the margin of the distributions
+				lowerMargin += rec[0].margin() + rec[2].margin();
+				upperMargin += rec[1].margin() + rec[3].margin();
+			}
+			double margin = Math.min(lowerMargin, upperMargin);
 
-            // store minimum margin as split axis
-            if (margin < minMargin) {
-                minMargin = margin;
-                splitAxis = i;
-                sortOrder = (lowerMargin < upperMargin) ? 0 : 2;
-            }
+			// store minimum margin as split axis
+			if (margin < minMargin) {
+				minMargin = margin;
+				splitAxis = i;
+				sortOrder = (lowerMargin < upperMargin) ? 0 : 2;
+			}
 
-            tupleEntries1.clear();
-            tupleEntries2.clear();
-        }
+			tupleEntries1.clear();
+			tupleEntries2.clear();
+		}
 
-        for (int i = 0; i < getTupleCount(); ++i) {
-            frameTuple.resetByTupleIndex(this, i);
-            double key = DoubleSerializerDeserializer.getDouble(frameTuple.getFieldData(splitAxis + sortOrder),
-                    frameTuple.getFieldStart(splitAxis + sortOrder));
-            tupleEntries1.add(i, key);
-        }
-        double key = DoubleSerializerDeserializer.getDouble(tuple.getFieldData(splitAxis + sortOrder),
-                tuple.getFieldStart(splitAxis + sortOrder));
-        tupleEntries1.add(-1, key);
-        tupleEntries1.sort(EntriesOrder.ASCENDING, getTupleCount() + 1);
+		for (int i = 0; i < getTupleCount(); ++i) {
+			frameTuple.resetByTupleIndex(this, i);
+			double key = recDescSers[splitAxis + sortOrder].getValue(
+					frameTuple.getFieldData(splitAxis + sortOrder),
+					frameTuple.getFieldStart(splitAxis + sortOrder));
+			tupleEntries1.add(i, key);
+		}
+		double key = recDescSers[splitAxis + sortOrder].getValue(
+				tuple.getFieldData(splitAxis + sortOrder),
+				tuple.getFieldStart(splitAxis + sortOrder));
+		tupleEntries1.add(-1, key);
+		tupleEntries1.sort(EntriesOrder.ASCENDING, getTupleCount() + 1);
 
-        double minArea = Double.MAX_VALUE;
-        double minOverlap = Double.MAX_VALUE;
-        int splitPoint = 0;
-        for (int i = 1; i <= splitDistribution; ++i) {
-            int d = m - 1 + i;
+		double minArea = Double.MAX_VALUE;
+		double minOverlap = Double.MAX_VALUE;
+		int splitPoint = 0;
+		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);
+			generateDist(tuple, tupleEntries1, rec[2], d, getTupleCount() + 1);
 
-            double overlap = rec[0].overlappedArea(rec[2]);
-            if (overlap < minOverlap) {
-                splitPoint = d;
-                minOverlap = overlap;
-                minArea = rec[0].area() + rec[2].area();
-            } else if (overlap == minOverlap) {
-                double area = rec[0].area() + rec[2].area();
-                if (area < minArea) {
-                    splitPoint = d;
-                    minArea = area;
-                }
-            }
-        }
-        int startIndex, endIndex;
-        if (splitPoint < (getTupleCount() + 1) / 2) {
-            startIndex = 0;
-            endIndex = splitPoint;
-        } else {
-            startIndex = splitPoint;
-            endIndex = (getTupleCount() + 1);
-        }
-        boolean tupleInserted = false;
-        int totalBytes = 0, numOfDeletedTuples = 0;
-        for (int i = startIndex; i < endIndex; i++) {
-            if (tupleEntries1.get(i).getTupleIndex() != -1) {
-                frameTuple.resetByTupleIndex(this, tupleEntries1.get(i).getTupleIndex());
-                rightFrame.insert(frameTuple, cmp, -1);
-                ((UnorderedSlotManager) slotManager).modifySlot(
-                        slotManager.getSlotOff(tupleEntries1.get(i).getTupleIndex()), -1);
-                totalBytes += tupleWriter.bytesRequired(frameTuple);
-                numOfDeletedTuples++;
-            } else {
-                rightFrame.insert(tuple, cmp, -1);
-                tupleInserted = true;
-            }
-        }
+			double overlap = rec[0].overlappedArea(rec[2]);
+			if (overlap < minOverlap) {
+				splitPoint = d;
+				minOverlap = overlap;
+				minArea = rec[0].area() + rec[2].area();
+			} else if (overlap == minOverlap) {
+				double area = rec[0].area() + rec[2].area();
+				if (area < minArea) {
+					splitPoint = d;
+					minArea = area;
+				}
+			}
+		}
+		int startIndex, endIndex;
+		if (splitPoint < (getTupleCount() + 1) / 2) {
+			startIndex = 0;
+			endIndex = splitPoint;
+		} else {
+			startIndex = splitPoint;
+			endIndex = (getTupleCount() + 1);
+		}
+		boolean tupleInserted = false;
+		int totalBytes = 0, numOfDeletedTuples = 0;
+		for (int i = startIndex; i < endIndex; i++) {
+			if (tupleEntries1.get(i).getTupleIndex() != -1) {
+				frameTuple.resetByTupleIndex(this, tupleEntries1.get(i)
+						.getTupleIndex());
+				rightFrame.insert(frameTuple, cmp, -1);
+				((UnorderedSlotManager) slotManager).modifySlot(slotManager
+						.getSlotOff(tupleEntries1.get(i).getTupleIndex()), -1);
+				totalBytes += tupleWriter.bytesRequired(frameTuple);
+				numOfDeletedTuples++;
+			} else {
+				rightFrame.insert(tuple, cmp, -1);
+				tupleInserted = true;
+			}
+		}
 
-        ((UnorderedSlotManager) slotManager).deleteEmptySlots();
+		((UnorderedSlotManager) slotManager).deleteEmptySlots();
 
-        // maintain space information
-        buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) + totalBytes
-                + (slotManager.getSlotSize() * numOfDeletedTuples));
+		// maintain space information
+		buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff)
+				+ totalBytes + (slotManager.getSlotSize() * numOfDeletedTuples));
 
-        // compact both pages
-        rightFrame.compact(cmp);
-        compact(cmp);
+		// compact both pages
+		rightFrame.compact(cmp);
+		compact(cmp);
 
-        if (!tupleInserted) {
-            insert(tuple, cmp, -1);
-        }
+		if (!tupleInserted) {
+			insert(tuple, cmp, -1);
+		}
 
-        int tupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff());
-        frameTuple.resetByTupleOffset(buf, tupleOff);
-        int splitKeySize = tupleWriter.bytesRequired(frameTuple, 0, cmp.getKeyFieldCount());
+		int tupleOff = slotManager.getTupleOff(slotManager.getSlotEndOff());
+		frameTuple.resetByTupleOffset(buf, tupleOff);
+		int splitKeySize = tupleWriter.bytesRequired(frameTuple, 0,
+				cmp.getKeyFieldCount());
 
-        splitKey.initData(splitKeySize);
-        this.adjustMBR(tuples, cmp);
-        rTreeTupleWriterLeftFrame.writeTupleFields(tuples, 0, rTreeSplitKey.getLeftPageBuffer(), 0);
-        rTreeSplitKey.getLeftTuple().resetByTupleOffset(rTreeSplitKey.getLeftPageBuffer(), 0);
+		splitKey.initData(splitKeySize);
+		this.adjustMBR(tuples, cmp);
+		rTreeTupleWriterLeftFrame.writeTupleFields(tuples, 0,
+				rTreeSplitKey.getLeftPageBuffer(), 0);
+		rTreeSplitKey.getLeftTuple().resetByTupleOffset(
+				rTreeSplitKey.getLeftPageBuffer(), 0);
 
-        ((IRTreeFrame) rightFrame).adjustMBR(((RTreeNSMFrame) rightFrame).getTuples(), cmp);
-        rTreeTupleWriterRightFrame.writeTupleFields(((RTreeNSMFrame) rightFrame).getTuples(), 0,
-                rTreeSplitKey.getRightPageBuffer(), 0);
-        rTreeSplitKey.getRightTuple().resetByTupleOffset(rTreeSplitKey.getRightPageBuffer(), 0);
+		((IRTreeFrame) rightFrame).adjustMBR(
+				((RTreeNSMFrame) rightFrame).getTuples(), cmp);
+		rTreeTupleWriterRightFrame.writeTupleFields(
+				((RTreeNSMFrame) rightFrame).getTuples(), 0,
+				rTreeSplitKey.getRightPageBuffer(), 0);
+		rTreeSplitKey.getRightTuple().resetByTupleOffset(
+				rTreeSplitKey.getRightPageBuffer(), 0);
 
-        tupleEntries1.clear();
-        tupleEntries2.clear();
-        return 0;
-    }
+		tupleEntries1.clear();
+		tupleEntries2.clear();
+		return 0;
+	}
 
-    @Override
-    public void insert(ITupleReference tuple, MultiComparator cmp, int tupleIndex) throws Exception {
-        frameTuple.setFieldCount(cmp.getFieldCount());
-        slotManager.insertSlot(-1, buf.getInt(freeSpaceOff));
-        int bytesWritten = tupleWriter.writeTuple(tuple, buf, buf.getInt(freeSpaceOff));
+	@Override
+	public void insert(ITupleReference tuple, MultiComparator cmp,
+			int tupleIndex) throws Exception {
+		frameTuple.setFieldCount(cmp.getFieldCount());
+		slotManager.insertSlot(-1, buf.getInt(freeSpaceOff));
+		int bytesWritten = tupleWriter.writeTuple(tuple, buf,
+				buf.getInt(freeSpaceOff));
 
-        buf.putInt(tupleCountOff, buf.getInt(tupleCountOff) + 1);
-        buf.putInt(freeSpaceOff, buf.getInt(freeSpaceOff) + bytesWritten);
-        buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) - bytesWritten - slotManager.getSlotSize());
-    }
+		buf.putInt(tupleCountOff, buf.getInt(tupleCountOff) + 1);
+		buf.putInt(freeSpaceOff, buf.getInt(freeSpaceOff) + bytesWritten);
+		buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff)
+				- bytesWritten - slotManager.getSlotSize());
+	}
 
-    @Override
-    public void delete(int tupleIndex, MultiComparator cmp) throws Exception {
-        frameTuple.setFieldCount(cmp.getFieldCount());
-        int slotOff = slotManager.getSlotOff(tupleIndex);
+	@Override
+	public void delete(int tupleIndex, MultiComparator cmp) throws Exception {
+		frameTuple.setFieldCount(cmp.getFieldCount());
+		int slotOff = slotManager.getSlotOff(tupleIndex);
 
-        int tupleOff = slotManager.getTupleOff(slotOff);
-        frameTuple.resetByTupleOffset(buf, tupleOff);
-        int tupleSize = tupleWriter.bytesRequired(frameTuple);
+		int tupleOff = slotManager.getTupleOff(slotOff);
+		frameTuple.resetByTupleOffset(buf, tupleOff);
+		int tupleSize = tupleWriter.bytesRequired(frameTuple);
 
-        // perform deletion (we just do a memcpy to overwrite the slot)
-        int slotStartOff = slotManager.getSlotEndOff();
-        int length = slotOff - slotStartOff;
-        System.arraycopy(buf.array(), slotStartOff, buf.array(), slotStartOff + slotManager.getSlotSize(), length);
+		// perform deletion (we just do a memcpy to overwrite the slot)
+		int slotStartOff = slotManager.getSlotEndOff();
+		int length = slotOff - slotStartOff;
+		System.arraycopy(buf.array(), slotStartOff, buf.array(), slotStartOff
+				+ slotManager.getSlotSize(), length);
 
-        // maintain space information
-        buf.putInt(tupleCountOff, buf.getInt(tupleCountOff) - 1);
-        buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) + tupleSize + slotManager.getSlotSize());
-    }
+		// maintain space information
+		buf.putInt(tupleCountOff, buf.getInt(tupleCountOff) - 1);
+		buf.putInt(totalFreeSpaceOff, buf.getInt(totalFreeSpaceOff) + tupleSize
+				+ slotManager.getSlotSize());
+	}
 
-    @Override
-    public void adjustMBR(ITreeIndexTupleReference[] tuples, MultiComparator cmp) {
-        for (int i = 0; i < tuples.length; i++) {
-            tuples[i].setFieldCount(cmp.getFieldCount());
-            tuples[i].resetByTupleIndex(this, 0);
-        }
+	@Override
+	public void adjustMBR(ITreeIndexTupleReference[] tuples, MultiComparator cmp) {
+		for (int i = 0; i < tuples.length; i++) {
+			tuples[i].setFieldCount(cmp.getFieldCount());
+			tuples[i].resetByTupleIndex(this, 0);
+		}
 
-        adjustMBRImpl(tuples, cmp);
-    }
-}
+		adjustMBRImpl(tuples, cmp);
+	}
+}
\ No newline at end of file
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrameFactory.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrameFactory.java
index 7da7f26..a470623 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrameFactory.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/RTreeNSMLeafFrameFactory.java
@@ -15,23 +15,29 @@
 
 package edu.uci.ics.hyracks.storage.am.rtree.frames;
 
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleWriterFactory;
 import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeLeafFrame;
 
 public class RTreeNSMLeafFrameFactory implements ITreeIndexFrameFactory {
 
-    private static final long serialVersionUID = 1L;
-    private ITreeIndexTupleWriterFactory tupleWriterFactory;
-    private int keyFieldCount;
+	private static final long serialVersionUID = 1L;
+	private ITreeIndexTupleWriterFactory tupleWriterFactory;
+	private ISerializerDeserializer[] recDescSers;
+	private int keyFieldCount;
 
-    public RTreeNSMLeafFrameFactory(ITreeIndexTupleWriterFactory tupleWriterFactory, int keyFieldCount) {
-        this.tupleWriterFactory = tupleWriterFactory;
-        this.keyFieldCount = keyFieldCount;
-    }
+	public RTreeNSMLeafFrameFactory(
+			ITreeIndexTupleWriterFactory tupleWriterFactory,
+			ISerializerDeserializer[] recDescSers, int keyFieldCount) {
+		this.tupleWriterFactory = tupleWriterFactory;
+		this.recDescSers = recDescSers;
+		this.keyFieldCount = keyFieldCount;
+	}
 
-    @Override
-    public IRTreeLeafFrame createFrame() {
-        return new RTreeNSMLeafFrame(tupleWriterFactory.createTupleWriter(), keyFieldCount);
-    }
-}
+	@Override
+	public IRTreeLeafFrame createFrame() {
+		return new RTreeNSMLeafFrame(tupleWriterFactory.createTupleWriter(),
+				recDescSers, keyFieldCount);
+	}
+}
\ No newline at end of file
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/DoubleGenericPrimitiveSerializerDeserializer.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/DoubleGenericPrimitiveSerializerDeserializer.java
new file mode 100644
index 0000000..c24eef4
--- /dev/null
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/DoubleGenericPrimitiveSerializerDeserializer.java
@@ -0,0 +1,34 @@
+/*
+ * 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.rtree.api.IGenericPrimitiveSerializerDeserializer;
+
+public class DoubleGenericPrimitiveSerializerDeserializer extends
+		DoubleSerializerDeserializer implements
+		IGenericPrimitiveSerializerDeserializer<Double> {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final DoubleGenericPrimitiveSerializerDeserializer INSTANCE = new DoubleGenericPrimitiveSerializerDeserializer();
+
+	@Override
+	public double getValue(byte[] bytes, int offset) {
+		return DoubleSerializerDeserializer.getDouble(bytes, offset);
+	}
+
+}
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/FloatGenericPrimitiveSerializerDeserializer.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/FloatGenericPrimitiveSerializerDeserializer.java
new file mode 100644
index 0000000..4a2fac6
--- /dev/null
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/FloatGenericPrimitiveSerializerDeserializer.java
@@ -0,0 +1,34 @@
+/*
+ * 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.rtree.api.IGenericPrimitiveSerializerDeserializer;
+
+public class FloatGenericPrimitiveSerializerDeserializer extends
+		FloatSerializerDeserializer implements
+		IGenericPrimitiveSerializerDeserializer<Float> {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final FloatGenericPrimitiveSerializerDeserializer INSTANCE = new FloatGenericPrimitiveSerializerDeserializer();
+
+	@Override
+	public double getValue(byte[] bytes, int offset) {
+		return FloatSerializerDeserializer.getFloat(bytes, offset);
+	}
+
+}
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/IntegerGenericPrimitiveSerializerDeserializer.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/IntegerGenericPrimitiveSerializerDeserializer.java
new file mode 100644
index 0000000..835d911
--- /dev/null
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/IntegerGenericPrimitiveSerializerDeserializer.java
@@ -0,0 +1,34 @@
+/*
+ * 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.rtree.api.IGenericPrimitiveSerializerDeserializer;
+
+public class IntegerGenericPrimitiveSerializerDeserializer extends
+		IntegerSerializerDeserializer implements
+		IGenericPrimitiveSerializerDeserializer<Integer> {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final IntegerGenericPrimitiveSerializerDeserializer INSTANCE = new IntegerGenericPrimitiveSerializerDeserializer();
+
+	@Override
+	public double getValue(byte[] bytes, int offset) {
+		return IntegerSerializerDeserializer.getInt(bytes, offset);
+	}
+
+}
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/Rectangle.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/Rectangle.java
index 1fb86a9..ef78a9b 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/Rectangle.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/Rectangle.java
@@ -16,121 +16,133 @@
 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.rtree.api.IGenericPrimitiveSerializerDeserializer;
 
 public class Rectangle {
-    private int dim;
-    private double[] low;
-    private double[] high;
+	private int dim;
+	private double[] low;
+	private double[] high;
+	private IGenericPrimitiveSerializerDeserializer[] recDescSers;
 
-    public Rectangle(int dim) {
-        this.dim = dim;
-        low = new double[this.dim];
-        high = new double[this.dim];
-    }
+	public Rectangle(int dim,
+			IGenericPrimitiveSerializerDeserializer[] recDescSers) {
+		this.dim = dim;
+		low = new double[this.dim];
+		high = new double[this.dim];
+		this.recDescSers = recDescSers;
+	}
 
-    public int getDim() {
-        return dim;
-    }
+	public int getDim() {
+		return dim;
+	}
 
-    public double getLow(int i) {
-        return low[i];
-    }
+	public double getLow(int i) {
+		return low[i];
+	}
 
-    public double getHigh(int i) {
-        return high[i];
-    }
+	public double getHigh(int i) {
+		return high[i];
+	}
 
-    public void setLow(int i, double value) {
-        low[i] = value;
-    }
+	public void setLow(int i, double value) {
+		low[i] = value;
+	}
 
-    public void setHigh(int i, double value) {
-        high[i] = value;
-    }
+	public void setHigh(int i, double value) {
+		high[i] = value;
+	}
 
-    public void set(ITupleReference tuple) {
-        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)));
-        }
-    }
+	public void set(ITupleReference tuple) {
+		for (int i = 0; i < getDim(); i++) {
+			int j = i + getDim();
+			setLow(i,
+					recDescSers[i].getValue(tuple.getFieldData(i),
+							tuple.getFieldStart(i)));
+			setHigh(i,
+					recDescSers[j].getValue(tuple.getFieldData(j),
+							tuple.getFieldStart(j)));
+		}
+	}
 
-    public void enlarge(ITupleReference tupleToBeInserted) {
-        for (int i = 0; i < getDim(); i++) {
-            int j = getDim() + i;
-            double low = DoubleSerializerDeserializer.getDouble(tupleToBeInserted.getFieldData(i),
-                    tupleToBeInserted.getFieldStart(i));
-            if (getLow(i) > low) {
-                setLow(i, low);
-            }
-            double high = DoubleSerializerDeserializer.getDouble(tupleToBeInserted.getFieldData(j),
-                    tupleToBeInserted.getFieldStart(j));
-            if (getHigh(i) < high) {
-                setHigh(i, high);
-            }
-        }
-    }
+	public void enlarge(ITupleReference tupleToBeInserted) {
+		for (int i = 0; i < getDim(); i++) {
+			int j = getDim() + i;
+			double low = recDescSers[i].getValue(
+					tupleToBeInserted.getFieldData(i),
+					tupleToBeInserted.getFieldStart(i));
+			if (getLow(i) > low) {
+				setLow(i, low);
+			}
+			double high = recDescSers[j].getValue(
+					tupleToBeInserted.getFieldData(j),
+					tupleToBeInserted.getFieldStart(j));
+			if (getHigh(i) < high) {
+				setHigh(i, high);
+			}
+		}
+	}
 
-    public double margin() {
-        double margin = 0.0;
-        double mul = Math.pow(2, (double) getDim() - 1.0);
-        for (int i = 0; i < getDim(); i++) {
-            margin += (getHigh(i) - getLow(i)) * mul;
-        }
-        return margin;
-    }
+	public double margin() {
+		double margin = 0.0;
+		double mul = Math.pow(2, (double) getDim() - 1.0);
+		for (int i = 0; i < getDim(); i++) {
+			margin += (getHigh(i) - getLow(i)) * mul;
+		}
+		return margin;
+	}
 
-    public double overlappedArea(ITupleReference tuple) {
-        double area = 1.0;
-        double f1, f2;
+	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;
-    }
+		for (int i = 0; i < getDim(); i++) {
+			int j = getDim() + i;
+			double low = recDescSers[i].getValue(tuple.getFieldData(i),
+					tuple.getFieldStart(i));
+			double high = recDescSers[j].getValue(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;
+	public double overlappedArea(Rectangle rec) {
+		double area = 1.0;
+		double f1, f2;
 
-        for (int i = 0; i < getDim(); i++) {
-            if (getLow(i) > rec.getHigh(i) || getHigh(i) < rec.getLow(i)) {
-                return 0.0;
-            }
+		for (int i = 0; i < getDim(); i++) {
+			if (getLow(i) > rec.getHigh(i) || getHigh(i) < rec.getLow(i)) {
+				return 0.0;
+			}
+			f1 = Math.max(getLow(i), rec.getLow(i));
+			f2 = Math.min(getHigh(i), rec.getHigh(i));
+			area *= f2 - f1;
+		}
+		return area;
+	}
 
-            f1 = Math.max(getLow(i), rec.getLow(i));
-            f2 = Math.min(getHigh(i), rec.getHigh(i));
-            area *= f2 - f1;
-        }
-        return area;
-    }
+	public double area(ITupleReference tuple) {
+		double area = 1.0;
+		for (int i = 0; i < getDim(); i++) {
+			int j = getDim() + i;
+			area *= recDescSers[j].getValue(tuple.getFieldData(j),
+					tuple.getFieldStart(j))
+					- recDescSers[i].getValue(tuple.getFieldData(i),
+							tuple.getFieldStart(i));
+		}
+		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++) {
-            area *= getHigh(i) - getLow(i);
-        }
-        return area;
-    }
-}
+	public double area() {
+		double area = 1.0;
+		for (int i = 0; i < getDim(); i++) {
+			area *= getHigh(i) - getLow(i);
+		}
+		return area;
+	}
+}
\ No newline at end of file
diff --git a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeTest.java b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeTest.java
index 514b81f..630c77a 100644
--- a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeTest.java
+++ b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeTest.java
@@ -36,6 +36,7 @@
 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;
@@ -63,508 +64,772 @@
 
 public class RTreeTest extends AbstractRTreeTest {
 
-    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 IHyracksTaskContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
+	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 IHyracksTaskContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
 
-    // create an R-tree of two dimensions
-    // fill the R-tree with random values using insertions
-    // perform ordered scan
-    @Test
-    public void test01() throws Exception {
+	// create an R-tree of two dimensions
+	// fill the R-tree with random values using insertions
+	// perform ordered scan
+	@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);
+		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] = DoubleBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        cmps[1] = cmps[0];
-        cmps[2] = cmps[0];
-        cmps[3] = cmps[0];
+		// declare keys
+		int keyFieldCount = 4;
+		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+		cmps[0] = DoubleBinaryComparatorFactory.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(8);
-        typeTraits[1] = new TypeTrait(8);
-        typeTraits[2] = new TypeTrait(8);
-        typeTraits[3] = new TypeTrait(8);
-        typeTraits[4] = new TypeTrait(8);
-        typeTraits[5] = new TypeTrait(4);
-        typeTraits[6] = new TypeTrait(8);
+		// declare tuple fields
+		int fieldCount = 7;
+		ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
+		typeTraits[0] = new TypeTrait(8);
+		typeTraits[1] = new TypeTrait(8);
+		typeTraits[2] = new TypeTrait(8);
+		typeTraits[3] = new TypeTrait(8);
+		typeTraits[4] = new TypeTrait(8);
+		typeTraits[5] = new TypeTrait(4);
+		typeTraits[6] = new TypeTrait(8);
 
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-        RTreeTypeAwareTupleWriterFactory tupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(typeTraits);
+		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();
+		@SuppressWarnings("rawtypes")
+		ISerializerDeserializer[] recDescSers = {
+				DoubleSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE };
 
-        IRTreeFrame interiorFrame = (IRTreeFrame) interiorFrameFactory.createFrame();
-        IRTreeFrame leafFrame = (IRTreeFrame) leafFrameFactory.createFrame();
-        IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, fileId, 0, metaFrameFactory);
+		ITreeIndexFrameFactory interiorFrameFactory = new RTreeNSMInteriorFrameFactory(
+				tupleWriterFactory, recDescSers, keyFieldCount);
+		ITreeIndexFrameFactory leafFrameFactory = new RTreeNSMLeafFrameFactory(
+				tupleWriterFactory, recDescSers, keyFieldCount);
+		ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
+		ITreeIndexMetaDataFrame metaFrame = metaFrameFactory.createFrame();
 
-        RTree rtree = new RTree(bufferCache, freePageManager, interiorFrameFactory, leafFrameFactory, cmp);
-        rtree.create(fileId, leafFrame, metaFrame);
-        rtree.open(fileId);
+		IRTreeFrame interiorFrame = (IRTreeFrame) interiorFrameFactory
+				.createFrame();
+		IRTreeFrame leafFrame = (IRTreeFrame) leafFrameFactory.createFrame();
+		IFreePageManager freePageManager = new LinkedListFreePageManager(
+				bufferCache, fileId, 0, metaFrameFactory);
 
-        ByteBuffer hyracksFrame = ctx.allocateFrame();
-        FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
-        DataOutput dos = tb.getDataOutput();
+		RTree rtree = new RTree(bufferCache, freePageManager,
+				interiorFrameFactory, leafFrameFactory, cmp);
+		rtree.create(fileId, leafFrame, metaFrame);
+		rtree.open(fileId);
 
-        @SuppressWarnings("rawtypes")
-        ISerializerDeserializer[] recDescSers = { DoubleSerializerDeserializer.INSTANCE,
-                DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
-                DoubleSerializerDeserializer.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();
+		ByteBuffer hyracksFrame = ctx.allocateFrame();
+		FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+		DataOutput dos = tb.getDataOutput();
 
-        RTreeOpContext insertOpCtx = rtree.createOpContext(IndexOp.INSERT, leafFrame, interiorFrame, metaFrame);
+		RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
+		IFrameTupleAccessor accessor = new FrameTupleAccessor(
+				ctx.getFrameSize(), recDesc);
+		accessor.reset(hyracksFrame);
+		FrameTupleReference tuple = new FrameTupleReference();
 
-        Random rnd = new Random();
-        rnd.setSeed(50);
+		RTreeOpContext insertOpCtx = rtree.createOpContext(IndexOp.INSERT,
+				leafFrame, interiorFrame, metaFrame);
 
-        Random rnd2 = new Random();
-        rnd2.setSeed(50);
-        for (int i = 0; i < 5000; i++) {
+		Random rnd = new Random();
+		rnd.setSeed(50);
 
-            double p1x = rnd.nextDouble();
-            double p1y = rnd.nextDouble();
-            double p2x = rnd.nextDouble();
-            double p2y = rnd.nextDouble();
+		Random rnd2 = new Random();
+		rnd2.setSeed(50);
+		for (int i = 0; i < 5000; i++) {
 
-            double pk1 = rnd2.nextDouble();
-            int pk2 = rnd2.nextInt();
-            double pk3 = rnd2.nextDouble();
+			double p1x = rnd.nextDouble();
+			double p1y = rnd.nextDouble();
+			double p2x = rnd.nextDouble();
+			double p2y = rnd.nextDouble();
 
-            tb.reset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1x, p2x), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1y, p2y), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1x, p2x), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.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();
+			double pk1 = rnd2.nextDouble();
+			int pk2 = rnd2.nextInt();
+			double pk3 = rnd2.nextDouble();
 
-            appender.reset(hyracksFrame, true);
-            appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
+			tb.reset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1x, p2x),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1y, p2y),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1x, p2x),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.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();
 
-            tuple.reset(accessor, 0);
+			appender.reset(hyracksFrame, true);
+			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0,
+					tb.getSize());
 
-            if (i % 1000 == 0) {
-                print("INSERTING " + i + " " + Math.min(p1x, p2x) + " " + Math.min(p1y, p2y) + " " + Math.max(p1x, p2x)
-                        + " " + Math.max(p1y, p2y) + "\n");
-            }
+			tuple.reset(accessor, 0);
 
-            try {
-                rtree.insert(tuple, insertOpCtx);
-            } catch (TreeIndexException e) {
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
+			if (i % 1000 == 0) {
+				print("INSERTING " + i + " " + Math.min(p1x, p2x) + " "
+						+ Math.min(p1y, p2y) + " " + Math.max(p1x, p2x) + " "
+						+ Math.max(p1y, p2y) + "\n");
+			}
 
-        // rtree.printTree(leafFrame, interiorFrame, recDescSers);
-        // System.err.println();
+			try {
+				rtree.insert(tuple, insertOpCtx);
+			} catch (TreeIndexException e) {
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
 
-        String rtreeStats = rtree.printStats();
-        print(rtreeStats);
+		// rtree.printTree(leafFrame, interiorFrame, recDescSers);
+		// System.err.println();
 
-        // 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();
-        }
+		String rtreeStats = rtree.printStats();
+		print(rtreeStats);
 
-        TreeIndexStatsGatherer statsGatherer = new TreeIndexStatsGatherer(bufferCache, freePageManager, fileId,
-                rtree.getRootPageId());
-        TreeIndexStats stats = statsGatherer.gatherStats(leafFrame, interiorFrame, metaFrame);
-        String string = stats.toString();
-        System.err.println(string);
+		// 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();
+		}
 
-        rtree.close();
-        bufferCache.closeFile(fileId);
-        bufferCache.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();
 
-    // create an R-tree of two dimensions
-    // fill the R-tree with random values using insertions
-    // and then delete all the tuples which result of an empty R-tree
-    @Test
-    public void test02() 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);
+	// create an R-tree of two dimensions
+	// fill the R-tree with random integer key values using insertions
+	// perform ordered scan
+	@Test
+	public void test02() throws Exception {
 
-        // declare keys
-        int keyFieldCount = 4;
-        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-        cmps[0] = DoubleBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        cmps[1] = cmps[0];
-        cmps[2] = cmps[0];
-        cmps[3] = cmps[0];
+		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 tuple fields
-        int fieldCount = 7;
-        ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
-        typeTraits[0] = new TypeTrait(8);
-        typeTraits[1] = new TypeTrait(8);
-        typeTraits[2] = new TypeTrait(8);
-        typeTraits[3] = new TypeTrait(8);
-        typeTraits[4] = new TypeTrait(8);
-        typeTraits[5] = new TypeTrait(4);
-        typeTraits[6] = new TypeTrait(8);
+		// 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];
 
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+		// 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);
 
-        RTreeTypeAwareTupleWriterFactory tupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(typeTraits);
+		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-        ITreeIndexFrameFactory interiorFrameFactory = new RTreeNSMInteriorFrameFactory(tupleWriterFactory,
-                keyFieldCount);
-        ITreeIndexFrameFactory leafFrameFactory = new RTreeNSMLeafFrameFactory(tupleWriterFactory, keyFieldCount);
-        ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
-        ITreeIndexMetaDataFrame metaFrame = metaFrameFactory.createFrame();
+		RTreeTypeAwareTupleWriterFactory tupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(
+				typeTraits);
+
+		@SuppressWarnings("rawtypes")
+		ISerializerDeserializer[] recDescSers = {
+				IntegerSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE };
+
+		ITreeIndexFrameFactory interiorFrameFactory = new RTreeNSMInteriorFrameFactory(
+				tupleWriterFactory, recDescSers, keyFieldCount);
+		ITreeIndexFrameFactory leafFrameFactory = new RTreeNSMLeafFrameFactory(
+				tupleWriterFactory, recDescSers, 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();
+
+		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();
+
+	}
+
+	// create an R-tree of two dimensions
+	// fill the R-tree with random values using insertions
+	// and then delete all the tuples which result of an empty R-tree
+	@Test
+	public void test03() 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] = DoubleBinaryComparatorFactory.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(8);
+		typeTraits[1] = new TypeTrait(8);
+		typeTraits[2] = new TypeTrait(8);
+		typeTraits[3] = new TypeTrait(8);
+		typeTraits[4] = new TypeTrait(8);
+		typeTraits[5] = new TypeTrait(4);
+		typeTraits[6] = new TypeTrait(8);
+
+		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+
+		RTreeTypeAwareTupleWriterFactory tupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(
+				typeTraits);
+
+		@SuppressWarnings("rawtypes")
+		ISerializerDeserializer[] recDescSers = {
+				DoubleSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE };
+		ITreeIndexFrameFactory interiorFrameFactory = new RTreeNSMInteriorFrameFactory(
+				tupleWriterFactory, recDescSers, keyFieldCount);
+		ITreeIndexFrameFactory leafFrameFactory = new RTreeNSMLeafFrameFactory(
+				tupleWriterFactory, recDescSers, 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);
+		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);
+		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();
+		ByteBuffer hyracksFrame = ctx.allocateFrame();
+		FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+		DataOutput dos = tb.getDataOutput();
 
-        @SuppressWarnings("rawtypes")
-        ISerializerDeserializer[] recDescSers = { DoubleSerializerDeserializer.INSTANCE,
-                DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
-                DoubleSerializerDeserializer.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();
+		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);
+		RTreeOpContext insertOpCtx = rtree.createOpContext(IndexOp.INSERT,
+				leafFrame, interiorFrame, metaFrame);
 
-        Random rnd = new Random();
-        rnd.setSeed(50);
+		Random rnd = new Random();
+		rnd.setSeed(50);
 
-        for (int i = 0; i < 5000; i++) {
+		for (int i = 0; i < 5000; i++) {
 
-            double p1x = rnd.nextDouble();
-            double p1y = rnd.nextDouble();
-            double p2x = rnd.nextDouble();
-            double p2y = rnd.nextDouble();
+			double p1x = rnd.nextDouble();
+			double p1y = rnd.nextDouble();
+			double p2x = rnd.nextDouble();
+			double p2y = rnd.nextDouble();
 
-            double pk1 = rnd.nextDouble();
-            int pk2 = rnd.nextInt();
-            double pk3 = rnd.nextDouble();
+			double pk1 = rnd.nextDouble();
+			int pk2 = rnd.nextInt();
+			double pk3 = rnd.nextDouble();
 
-            tb.reset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1x, p2x), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1y, p2y), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1x, p2x), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.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();
+			tb.reset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1x, p2x),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1y, p2y),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1x, p2x),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.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());
+			appender.reset(hyracksFrame, true);
+			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0,
+					tb.getSize());
 
-            tuple.reset(accessor, 0);
+			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");
-            }
+			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();
-            }
-        }
+			try {
+				rtree.insert(tuple, insertOpCtx);
+			} catch (TreeIndexException e) {
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
 
-        // rtree.printTree(leafFrame, interiorFrame, recDescSers);
-        // System.err.println();
+		// rtree.printTree(leafFrame, interiorFrame, recDescSers);
+		// System.err.println();
 
-        String rtreeStats = rtree.printStats();
-        print(rtreeStats);
+		String rtreeStats = rtree.printStats();
+		print(rtreeStats);
 
-        RTreeOpContext deleteOpCtx = rtree.createOpContext(IndexOp.DELETE, leafFrame, interiorFrame, metaFrame);
-        rnd.setSeed(50);
-        for (int i = 0; i < 5000; i++) {
+		RTreeOpContext deleteOpCtx = rtree.createOpContext(IndexOp.DELETE,
+				leafFrame, interiorFrame, metaFrame);
+		rnd.setSeed(50);
+		for (int i = 0; i < 5000; i++) {
 
-            double p1x = rnd.nextDouble();
-            double p1y = rnd.nextDouble();
-            double p2x = rnd.nextDouble();
-            double p2y = rnd.nextDouble();
+			double p1x = rnd.nextDouble();
+			double p1y = rnd.nextDouble();
+			double p2x = rnd.nextDouble();
+			double p2y = rnd.nextDouble();
 
-            double pk1 = rnd.nextDouble();
-            int pk2 = rnd.nextInt();
-            double pk3 = rnd.nextDouble();
+			double pk1 = rnd.nextDouble();
+			int pk2 = rnd.nextInt();
+			double pk3 = rnd.nextDouble();
 
-            tb.reset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1x, p2x), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1y, p2y), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1x, p2x), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.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();
+			tb.reset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1x, p2x),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1y, p2y),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1x, p2x),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.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());
+			appender.reset(hyracksFrame, true);
+			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0,
+					tb.getSize());
 
-            tuple.reset(accessor, 0);
+			tuple.reset(accessor, 0);
 
-            if (i % 1000 == 0) {
-                print("DELETING " + i + " " + Math.min(p1x, p2x) + " " + Math.min(p1y, p2y) + " " + Math.max(p1x, p2x)
-                        + " " + Math.max(p1y, p2y) + "\n");
-            }
+			if (i % 1000 == 0) {
+				print("DELETING " + i + " " + Math.min(p1x, p2x) + " "
+						+ Math.min(p1y, p2y) + " " + Math.max(p1x, p2x) + " "
+						+ Math.max(p1y, p2y) + "\n");
+			}
 
-            try {
-                rtree.delete(tuple, deleteOpCtx);
+			try {
+				rtree.delete(tuple, deleteOpCtx);
 
-            } catch (TreeIndexException e) {
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
+			} catch (TreeIndexException e) {
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
 
-        TreeIndexStatsGatherer statsGatherer = new TreeIndexStatsGatherer(bufferCache, freePageManager, fileId,
-                rtree.getRootPageId());
-        TreeIndexStats stats = statsGatherer.gatherStats(leafFrame, interiorFrame, metaFrame);
-        String string = stats.toString();
-        System.err.println(string);
+		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();
+		rtree.close();
+		bufferCache.closeFile(fileId);
+		bufferCache.close();
 
-    }
+	}
 
-    // create an R-tree of three dimensions
-    // fill the R-tree with random values using insertions
-    // perform ordered scan
-    @Test
-    public void test03() throws Exception {
+	// create an R-tree of three dimensions
+	// fill the R-tree with random 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);
+		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 = 6;
-        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-        cmps[0] = DoubleBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        cmps[1] = cmps[0];
-        cmps[2] = cmps[0];
-        cmps[3] = cmps[0];
-        cmps[4] = cmps[0];
-        cmps[5] = cmps[0];
+		// declare keys
+		int keyFieldCount = 6;
+		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+		cmps[0] = DoubleBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		cmps[1] = cmps[0];
+		cmps[2] = cmps[0];
+		cmps[3] = cmps[0];
+		cmps[4] = cmps[0];
+		cmps[5] = cmps[0];
 
-        // declare tuple fields
-        int fieldCount = 9;
-        ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
-        typeTraits[0] = new TypeTrait(8);
-        typeTraits[1] = new TypeTrait(8);
-        typeTraits[2] = new TypeTrait(8);
-        typeTraits[3] = new TypeTrait(8);
-        typeTraits[4] = new TypeTrait(8);
-        typeTraits[5] = new TypeTrait(8);
-        typeTraits[6] = new TypeTrait(8);
-        typeTraits[7] = new TypeTrait(4);
-        typeTraits[8] = new TypeTrait(8);
+		// declare tuple fields
+		int fieldCount = 9;
+		ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
+		typeTraits[0] = new TypeTrait(8);
+		typeTraits[1] = new TypeTrait(8);
+		typeTraits[2] = new TypeTrait(8);
+		typeTraits[3] = new TypeTrait(8);
+		typeTraits[4] = new TypeTrait(8);
+		typeTraits[5] = new TypeTrait(8);
+		typeTraits[6] = new TypeTrait(8);
+		typeTraits[7] = new TypeTrait(4);
+		typeTraits[8] = new TypeTrait(8);
 
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-        RTreeTypeAwareTupleWriterFactory tupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(typeTraits);
+		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();
+		@SuppressWarnings("rawtypes")
+		ISerializerDeserializer[] recDescSers = {
+				DoubleSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE };
+		ITreeIndexFrameFactory interiorFrameFactory = new RTreeNSMInteriorFrameFactory(
+				tupleWriterFactory, recDescSers, keyFieldCount);
+		ITreeIndexFrameFactory leafFrameFactory = new RTreeNSMLeafFrameFactory(
+				tupleWriterFactory, recDescSers, 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);
+		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);
+		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();
+		ByteBuffer hyracksFrame = ctx.allocateFrame();
+		FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+		DataOutput dos = tb.getDataOutput();
 
-        @SuppressWarnings("rawtypes")
-        ISerializerDeserializer[] recDescSers = { DoubleSerializerDeserializer.INSTANCE,
-                DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
-                DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
-                DoubleSerializerDeserializer.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();
+		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);
+		RTreeOpContext insertOpCtx = rtree.createOpContext(IndexOp.INSERT,
+				leafFrame, interiorFrame, metaFrame);
 
-        Random rnd = new Random();
-        rnd.setSeed(50);
+		Random rnd = new Random();
+		rnd.setSeed(50);
 
-        for (int i = 0; i < 5000; i++) {
+		for (int i = 0; i < 5000; i++) {
 
-            double p1x = rnd.nextDouble();
-            double p1y = rnd.nextDouble();
-            double p1z = rnd.nextDouble();
-            double p2x = rnd.nextDouble();
-            double p2y = rnd.nextDouble();
-            double p2z = rnd.nextDouble();
+			double p1x = rnd.nextDouble();
+			double p1y = rnd.nextDouble();
+			double p1z = rnd.nextDouble();
+			double p2x = rnd.nextDouble();
+			double p2y = rnd.nextDouble();
+			double p2z = rnd.nextDouble();
 
-            double pk1 = rnd.nextDouble();
-            int pk2 = rnd.nextInt();
-            double pk3 = rnd.nextDouble();
+			double pk1 = rnd.nextDouble();
+			int pk2 = rnd.nextInt();
+			double pk3 = rnd.nextDouble();
 
-            tb.reset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1x, p2x), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1y, p2y), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1z, p2z), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1x, p2x), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1y, p2y), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1z, p2z), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(pk1, dos);
-            tb.addFieldEndOffset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(pk2, dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(pk3, dos);
-            tb.addFieldEndOffset();
+			tb.reset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1x, p2x),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1y, p2y),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1z, p2z),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1x, p2x),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1y, p2y),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1z, p2z),
+					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());
+			appender.reset(hyracksFrame, true);
+			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0,
+					tb.getSize());
 
-            tuple.reset(accessor, 0);
+			tuple.reset(accessor, 0);
 
-            if (i % 1000 == 0) {
-                print("INSERTING " + i + " " + Math.min(p1x, p2x) + " " + Math.min(p1y, p2y) + " " + Math.min(p1z, p2z)
-                        + " " + " " + Math.max(p1x, p2x) + " " + Math.max(p1y, p2y) + " " + Math.max(p1z, p2z) + "\n");
-            }
+			if (i % 1000 == 0) {
+				print("INSERTING " + i + " " + Math.min(p1x, p2x) + " "
+						+ Math.min(p1y, p2y) + " " + Math.min(p1z, p2z) + " "
+						+ " " + Math.max(p1x, p2x) + " " + Math.max(p1y, p2y)
+						+ " " + Math.max(p1z, p2z) + "\n");
+			}
 
-            try {
-                rtree.insert(tuple, insertOpCtx);
-            } catch (TreeIndexException e) {
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
+			try {
+				rtree.insert(tuple, insertOpCtx);
+			} catch (TreeIndexException e) {
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
 
-        // rtree.printTree(leafFrame, interiorFrame, recDescSers);
-        // System.err.println();
+		// rtree.printTree(leafFrame, interiorFrame, recDescSers);
+		// System.err.println();
 
-        String rtreeStats = rtree.printStats();
-        print(rtreeStats);
+		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();
-        }
+		// 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);
+		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();
+		rtree.close();
+		bufferCache.closeFile(fileId);
+		bufferCache.close();
 
-    }
-}
+	}
+}
\ No newline at end of file
diff --git a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/SearchCursorTest.java b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/SearchCursorTest.java
index fb53b2a..09305be 100644
--- a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/SearchCursorTest.java
+++ b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/SearchCursorTest.java
@@ -67,174 +67,208 @@
 import edu.uci.ics.hyracks.test.support.TestUtils;
 
 public class SearchCursorTest extends AbstractRTreeTest {
-    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 IHyracksTaskContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
+	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 IHyracksTaskContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
 
-    // create an R-tree of two dimensions
-    // fill the R-tree with random values using insertions
-    // and then perform range search
-    @Test
-    public void searchCursorTest() throws Exception {
+	// create an R-tree of two dimensions
+	// fill the R-tree with random values using insertions
+	// and then perform range search
+	@Test
+	public void searchCursorTest() 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);
+		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] = DoubleBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        cmps[1] = cmps[0];
-        cmps[2] = cmps[0];
-        cmps[3] = cmps[0];
+		// declare keys
+		int keyFieldCount = 4;
+		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+		cmps[0] = DoubleBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		cmps[1] = cmps[0];
+		cmps[2] = cmps[0];
+		cmps[3] = cmps[0];
 
-        // declare tuple fields
-        int fieldCount = 5;
-        ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
-        typeTraits[0] = new TypeTrait(8);
-        typeTraits[1] = new TypeTrait(8);
-        typeTraits[2] = new TypeTrait(8);
-        typeTraits[3] = new TypeTrait(8);
-        typeTraits[4] = new TypeTrait(4);
+		// declare tuple fields
+		int fieldCount = 5;
+		ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
+		typeTraits[0] = new TypeTrait(8);
+		typeTraits[1] = new TypeTrait(8);
+		typeTraits[2] = new TypeTrait(8);
+		typeTraits[3] = new TypeTrait(8);
+		typeTraits[4] = new TypeTrait(4);
 
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-        RTreeTypeAwareTupleWriterFactory tupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(typeTraits);
+		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();
+		@SuppressWarnings("rawtypes")
+		ISerializerDeserializer[] recDescSers = {
+				DoubleSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				DoubleSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE };
 
-        IRTreeInteriorFrame interiorFrame = (IRTreeInteriorFrame) interiorFrameFactory.createFrame();
-        IRTreeLeafFrame leafFrame = (IRTreeLeafFrame) leafFrameFactory.createFrame();
-        IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, fileId, 0, metaFrameFactory);
+		ITreeIndexFrameFactory interiorFrameFactory = new RTreeNSMInteriorFrameFactory(
+				tupleWriterFactory, recDescSers, keyFieldCount);
+		ITreeIndexFrameFactory leafFrameFactory = new RTreeNSMLeafFrameFactory(
+				tupleWriterFactory, recDescSers, keyFieldCount);
+		ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
+		ITreeIndexMetaDataFrame metaFrame = metaFrameFactory.createFrame();
 
-        RTree rtree = new RTree(bufferCache, freePageManager, interiorFrameFactory, leafFrameFactory, cmp);
-        rtree.create(fileId, leafFrame, metaFrame);
-        rtree.open(fileId);
+		IRTreeInteriorFrame interiorFrame = (IRTreeInteriorFrame) interiorFrameFactory
+				.createFrame();
+		IRTreeLeafFrame leafFrame = (IRTreeLeafFrame) leafFrameFactory
+				.createFrame();
+		IFreePageManager freePageManager = new LinkedListFreePageManager(
+				bufferCache, fileId, 0, metaFrameFactory);
 
-        ByteBuffer hyracksFrame = ctx.allocateFrame();
-        FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
-        DataOutput dos = tb.getDataOutput();
+		RTree rtree = new RTree(bufferCache, freePageManager,
+				interiorFrameFactory, leafFrameFactory, cmp);
+		rtree.create(fileId, leafFrame, metaFrame);
+		rtree.open(fileId);
 
-        @SuppressWarnings("rawtypes")
-        ISerializerDeserializer[] recDescSers = { DoubleSerializerDeserializer.INSTANCE,
-                DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
-                DoubleSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
-        RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
-        IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(), recDesc);
-        accessor.reset(hyracksFrame);
-        FrameTupleReference tuple = new FrameTupleReference();
+		ByteBuffer hyracksFrame = ctx.allocateFrame();
+		FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+		DataOutput dos = tb.getDataOutput();
 
-        RTreeOpContext insertOpCtx = rtree.createOpContext(IndexOp.INSERT, leafFrame, interiorFrame, metaFrame);
+		RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
+		IFrameTupleAccessor accessor = new FrameTupleAccessor(
+				ctx.getFrameSize(), recDesc);
+		accessor.reset(hyracksFrame);
+		FrameTupleReference tuple = new FrameTupleReference();
 
-        Random rnd = new Random();
-        rnd.setSeed(50);
-        for (int i = 0; i < 5000; i++) {
+		RTreeOpContext insertOpCtx = rtree.createOpContext(IndexOp.INSERT,
+				leafFrame, interiorFrame, metaFrame);
 
-            double p1x = rnd.nextDouble();
-            double p1y = rnd.nextDouble();
-            double p2x = rnd.nextDouble();
-            double p2y = rnd.nextDouble();
+		Random rnd = new Random();
+		rnd.setSeed(50);
+		for (int i = 0; i < 5000; i++) {
 
-            int pk = rnd.nextInt();
+			double p1x = rnd.nextDouble();
+			double p1y = rnd.nextDouble();
+			double p2x = rnd.nextDouble();
+			double p2y = rnd.nextDouble();
 
-            tb.reset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1x, p2x), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1y, p2y), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1x, p2x), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1y, p2y), dos);
-            tb.addFieldEndOffset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(pk, dos);
-            tb.addFieldEndOffset();
+			int pk = rnd.nextInt();
 
-            appender.reset(hyracksFrame, true);
-            appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
+			tb.reset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1x, p2x),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1y, p2y),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1x, p2x),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1y, p2y),
+					dos);
+			tb.addFieldEndOffset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(pk, dos);
+			tb.addFieldEndOffset();
 
-            tuple.reset(accessor, 0);
+			appender.reset(hyracksFrame, true);
+			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0,
+					tb.getSize());
 
-            if (i % 1000 == 0) {
-                print("INSERTING " + i + " " + Math.min(p1x, p2x) + " " + Math.min(p1y, p2y) + " " + Math.max(p1x, p2x)
-                        + " " + Math.max(p1y, p2y) + "\n");
-            }
+			tuple.reset(accessor, 0);
 
-            try {
-                rtree.insert(tuple, insertOpCtx);
-            } catch (TreeIndexException e) {
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
+			if (i % 1000 == 0) {
+				print("INSERTING " + i + " " + Math.min(p1x, p2x) + " "
+						+ Math.min(p1y, p2y) + " " + Math.max(p1x, p2x) + " "
+						+ Math.max(p1y, p2y) + "\n");
+			}
 
-        for (int i = 0; i < 50; i++) {
-            double p1x = rnd.nextDouble();
-            double p1y = rnd.nextDouble();
-            double p2x = rnd.nextDouble();
-            double p2y = rnd.nextDouble();
+			try {
+				rtree.insert(tuple, insertOpCtx);
+			} catch (TreeIndexException e) {
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
 
-            int pk = rnd.nextInt();
+		for (int i = 0; i < 50; i++) {
+			double p1x = rnd.nextDouble();
+			double p1y = rnd.nextDouble();
+			double p2x = rnd.nextDouble();
+			double p2y = rnd.nextDouble();
 
-            tb.reset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1x, p2x), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1y, p2y), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1x, p2x), dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1y, p2y), dos);
-            tb.addFieldEndOffset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(pk, dos);
-            tb.addFieldEndOffset();
+			int pk = rnd.nextInt();
 
-            appender.reset(hyracksFrame, true);
-            appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
+			tb.reset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1x, p2x),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1y, p2y),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1x, p2x),
+					dos);
+			tb.addFieldEndOffset();
+			DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1y, p2y),
+					dos);
+			tb.addFieldEndOffset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(pk, dos);
+			tb.addFieldEndOffset();
 
-            tuple.reset(accessor, 0);
+			appender.reset(hyracksFrame, true);
+			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0,
+					tb.getSize());
 
-            print(i + " Searching for: " + Math.min(p1x, p2x) + " " + Math.min(p1y, p2y) + " " + Math.max(p1x, p2x)
-                    + " " + Math.max(p1y, p2y) + "\n");
+			tuple.reset(accessor, 0);
 
-            ITreeIndexCursor searchCursor = new RTreeSearchCursor(interiorFrame, leafFrame);
-            SearchPredicate searchPredicate = new SearchPredicate(tuple, cmp);
+			print(i + " Searching for: " + Math.min(p1x, p2x) + " "
+					+ Math.min(p1y, p2y) + " " + Math.max(p1x, p2x) + " "
+					+ Math.max(p1y, p2y) + "\n");
 
-            RTreeOpContext searchOpCtx = rtree.createOpContext(IndexOp.SEARCH, leafFrame, interiorFrame, metaFrame);
-            rtree.search(searchCursor, searchPredicate, searchOpCtx);
+			ITreeIndexCursor searchCursor = new RTreeSearchCursor(
+					interiorFrame, leafFrame);
+			SearchPredicate searchPredicate = new SearchPredicate(tuple, cmp);
 
-            ArrayList<Integer> results = new ArrayList<Integer>();
-            try {
-                while (searchCursor.hasNext()) {
-                    searchCursor.next();
-                    ITupleReference frameTuple = searchCursor.getTuple();
-                    ByteArrayInputStream inStream = new ByteArrayInputStream(frameTuple.getFieldData(4),
-                            frameTuple.getFieldStart(4), frameTuple.getFieldLength(4));
-                    DataInput dataIn = new DataInputStream(inStream);
-                    Integer res = IntegerSerializerDeserializer.INSTANCE.deserialize(dataIn);
-                    results.add(res);
-                }
-            } catch (Exception e) {
-                e.printStackTrace();
-            } finally {
-                searchCursor.close();
-            }
+			RTreeOpContext searchOpCtx = rtree.createOpContext(IndexOp.SEARCH,
+					leafFrame, interiorFrame, metaFrame);
+			rtree.search(searchCursor, searchPredicate, searchOpCtx);
 
-            System.err.println("There are " + results.size() + " objects that satisfy the query");
-        }
+			ArrayList<Integer> results = new ArrayList<Integer>();
+			try {
+				while (searchCursor.hasNext()) {
+					searchCursor.next();
+					ITupleReference frameTuple = searchCursor.getTuple();
+					ByteArrayInputStream inStream = new ByteArrayInputStream(
+							frameTuple.getFieldData(4),
+							frameTuple.getFieldStart(4),
+							frameTuple.getFieldLength(4));
+					DataInput dataIn = new DataInputStream(inStream);
+					Integer res = IntegerSerializerDeserializer.INSTANCE
+							.deserialize(dataIn);
+					results.add(res);
+				}
+			} catch (Exception e) {
+				e.printStackTrace();
+			} finally {
+				searchCursor.close();
+			}
 
-        rtree.close();
-        bufferCache.closeFile(fileId);
-        bufferCache.close();
-    }
+			System.err.println("There are " + results.size()
+					+ " objects that satisfy the query");
+		}
+
+		rtree.close();
+		bufferCache.closeFile(fileId);
+		bufferCache.close();
+	}
 }