diff --git a/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeOperatorsTest.java b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeOperatorsTest.java
index d3c047e..3109c33 100644
--- a/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeOperatorsTest.java
+++ b/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeOperatorsTest.java
@@ -17,7 +17,10 @@
 
 import java.io.DataOutput;
 import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
 
+import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -68,8 +71,10 @@
 	private IStorageManagerInterface storageManager = new TestStorageManagerInterface();
 	private IBTreeRegistryProvider btreeRegistryProvider = new TestBTreeRegistryProvider();
 
-	private final 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 index
 	private int primaryFieldCount = 6;
 	private ITypeTrait[] primaryTypeTraits = new ITypeTrait[primaryFieldCount];
@@ -82,13 +87,15 @@
 	private IBTreeLeafFrameFactory primaryLeafFrameFactory = new NSMLeafFrameFactory(
 			primaryTupleWriterFactory);
 
-	private String primaryBtreeName = "primary.ix";
-	private String primaryNc1FileName = System.getProperty("java.io.tmpdir")
+	private static String primaryBtreeName = "primary"
+			+ simpleDateFormat.format(new Date());
+	private static String primaryFileName = System
+			.getProperty("java.io.tmpdir")
 			+ sep + "nc1" + sep + primaryBtreeName;
 
 	private IFileSplitProvider primaryBtreeSplitProvider = new ConstantFileSplitProvider(
 			new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(
-					primaryNc1FileName))) });
+					primaryFileName))) });
 
 	private RecordDescriptor primaryRecDesc = new RecordDescriptor(
 			new ISerializerDeserializer[] {
@@ -111,13 +118,15 @@
 	private IBTreeLeafFrameFactory secondaryLeafFrameFactory = new NSMLeafFrameFactory(
 			secondaryTupleWriterFactory);
 
-	private String secondaryBtreeName = "secondary.ix";
-	private String secondaryNc1FileName = System.getProperty("java.io.tmpdir")
+	private static String secondaryBtreeName = "secondary"
+			+ simpleDateFormat.format(new Date());
+	private static String secondaryFileName = System
+			.getProperty("java.io.tmpdir")
 			+ sep + "nc1" + sep + secondaryBtreeName;
 
 	private IFileSplitProvider secondaryBtreeSplitProvider = new ConstantFileSplitProvider(
 			new FileSplit[] { new FileSplit(NC1_ID, new FileReference(new File(
-					secondaryNc1FileName))) });
+					secondaryFileName))) });
 
 	private RecordDescriptor secondaryRecDesc = new RecordDescriptor(
 			new ISerializerDeserializer[] {
@@ -593,4 +602,12 @@
 		runTest(spec);
 	}
 
-}
+	@AfterClass
+	public static void cleanup() throws Exception {
+		File primary = new File(primaryFileName);
+		primary.deleteOnExit();
+
+		File secondary = new File(secondaryFileName);
+		secondary.deleteOnExit();
+	}
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorNodePushable.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorNodePushable.java
index 1dd69ba..6e13ed7 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorNodePushable.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorNodePushable.java
@@ -26,56 +26,70 @@
 import edu.uci.ics.hyracks.storage.am.btree.frames.MetaDataFrame;
 import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
 
-public class BTreeBulkLoadOperatorNodePushable extends AbstractUnaryInputSinkOperatorNodePushable {
-    private float fillFactor;
-    private final BTreeOpHelper btreeOpHelper;
-    private FrameTupleAccessor accessor;
-    private BTree.BulkLoadContext bulkLoadCtx;
+public class BTreeBulkLoadOperatorNodePushable extends
+		AbstractUnaryInputSinkOperatorNodePushable {
+	private float fillFactor;
+	private final BTreeOpHelper btreeOpHelper;
+	private FrameTupleAccessor accessor;
+	private BTree.BulkLoadContext bulkLoadCtx;
 
-    private IRecordDescriptorProvider recordDescProvider;
+	private IRecordDescriptorProvider recordDescProvider;
 
-    private PermutingFrameTupleReference tuple = new PermutingFrameTupleReference();
+	private PermutingFrameTupleReference tuple = new PermutingFrameTupleReference();
 
-    public BTreeBulkLoadOperatorNodePushable(AbstractBTreeOperatorDescriptor opDesc, IHyracksStageletContext ctx,
-            int partition, int[] fieldPermutation, float fillFactor, IRecordDescriptorProvider recordDescProvider) {
-        btreeOpHelper = new BTreeOpHelper(opDesc, ctx, partition, BTreeOpHelper.BTreeMode.CREATE_BTREE);
-        this.fillFactor = fillFactor;
-        this.recordDescProvider = recordDescProvider;
-        tuple.setFieldPermutation(fieldPermutation);
-    }
+	public BTreeBulkLoadOperatorNodePushable(
+			AbstractBTreeOperatorDescriptor opDesc,
+			IHyracksStageletContext ctx, int partition, int[] fieldPermutation,
+			float fillFactor, IRecordDescriptorProvider recordDescProvider) {
+		btreeOpHelper = new BTreeOpHelper(opDesc, ctx, partition,
+				BTreeOpHelper.BTreeMode.CREATE_BTREE);
+		this.fillFactor = fillFactor;
+		this.recordDescProvider = recordDescProvider;
+		tuple.setFieldPermutation(fieldPermutation);
+	}
 
-    @Override
-    public void open() throws HyracksDataException {
-        AbstractBTreeOperatorDescriptor opDesc = btreeOpHelper.getOperatorDescriptor();
-        RecordDescriptor recDesc = recordDescProvider.getInputRecordDescriptor(opDesc.getOperatorId(), 0);
-        accessor = new FrameTupleAccessor(btreeOpHelper.getHyracksStageletContext().getFrameSize(), recDesc);
-        IBTreeMetaDataFrame metaFrame = new MetaDataFrame();
-        btreeOpHelper.init();
-        btreeOpHelper.getBTree().open(btreeOpHelper.getBTreeFileId());
-        bulkLoadCtx = btreeOpHelper.getBTree().beginBulkLoad(fillFactor, btreeOpHelper.getLeafFrame(),
-                btreeOpHelper.getInteriorFrame(), metaFrame);
-    }
+	@Override
+	public void open() throws HyracksDataException {
+		AbstractBTreeOperatorDescriptor opDesc = btreeOpHelper
+				.getOperatorDescriptor();
+		RecordDescriptor recDesc = recordDescProvider.getInputRecordDescriptor(
+				opDesc.getOperatorId(), 0);
+		accessor = new FrameTupleAccessor(btreeOpHelper
+				.getHyracksStageletContext().getFrameSize(), recDesc);
+		IBTreeMetaDataFrame metaFrame = new MetaDataFrame();
+		try {
+			btreeOpHelper.init();
+			btreeOpHelper.getBTree().open(btreeOpHelper.getBTreeFileId());
+			bulkLoadCtx = btreeOpHelper.getBTree().beginBulkLoad(fillFactor,
+					btreeOpHelper.getLeafFrame(),
+					btreeOpHelper.getInteriorFrame(), metaFrame);
+		} catch (Exception e) {
+			// cleanup in case of failure
+			btreeOpHelper.deinit();
+			throw new HyracksDataException(e);
+		}
+	}
 
-    @Override
-    public void nextFrame(ByteBuffer buffer) throws HyracksDataException {
-        accessor.reset(buffer);
-        int tupleCount = accessor.getTupleCount();
-        for (int i = 0; i < tupleCount; i++) {
-            tuple.reset(accessor, i);
-            btreeOpHelper.getBTree().bulkLoadAddTuple(bulkLoadCtx, tuple);
-        }
-    }
+	@Override
+	public void nextFrame(ByteBuffer buffer) throws HyracksDataException {
+		accessor.reset(buffer);
+		int tupleCount = accessor.getTupleCount();
+		for (int i = 0; i < tupleCount; i++) {
+			tuple.reset(accessor, i);
+			btreeOpHelper.getBTree().bulkLoadAddTuple(bulkLoadCtx, tuple);
+		}
+	}
 
-    @Override
-    public void close() throws HyracksDataException {
-        try {
-            btreeOpHelper.getBTree().endBulkLoad(bulkLoadCtx);
-        } finally {
-            btreeOpHelper.deinit();
-        }
-    }
+	@Override
+	public void close() throws HyracksDataException {
+		try {
+			btreeOpHelper.getBTree().endBulkLoad(bulkLoadCtx);
+		} finally {
+			btreeOpHelper.deinit();
+		}
+	}
 
-    @Override
-    public void flush() throws HyracksDataException {
-    }
+	@Override
+	public void flush() throws HyracksDataException {
+	}
 }
\ No newline at end of file
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorNodePushable.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorNodePushable.java
index fe71c33..c362183 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorNodePushable.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorNodePushable.java
@@ -45,50 +45,56 @@
         DiskOrderScanCursor cursor = new DiskOrderScanCursor(cursorFrame);
         IBTreeMetaDataFrame metaFrame = new MetaDataFrame();
 
-        btreeOpHelper.init();
-        btreeOpHelper.getBTree().diskOrderScan(cursor, cursorFrame, metaFrame);
-
-        MultiComparator cmp = btreeOpHelper.getBTree().getMultiComparator();
-        ByteBuffer frame = btreeOpHelper.getHyracksStageletContext().allocateFrame();
-        FrameTupleAppender appender = new FrameTupleAppender(btreeOpHelper.getHyracksStageletContext().getFrameSize());
-        appender.reset(frame, true);
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
-        DataOutput dos = tb.getDataOutput();
-
         try {
-            while (cursor.hasNext()) {
-                tb.reset();
-                cursor.next();
+        
+        	btreeOpHelper.init();
+        	
+        	try {
+        		btreeOpHelper.getBTree().diskOrderScan(cursor, cursorFrame, metaFrame);
 
-                ITupleReference frameTuple = cursor.getTuple();
-                for (int i = 0; i < frameTuple.getFieldCount(); i++) {
-                    dos.write(frameTuple.getFieldData(i), frameTuple.getFieldStart(i), frameTuple.getFieldLength(i));
-                    tb.addFieldEndOffset();
-                }
+        		MultiComparator cmp = btreeOpHelper.getBTree().getMultiComparator();
+        		ByteBuffer frame = btreeOpHelper.getHyracksStageletContext().allocateFrame();
+        		FrameTupleAppender appender = new FrameTupleAppender(btreeOpHelper.getHyracksStageletContext().getFrameSize());
+        		appender.reset(frame, true);
+        		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+        		DataOutput dos = tb.getDataOutput();
 
-                if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
-                    FrameUtils.flushFrame(frame, writer);
-                    appender.reset(frame, true);
-                    if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
-                        throw new IllegalStateException();
-                    }
-                }
-            }
+        		while (cursor.hasNext()) {
+        			tb.reset();
+        			cursor.next();
 
-            if (appender.getTupleCount() > 0) {
-                FrameUtils.flushFrame(frame, writer);
-            }
+        			ITupleReference frameTuple = cursor.getTuple();
+        			for (int i = 0; i < frameTuple.getFieldCount(); i++) {
+        				dos.write(frameTuple.getFieldData(i), frameTuple.getFieldStart(i), frameTuple.getFieldLength(i));
+        				tb.addFieldEndOffset();
+        			}
 
-            cursor.close();
-            writer.close();
+        			if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
+        				FrameUtils.flushFrame(frame, writer);
+        				appender.reset(frame, true);
+        				if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
+        					throw new IllegalStateException();
+        				}
+        			}
+        		}
 
-        } catch (Exception e) {
-            e.printStackTrace();
+        		if (appender.getTupleCount() > 0) {
+        			FrameUtils.flushFrame(frame, writer);
+        		}
+        	}
+        	finally {
+        		cursor.close();
+        		writer.close();
+        	}
+
+        } catch(Exception e) {
+        	deinitialize();
+        	throw new HyracksDataException(e);
         }
     }
 
     @Override
     public void deinitialize() throws HyracksDataException {
-        btreeOpHelper.deinit();
+    	btreeOpHelper.deinit();
     }
 }
\ No newline at end of file
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDropOperatorNodePushable.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDropOperatorNodePushable.java
index 23a6601..c087fdd 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDropOperatorNodePushable.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDropOperatorNodePushable.java
@@ -15,6 +15,9 @@
 
 package edu.uci.ics.hyracks.storage.am.btree.dataflow;
 
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
 import edu.uci.ics.hyracks.api.comm.IFrameWriter;
 import edu.uci.ics.hyracks.api.context.IHyracksStageletContext;
 import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
@@ -27,7 +30,9 @@
 import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
 
 public class BTreeDropOperatorNodePushable extends AbstractOperatorNodePushable {
-    private final IHyracksStageletContext ctx;
+	private static final Logger LOGGER = Logger.getLogger(BTreeDropOperatorNodePushable.class.getName());
+	
+	private final IHyracksStageletContext ctx;
     private IBTreeRegistryProvider btreeRegistryProvider;
     private IStorageManagerInterface storageManager;
     private IFileSplitProvider fileSplitProvider;
@@ -58,30 +63,39 @@
 
     @Override
     public void initialize() throws HyracksDataException {
+    	try {
 
-        BTreeRegistry btreeRegistry = btreeRegistryProvider.getBTreeRegistry(ctx);
-        IBufferCache bufferCache = storageManager.getBufferCache(ctx);
-        IFileMapProvider fileMapProvider = storageManager.getFileMapProvider(ctx);
+    		BTreeRegistry btreeRegistry = btreeRegistryProvider.getBTreeRegistry(ctx);
+    		IBufferCache bufferCache = storageManager.getBufferCache(ctx);
+    		IFileMapProvider fileMapProvider = storageManager.getFileMapProvider(ctx);
 
-        FileReference f = fileSplitProvider.getFileSplits()[partition].getLocalFile();
+    		FileReference f = fileSplitProvider.getFileSplits()[partition].getLocalFile();
 
-        boolean fileIsMapped = fileMapProvider.isMapped(f);
-        if (!fileIsMapped) {
-            throw new HyracksDataException("Cannot drop B-Tree with name " + f.toString() + ". No file mapping exists.");
-        }
+    		boolean fileIsMapped = fileMapProvider.isMapped(f);
+    		if (!fileIsMapped) {    			    			
+    			throw new HyracksDataException("Cannot drop B-Tree with name " + f.toString() + ". No file mapping exists.");
+    		}
 
-        int btreeFileId = fileMapProvider.lookupFileId(f);
+    		int btreeFileId = fileMapProvider.lookupFileId(f);
 
-        // unregister btree instance
-        btreeRegistry.lock();
-        try {
-            btreeRegistry.unregister(btreeFileId);
-        } finally {
-            btreeRegistry.unlock();
-        }
+    		// unregister btree instance
+    		btreeRegistry.lock();
+    		try {
+    			btreeRegistry.unregister(btreeFileId);
+    		} finally {
+    			btreeRegistry.unlock();
+    		}
 
-        // remove name to id mapping
-        bufferCache.deleteFile(btreeFileId);
+    		// remove name to id mapping
+    		bufferCache.deleteFile(btreeFileId);
+    	}
+    	// TODO: for the time being we don't throw,
+		// with proper exception handling (no hanging job problem) we should throw
+    	catch (Exception e) {
+    		if (LOGGER.isLoggable(Level.WARNING)) {
+                LOGGER.warning("BTRee Drop Operator Failed Due To Exception: " + e.getMessage());
+            }
+    	}
     }
 
     @Override
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeFileEnlistmentOperatorNodePushable.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeFileEnlistmentOperatorNodePushable.java
index 7557573..023cd40 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeFileEnlistmentOperatorNodePushable.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeFileEnlistmentOperatorNodePushable.java
@@ -46,8 +46,12 @@
 
     @Override
     public void initialize() throws HyracksDataException {
-        btreeOpHelper.init();
-        btreeOpHelper.deinit();
+        try {
+        	btreeOpHelper.init();
+        }
+        finally {
+        	btreeOpHelper.deinit();
+        }
     }
 
     @Override
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorNodePushable.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorNodePushable.java
index e6ba012..acb7d0f 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorNodePushable.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorNodePushable.java
@@ -48,14 +48,20 @@
 
     @Override
     public void open() throws HyracksDataException {
-        AbstractBTreeOperatorDescriptor opDesc = btreeOpHelper.getOperatorDescriptor();
-        RecordDescriptor inputRecDesc = recordDescProvider.getInputRecordDescriptor(opDesc.getOperatorId(), 0);
-        accessor = new FrameTupleAccessor(btreeOpHelper.getHyracksStageletContext().getFrameSize(), inputRecDesc);
-        writeBuffer = btreeOpHelper.getHyracksStageletContext().allocateFrame();
-        btreeOpHelper.init();
-        btreeOpHelper.getBTree().open(btreeOpHelper.getBTreeFileId());
-        opCtx = btreeOpHelper.getBTree().createOpContext(op, btreeOpHelper.getLeafFrame(),
-                btreeOpHelper.getInteriorFrame(), new MetaDataFrame());
+    	AbstractBTreeOperatorDescriptor opDesc = btreeOpHelper.getOperatorDescriptor();
+    	RecordDescriptor inputRecDesc = recordDescProvider.getInputRecordDescriptor(opDesc.getOperatorId(), 0);
+    	accessor = new FrameTupleAccessor(btreeOpHelper.getHyracksStageletContext().getFrameSize(), inputRecDesc);
+    	writeBuffer = btreeOpHelper.getHyracksStageletContext().allocateFrame();
+    	try {
+    		btreeOpHelper.init();
+    		btreeOpHelper.getBTree().open(btreeOpHelper.getBTreeFileId());
+    		opCtx = btreeOpHelper.getBTree().createOpContext(op, btreeOpHelper.getLeafFrame(),
+    				btreeOpHelper.getInteriorFrame(), new MetaDataFrame());
+    	} catch(Exception e) {
+    		// cleanup in case of failure
+    		btreeOpHelper.deinit();
+    		throw new HyracksDataException(e);
+    	}
     }
 
     @Override
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeOpHelper.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeOpHelper.java
index d01ceee..880cc25 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeOpHelper.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeOpHelper.java
@@ -29,23 +29,21 @@
 
 final class BTreeOpHelper {
 
-    public enum BTreeMode {
-        OPEN_BTREE,
-        CREATE_BTREE,
-        ENLIST_BTREE
-    }
+	public enum BTreeMode {
+		OPEN_BTREE, CREATE_BTREE, ENLIST_BTREE
+	}
+	
+	private IBTreeInteriorFrame interiorFrame;
+	private IBTreeLeafFrame leafFrame;
 
-    private IBTreeInteriorFrame interiorFrame;
-    private IBTreeLeafFrame leafFrame;
-
-    private BTree btree;
-    private int btreeFileId = -1;
-    private int partition;
+	private BTree btree;
+	private int btreeFileId = -1;
+	private int partition;
 
     private AbstractBTreeOperatorDescriptor opDesc;
     private IHyracksStageletContext ctx;
 
-    private BTreeMode mode;
+	private BTreeMode mode;
 
     BTreeOpHelper(AbstractBTreeOperatorDescriptor opDesc, final IHyracksStageletContext ctx, int partition,
             BTreeMode mode) {
@@ -55,7 +53,7 @@
         this.partition = partition;
     }
 
-    void init() throws HyracksDataException {
+	void init() throws HyracksDataException {
         IBufferCache bufferCache = opDesc.getStorageManager().getBufferCache(ctx);
         IFileMapProvider fileMapProvider = opDesc.getStorageManager().getFileMapProvider(ctx);
         IFileSplitProvider fileSplitProvider = opDesc.getFileSplitProvider();
@@ -63,70 +61,72 @@
         FileReference f = fileSplitProvider.getFileSplits()[partition].getLocalFile();
         boolean fileIsMapped = fileMapProvider.isMapped(f);
 
-        switch (mode) {
+		switch (mode) {
+		
+		case OPEN_BTREE: {
+			if (!fileIsMapped) {
+				throw new HyracksDataException(
+						"Trying to open btree from unmapped file " + f.toString());
+			}
+		}
+		break;
 
-            case OPEN_BTREE: {
-                if (!fileIsMapped) {
-                    bufferCache.createFile(f);
-                    // throw new
-                    // HyracksDataException("Trying to open btree from unmapped file "
-                    // + fileName);
-                }
-            }
-                break;
-
-            case CREATE_BTREE:
-            case ENLIST_BTREE: {
-                if (!fileIsMapped) {
-                    bufferCache.createFile(f);
-                }
-            }
-                break;
-
-        }
+		case CREATE_BTREE:
+		case ENLIST_BTREE: {
+			if (!fileIsMapped) {
+				bufferCache.createFile(f);
+			}
+		}
+		break;
+		
+		}
 
         btreeFileId = fileMapProvider.lookupFileId(f);
         bufferCache.openFile(btreeFileId);
 
-        interiorFrame = opDesc.getInteriorFactory().getFrame();
-        leafFrame = opDesc.getLeafFactory().getFrame();
+		interiorFrame = opDesc.getInteriorFactory().getFrame();
+		leafFrame = opDesc.getLeafFactory().getFrame();
 
         BTreeRegistry btreeRegistry = opDesc.getBtreeRegistryProvider().getBTreeRegistry(ctx);
         btree = btreeRegistry.get(btreeFileId);
         if (btree == null) {
 
-            // create new btree and register it
-            btreeRegistry.lock();
-            try {
-                // check if btree has already been registered by another thread
-                btree = btreeRegistry.get(btreeFileId);
-                if (btree == null) {
-                    // this thread should create and register the btree
+			// create new btree and register it
+			btreeRegistry.lock();
+			try {
+				// check if btree has already been registered by another thread
+				btree = btreeRegistry.get(btreeFileId);
+				if (btree == null) {
+					// this thread should create and register the btree
 
-                    IBinaryComparator[] comparators = new IBinaryComparator[opDesc.getComparatorFactories().length];
-                    for (int i = 0; i < opDesc.getComparatorFactories().length; i++) {
-                        comparators[i] = opDesc.getComparatorFactories()[i].createBinaryComparator();
-                    }
+					IBinaryComparator[] comparators = new IBinaryComparator[opDesc
+							.getComparatorFactories().length];
+					for (int i = 0; i < opDesc.getComparatorFactories().length; i++) {
+						comparators[i] = opDesc.getComparatorFactories()[i]
+								.createBinaryComparator();
+					}
 
-                    MultiComparator cmp = new MultiComparator(opDesc.getTypeTraits(), comparators);
+					MultiComparator cmp = new MultiComparator(opDesc
+							.getTypeTraits(), comparators);
 
-                    btree = new BTree(bufferCache, opDesc.getInteriorFactory(), opDesc.getLeafFactory(), cmp);
-                    if (mode == BTreeMode.CREATE_BTREE) {
-                        MetaDataFrame metaFrame = new MetaDataFrame();
-                        try {
-                            btree.create(btreeFileId, leafFrame, metaFrame);
-                            btree.open(btreeFileId);
-                        } catch (Exception e) {
-                            throw new HyracksDataException(e);
-                        }
-                    }
-                    btreeRegistry.register(btreeFileId, btree);
-                }
-            } finally {
-                btreeRegistry.unlock();
-            }
-        }
-    }
+					btree = new BTree(bufferCache, opDesc.getInteriorFactory(),
+							opDesc.getLeafFactory(), cmp);
+					if (mode == BTreeMode.CREATE_BTREE) {
+						MetaDataFrame metaFrame = new MetaDataFrame();
+						try {
+							btree.create(btreeFileId, leafFrame, metaFrame);
+							btree.open(btreeFileId);
+						} catch (Exception e) {
+							throw new HyracksDataException(e);
+						}
+					}
+					btreeRegistry.register(btreeFileId, btree);
+				}
+			} finally {
+				btreeRegistry.unlock();
+			}
+		}
+	}
 
     public void deinit() throws HyracksDataException {
         if (btreeFileId != -1) {
@@ -135,27 +135,27 @@
         }
     }
 
-    public BTree getBTree() {
-        return btree;
-    }
+	public BTree getBTree() {
+		return btree;
+	}
 
     public IHyracksStageletContext getHyracksStageletContext() {
         return ctx;
     }
 
-    public AbstractBTreeOperatorDescriptor getOperatorDescriptor() {
-        return opDesc;
-    }
+	public AbstractBTreeOperatorDescriptor getOperatorDescriptor() {
+		return opDesc;
+	}
 
-    public IBTreeLeafFrame getLeafFrame() {
-        return leafFrame;
-    }
+	public IBTreeLeafFrame getLeafFrame() {
+		return leafFrame;
+	}
 
-    public IBTreeInteriorFrame getInteriorFrame() {
-        return interiorFrame;
-    }
+	public IBTreeInteriorFrame getInteriorFrame() {
+		return interiorFrame;
+	}
 
-    public int getBTreeFileId() {
-        return btreeFileId;
-    }
+	public int getBTreeFileId() {
+		return btreeFileId;
+	}
 }
\ No newline at end of file
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorNodePushable.java b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorNodePushable.java
index 5911ae9..415f169 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorNodePushable.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorNodePushable.java
@@ -37,165 +37,194 @@
 import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
 import edu.uci.ics.hyracks.storage.am.btree.impls.RangeSearchCursor;
 
-public class BTreeSearchOperatorNodePushable extends AbstractUnaryInputUnaryOutputOperatorNodePushable {
-    private BTreeOpHelper btreeOpHelper;
-    private FrameTupleAccessor accessor;
+public class BTreeSearchOperatorNodePushable extends
+		AbstractUnaryInputUnaryOutputOperatorNodePushable {
+	private BTreeOpHelper btreeOpHelper;
+	private FrameTupleAccessor accessor;
 
-    private ByteBuffer writeBuffer;
-    private FrameTupleAppender appender;
-    private ArrayTupleBuilder tb;
-    private DataOutput dos;
+	private ByteBuffer writeBuffer;
+	private FrameTupleAppender appender;
+	private ArrayTupleBuilder tb;
+	private DataOutput dos;
 
-    private BTree btree;
-    private boolean isForward;
-    private PermutingFrameTupleReference lowKey;
-    private PermutingFrameTupleReference highKey;
-    private boolean lowKeyInclusive;
-    private boolean highKeyInclusive;
-    private RangePredicate rangePred;
-    private MultiComparator lowKeySearchCmp;
-    private MultiComparator highKeySearchCmp;
-    private IBTreeCursor cursor;
-    private IBTreeLeafFrame cursorFrame;
-    private BTreeOpContext opCtx;
+	private BTree btree;
+	private boolean isForward;
+	private PermutingFrameTupleReference lowKey;
+	private PermutingFrameTupleReference highKey;
+	private boolean lowKeyInclusive;
+	private boolean highKeyInclusive;
+	private RangePredicate rangePred;
+	private MultiComparator lowKeySearchCmp;
+	private MultiComparator highKeySearchCmp;
+	private IBTreeCursor cursor;
+	private IBTreeLeafFrame cursorFrame;
+	private BTreeOpContext opCtx;
 
-    private RecordDescriptor recDesc;
+	private RecordDescriptor recDesc;
 
-    public BTreeSearchOperatorNodePushable(AbstractBTreeOperatorDescriptor opDesc, IHyracksStageletContext ctx,
-            int partition, IRecordDescriptorProvider recordDescProvider, boolean isForward, int[] lowKeyFields,
-            int[] highKeyFields, boolean lowKeyInclusive, boolean highKeyInclusive) {
-        btreeOpHelper = new BTreeOpHelper(opDesc, ctx, partition, BTreeOpHelper.BTreeMode.OPEN_BTREE);
-        this.isForward = isForward;
-        this.lowKeyInclusive = lowKeyInclusive;
-        this.highKeyInclusive = highKeyInclusive;
-        this.recDesc = recordDescProvider.getInputRecordDescriptor(opDesc.getOperatorId(), 0);
-        if (lowKeyFields != null && lowKeyFields.length > 0) {
-            lowKey = new PermutingFrameTupleReference();
-            lowKey.setFieldPermutation(lowKeyFields);
-        }
-        if (highKeyFields != null && highKeyFields.length > 0) {
-            highKey = new PermutingFrameTupleReference();
-            highKey.setFieldPermutation(highKeyFields);
-        }
-    }
+	public BTreeSearchOperatorNodePushable(
+			AbstractBTreeOperatorDescriptor opDesc,
+			IHyracksStageletContext ctx, int partition,
+			IRecordDescriptorProvider recordDescProvider, boolean isForward,
+			int[] lowKeyFields, int[] highKeyFields, boolean lowKeyInclusive,
+			boolean highKeyInclusive) {
+		btreeOpHelper = new BTreeOpHelper(opDesc, ctx, partition,
+				BTreeOpHelper.BTreeMode.OPEN_BTREE);
+		this.isForward = isForward;
+		this.lowKeyInclusive = lowKeyInclusive;
+		this.highKeyInclusive = highKeyInclusive;
+		this.recDesc = recordDescProvider.getInputRecordDescriptor(opDesc
+				.getOperatorId(), 0);
+		if (lowKeyFields != null && lowKeyFields.length > 0) {
+			lowKey = new PermutingFrameTupleReference();
+			lowKey.setFieldPermutation(lowKeyFields);
+		}
+		if (highKeyFields != null && highKeyFields.length > 0) {
+			highKey = new PermutingFrameTupleReference();
+			highKey.setFieldPermutation(highKeyFields);
+		}
+	}
 
-    @Override
-    public void open() throws HyracksDataException {
-        AbstractBTreeOperatorDescriptor opDesc = btreeOpHelper.getOperatorDescriptor();
-        accessor = new FrameTupleAccessor(btreeOpHelper.getHyracksStageletContext().getFrameSize(), recDesc);
+	@Override
+	public void open() throws HyracksDataException {
+		AbstractBTreeOperatorDescriptor opDesc = btreeOpHelper
+				.getOperatorDescriptor();
+		accessor = new FrameTupleAccessor(btreeOpHelper
+				.getHyracksStageletContext().getFrameSize(), recDesc);
 
-        cursorFrame = opDesc.getLeafFactory().getFrame();
-        cursor = new RangeSearchCursor(cursorFrame);
+		cursorFrame = opDesc.getLeafFactory().getFrame();
+		cursor = new RangeSearchCursor(cursorFrame);
 
-        btreeOpHelper.init();
-        btree = btreeOpHelper.getBTree();
+		try {
 
-        // construct range predicate
+			btreeOpHelper.init();
+			btree = btreeOpHelper.getBTree();
 
-        int lowKeySearchFields = btree.getMultiComparator().getComparators().length;
-        int highKeySearchFields = btree.getMultiComparator().getComparators().length;
-        if (lowKey != null)
-            lowKeySearchFields = lowKey.getFieldCount();
-        if (highKey != null)
-            highKeySearchFields = highKey.getFieldCount();
+			// construct range predicate
 
-        IBinaryComparator[] lowKeySearchComparators = new IBinaryComparator[lowKeySearchFields];
-        for (int i = 0; i < lowKeySearchFields; i++) {
-            lowKeySearchComparators[i] = btree.getMultiComparator().getComparators()[i];
-        }
-        lowKeySearchCmp = new MultiComparator(btree.getMultiComparator().getTypeTraits(), lowKeySearchComparators);
+			int lowKeySearchFields = btree.getMultiComparator()
+					.getComparators().length;
+			int highKeySearchFields = btree.getMultiComparator()
+					.getComparators().length;
+			if (lowKey != null)
+				lowKeySearchFields = lowKey.getFieldCount();
+			if (highKey != null)
+				highKeySearchFields = highKey.getFieldCount();
 
-        if (lowKeySearchFields == highKeySearchFields) {
-            highKeySearchCmp = lowKeySearchCmp;
-        } else {
-            IBinaryComparator[] highKeySearchComparators = new IBinaryComparator[highKeySearchFields];
-            for (int i = 0; i < highKeySearchFields; i++) {
-                highKeySearchComparators[i] = btree.getMultiComparator().getComparators()[i];
-            }
-            highKeySearchCmp = new MultiComparator(btree.getMultiComparator().getTypeTraits(), highKeySearchComparators);
+			IBinaryComparator[] lowKeySearchComparators = new IBinaryComparator[lowKeySearchFields];
+			for (int i = 0; i < lowKeySearchFields; i++) {
+				lowKeySearchComparators[i] = btree.getMultiComparator()
+						.getComparators()[i];
+			}
+			lowKeySearchCmp = new MultiComparator(btree.getMultiComparator()
+					.getTypeTraits(), lowKeySearchComparators);
 
-        }
+			if (lowKeySearchFields == highKeySearchFields) {
+				highKeySearchCmp = lowKeySearchCmp;
+			} else {
+				IBinaryComparator[] highKeySearchComparators = new IBinaryComparator[highKeySearchFields];
+				for (int i = 0; i < highKeySearchFields; i++) {
+					highKeySearchComparators[i] = btree.getMultiComparator()
+							.getComparators()[i];
+				}
+				highKeySearchCmp = new MultiComparator(btree
+						.getMultiComparator().getTypeTraits(),
+						highKeySearchComparators);
 
-        rangePred = new RangePredicate(isForward, null, null, lowKeyInclusive, highKeyInclusive, lowKeySearchCmp,
-                highKeySearchCmp);
+			}
 
-        accessor = new FrameTupleAccessor(btreeOpHelper.getHyracksStageletContext().getFrameSize(), recDesc);
+			rangePred = new RangePredicate(isForward, null, null,
+					lowKeyInclusive, highKeyInclusive, lowKeySearchCmp,
+					highKeySearchCmp);
 
-        writeBuffer = btreeOpHelper.getHyracksStageletContext().allocateFrame();
-        tb = new ArrayTupleBuilder(btree.getMultiComparator().getFieldCount());
-        dos = tb.getDataOutput();
-        appender = new FrameTupleAppender(btreeOpHelper.getHyracksStageletContext().getFrameSize());
-        appender.reset(writeBuffer, true);
+			accessor = new FrameTupleAccessor(btreeOpHelper
+					.getHyracksStageletContext().getFrameSize(), recDesc);
 
-        opCtx = btree.createOpContext(BTreeOp.BTO_SEARCH, btreeOpHelper.getLeafFrame(),
-                btreeOpHelper.getInteriorFrame(), null);
-    }
+			writeBuffer = btreeOpHelper.getHyracksStageletContext()
+					.allocateFrame();
+			tb = new ArrayTupleBuilder(btree.getMultiComparator()
+					.getFieldCount());
+			dos = tb.getDataOutput();
+			appender = new FrameTupleAppender(btreeOpHelper
+					.getHyracksStageletContext().getFrameSize());
+			appender.reset(writeBuffer, true);
 
-    private void writeSearchResults() throws Exception {
-        while (cursor.hasNext()) {
-            tb.reset();
-            cursor.next();
+			opCtx = btree.createOpContext(BTreeOp.BTO_SEARCH, btreeOpHelper
+					.getLeafFrame(), btreeOpHelper.getInteriorFrame(), null);
 
-            ITupleReference frameTuple = cursor.getTuple();
-            for (int i = 0; i < frameTuple.getFieldCount(); i++) {
-                dos.write(frameTuple.getFieldData(i), frameTuple.getFieldStart(i), frameTuple.getFieldLength(i));
-                tb.addFieldEndOffset();
-            }
+		} catch (Exception e) {
+			btreeOpHelper.deinit();
+		}
+	}
 
-            if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
-                FrameUtils.flushFrame(writeBuffer, writer);
-                appender.reset(writeBuffer, true);
-                if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
-                    throw new IllegalStateException();
-                }
-            }
-        }
-    }
+	private void writeSearchResults() throws Exception {
+		while (cursor.hasNext()) {
+			tb.reset();
+			cursor.next();
 
-    @Override
-    public void nextFrame(ByteBuffer buffer) throws HyracksDataException {
-        accessor.reset(buffer);
+			ITupleReference frameTuple = cursor.getTuple();
+			for (int i = 0; i < frameTuple.getFieldCount(); i++) {
+				dos.write(frameTuple.getFieldData(i), frameTuple
+						.getFieldStart(i), frameTuple.getFieldLength(i));
+				tb.addFieldEndOffset();
+			}
 
-        int tupleCount = accessor.getTupleCount();
-        try {
-            for (int i = 0; i < tupleCount; i++) {
-                if (lowKey != null)
-                    lowKey.reset(accessor, i);
-                if (highKey != null)
-                    highKey.reset(accessor, i);
-                rangePred.setLowKey(lowKey, lowKeyInclusive);
-                rangePred.setHighKey(highKey, highKeyInclusive);
+			if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0,
+					tb.getSize())) {
+				FrameUtils.flushFrame(writeBuffer, writer);
+				appender.reset(writeBuffer, true);
+				if (!appender.append(tb.getFieldEndOffsets(),
+						tb.getByteArray(), 0, tb.getSize())) {
+					throw new IllegalStateException();
+				}
+			}
+		}
+	}
 
-                cursor.reset();
-                btree.search(cursor, rangePred, opCtx);
-                writeSearchResults();
-            }
-        } catch (Exception e) {
-            throw new HyracksDataException(e);
-        }
-    }
-    
-    @Override
-    public void close() throws HyracksDataException {
-        try {
-            if (appender.getTupleCount() > 0) {
-                FrameUtils.flushFrame(writeBuffer, writer);
-            }
-            writer.close();
-            try {
-                cursor.close();
-            } catch (Exception e) {
-                throw new HyracksDataException(e);
-            }
-        } finally {
-            btreeOpHelper.deinit();
-        }
-    }
+	@Override
+	public void nextFrame(ByteBuffer buffer) throws HyracksDataException {
+		accessor.reset(buffer);
 
-    @Override
-    public void flush() throws HyracksDataException {
-        if (appender.getTupleCount() > 0) {
-            FrameUtils.flushFrame(writeBuffer, writer);
-        }
-    }
+		int tupleCount = accessor.getTupleCount();
+		try {
+			for (int i = 0; i < tupleCount; i++) {
+				if (lowKey != null)
+					lowKey.reset(accessor, i);
+				if (highKey != null)
+					highKey.reset(accessor, i);
+				rangePred.setLowKey(lowKey, lowKeyInclusive);
+				rangePred.setHighKey(highKey, highKeyInclusive);
+
+				cursor.reset();
+				btree.search(cursor, rangePred, opCtx);
+				writeSearchResults();
+			}
+		} catch (Exception e) {
+			throw new HyracksDataException(e);
+		}
+	}
+
+	@Override
+	public void close() throws HyracksDataException {
+		try {
+			if (appender.getTupleCount() > 0) {
+				FrameUtils.flushFrame(writeBuffer, writer);
+			}
+			writer.close();
+			try {
+				cursor.close();
+			} catch (Exception e) {
+				throw new HyracksDataException(e);
+			}
+		} finally {
+			btreeOpHelper.deinit();
+		}
+	}
+
+	@Override
+	public void flush() throws HyracksDataException {
+		if (appender.getTupleCount() > 0) {
+			FrameUtils.flushFrame(writeBuffer, writer);
+		}
+	}
 }
\ No newline at end of file
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/AbstractBTreeTest.java b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/AbstractBTreeTest.java
new file mode 100644
index 0000000..c2e2fd6
--- /dev/null
+++ b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/AbstractBTreeTest.java
@@ -0,0 +1,25 @@
+package edu.uci.ics.hyracks.storage.am.btree;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.junit.AfterClass;
+
+public abstract class AbstractBTreeTest {
+
+    protected final static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMyy-hhmmssSS");
+    protected final static String tmpDir = System.getProperty("java.io.tmpdir");
+    protected final static String sep = System.getProperty("file.separator");
+    protected final static String fileName = tmpDir + sep + simpleDateFormat.format(new Date());
+
+    protected void print(String str) {
+        System.out.print(str);
+    }
+
+    @AfterClass
+    public static void cleanup() throws Exception {
+        File f = new File(fileName);
+        f.deleteOnExit();
+    }
+}
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeFieldPrefixNSMTest.java b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeFieldPrefixNSMTest.java
index 0798c22..e856296 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeFieldPrefixNSMTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeFieldPrefixNSMTest.java
@@ -54,193 +54,197 @@
 import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
 import edu.uci.ics.hyracks.test.support.TestUtils;
 
-public class BTreeFieldPrefixNSMTest {
+public class BTreeFieldPrefixNSMTest extends AbstractBTreeTest {
 
-    private static final int PAGE_SIZE = 32768; // 32K
-    private static final int NUM_PAGES = 40;
-    private static final int HYRACKS_FRAME_SIZE = 128;
+	private static final int PAGE_SIZE = 32768; // 32K
+	private static final int NUM_PAGES = 40;
+	private static final int HYRACKS_FRAME_SIZE = 128;
+	private IHyracksStageletContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
+	
+	public class BufferAllocator implements ICacheMemoryAllocator {
+		@Override
+		public ByteBuffer[] allocate(int pageSize, int numPages) {
+			ByteBuffer[] buffers = new ByteBuffer[numPages];
+			for (int i = 0; i < numPages; ++i) {
+				buffers[i] = ByteBuffer.allocate(pageSize);
+			}
+			return buffers;
+		}
+	}
 
-    private String tmpDir = System.getProperty("java.io.tmpdir");
+	private ITupleReference createTuple(IHyracksStageletContext ctx, int f0,
+			int f1, int f2, boolean print) throws HyracksDataException {
+		if (print)
+			System.out.println("CREATING: " + f0 + " " + f1 + " " + f2);
 
-    // to help with the logger madness
-    private void print(String str) {
-        System.out.print(str);
+		ByteBuffer buf = ctx.allocateFrame();
+		FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+		ArrayTupleBuilder tb = new ArrayTupleBuilder(3);
+		DataOutput dos = tb.getDataOutput();
 
-        // if(GlobalConfig.ASTERIX_LOGGER.isLoggable(Level.FINEST)) {
-        // GlobalConfig.ASTERIX_LOGGER.finest(str);
-        // }
-    }
+		ISerializerDeserializer[] recDescSers = {
+				IntegerSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE };
+		RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
+		IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx
+				.getFrameSize(), recDesc);
+		accessor.reset(buf);
+		FrameTupleReference tuple = new FrameTupleReference();
 
-    public class BufferAllocator implements ICacheMemoryAllocator {
-        @Override
-        public ByteBuffer[] allocate(int pageSize, int numPages) {
-            ByteBuffer[] buffers = new ByteBuffer[numPages];
-            for (int i = 0; i < numPages; ++i) {
-                buffers[i] = ByteBuffer.allocate(pageSize);
-            }
-            return buffers;
-        }
-    }
+		tb.reset();
+		IntegerSerializerDeserializer.INSTANCE.serialize(f0, dos);
+		tb.addFieldEndOffset();
+		IntegerSerializerDeserializer.INSTANCE.serialize(f1, dos);
+		tb.addFieldEndOffset();
+		IntegerSerializerDeserializer.INSTANCE.serialize(f2, dos);
+		tb.addFieldEndOffset();
 
-    private ITupleReference createTuple(IHyracksStageletContext ctx, int f0, int f1, int f2, boolean print)
-            throws HyracksDataException {
-        if (print)
-            System.out.println("CREATING: " + f0 + " " + f1 + " " + f2);
+		appender.reset(buf, true);
+		appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb
+				.getSize());
 
-        ByteBuffer buf = ctx.allocateFrame();
-        FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(3);
-        DataOutput dos = tb.getDataOutput();
+		tuple.reset(accessor, 0);
 
-        ISerializerDeserializer[] recDescSers = { IntegerSerializerDeserializer.INSTANCE,
-                IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
-        RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
-        IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(), recDesc);
-        accessor.reset(buf);
-        FrameTupleReference tuple = new FrameTupleReference();
+		return tuple;
+	}
 
-        tb.reset();
-        IntegerSerializerDeserializer.INSTANCE.serialize(f0, dos);
-        tb.addFieldEndOffset();
-        IntegerSerializerDeserializer.INSTANCE.serialize(f1, dos);
-        tb.addFieldEndOffset();
-        IntegerSerializerDeserializer.INSTANCE.serialize(f2, dos);
-        tb.addFieldEndOffset();
+	@Test
+	public void test01() throws Exception {
+		
+		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
+		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);
 
-        appender.reset(buf, true);
-        appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
+		// declare fields
+		int fieldCount = 3;
+		ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
+		typeTraits[0] = new TypeTrait(4);
+		typeTraits[1] = new TypeTrait(4);
+		typeTraits[2] = new TypeTrait(4);
 
-        tuple.reset(accessor, 0);
+		// declare keys
+		int keyFieldCount = 3;
+		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+		cmps[0] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		cmps[1] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		cmps[2] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-        return tuple;
-    }
+		// just for printing
+		ISerializerDeserializer[] sers = {
+				IntegerSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE };
 
-    @Test
-    public void test01() throws Exception {
-        IHyracksStageletContext stageletCtx = TestUtils.create(HYRACKS_FRAME_SIZE);
-        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
-        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(stageletCtx);
-        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(stageletCtx);
-        FileReference file = new FileReference(new File(tmpDir + "/" + "btreetest.bin"));
-        bufferCache.createFile(file);
-        int fileId = fmp.lookupFileId(file);
-        bufferCache.openFile(fileId);
+		Random rnd = new Random();
+		rnd.setSeed(50);
 
-        // declare fields
-        int fieldCount = 3;
-        ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
-        typeTraits[0] = new TypeTrait(4);
-        typeTraits[1] = new TypeTrait(4);
-        typeTraits[2] = new TypeTrait(4);
+		ICachedPage page = bufferCache.pin(BufferedFileHandle.getDiskPageId(
+				fileId, 0), false);
+		try {
 
-        // declare keys
-        int keyFieldCount = 3;
-        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-        cmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        cmps[1] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        cmps[2] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+			IPrefixSlotManager slotManager = new FieldPrefixSlotManager();
+			IBTreeTupleWriter tupleWriter = new TypeAwareTupleWriter(typeTraits);
+			FieldPrefixNSMLeafFrame frame = new FieldPrefixNSMLeafFrame(
+					tupleWriter);
+			frame.setPage(page);
+			frame.initBuffer((byte) 0);
+			slotManager.setFrame(frame);
+			frame.setPrefixTupleCount(0);
 
-        // just for printing
-        ISerializerDeserializer[] sers = { IntegerSerializerDeserializer.INSTANCE,
-                IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
+			String before = new String();
+			String after = new String();
 
-        Random rnd = new Random();
-        rnd.setSeed(50);
+			int compactFreq = 5;
+			int compressFreq = 5;
+			int smallMax = 10;
+			int numRecords = 1000;
 
-        ICachedPage page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, 0), false);
-        try {
+			int[][] savedFields = new int[numRecords][3];
 
-            IPrefixSlotManager slotManager = new FieldPrefixSlotManager();
-            IBTreeTupleWriter tupleWriter = new TypeAwareTupleWriter(typeTraits);
-            FieldPrefixNSMLeafFrame frame = new FieldPrefixNSMLeafFrame(tupleWriter);
-            frame.setPage(page);
-            frame.initBuffer((byte) 0);
-            slotManager.setFrame(frame);
-            frame.setPrefixTupleCount(0);
+			// insert records with random calls to compact and compress
+			for (int i = 0; i < numRecords; i++) {
 
-            String before = new String();
-            String after = new String();
+				if ((i + 1) % 100 == 0)
+					print("INSERTING " + (i + 1) + " / " + numRecords + "\n");
 
-            int compactFreq = 5;
-            int compressFreq = 5;
-            int smallMax = 10;
-            int numRecords = 1000;
+				int a = rnd.nextInt() % smallMax;
+				int b = rnd.nextInt() % smallMax;
+				int c = i;
 
-            int[][] savedFields = new int[numRecords][3];
+				ITupleReference tuple = createTuple(ctx, a, b, c, false);
+				try {
+					frame.insert(tuple, cmp);
+				} catch (BTreeException e) {
+					e.printStackTrace();
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
 
-            // insert records with random calls to compact and compress
-            for (int i = 0; i < numRecords; i++) {
+				savedFields[i][0] = a;
+				savedFields[i][1] = b;
+				savedFields[i][2] = c;
 
-                if ((i + 1) % 100 == 0)
-                    print("INSERTING " + (i + 1) + " / " + numRecords + "\n");
+				if (rnd.nextInt() % compactFreq == 0) {
+					before = frame.printKeys(cmp, sers);
+					frame.compact(cmp);
+					after = frame.printKeys(cmp, sers);
+					Assert.assertEquals(before, after);
+				}
 
-                int a = rnd.nextInt() % smallMax;
-                int b = rnd.nextInt() % smallMax;
-                int c = i;
+				if (rnd.nextInt() % compressFreq == 0) {
+					before = frame.printKeys(cmp, sers);
+					frame.compress(cmp);
+					after = frame.printKeys(cmp, sers);
+					Assert.assertEquals(before, after);
+				}
 
-                ITupleReference tuple = createTuple(stageletCtx, a, b, c, false);
-                try {
-                    frame.insert(tuple, cmp);
-                } catch (BTreeException e) {
-                    e.printStackTrace();
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
+			}
 
-                savedFields[i][0] = a;
-                savedFields[i][1] = b;
-                savedFields[i][2] = c;
+			// delete records with random calls to compact and compress
+			for (int i = 0; i < numRecords; i++) {
 
-                if (rnd.nextInt() % compactFreq == 0) {
-                    before = frame.printKeys(cmp, sers);
-                    frame.compact(cmp);
-                    after = frame.printKeys(cmp, sers);
-                    Assert.assertEquals(before, after);
-                }
+				if ((i + 1) % 100 == 0)
+					print("DELETING " + (i + 1) + " / " + numRecords + "\n");
 
-                if (rnd.nextInt() % compressFreq == 0) {
-                    before = frame.printKeys(cmp, sers);
-                    frame.compress(cmp);
-                    after = frame.printKeys(cmp, sers);
-                    Assert.assertEquals(before, after);
-                }
+				ITupleReference tuple = createTuple(ctx,
+						savedFields[i][0], savedFields[i][1],
+						savedFields[i][2], false);
+				try {
+					frame.delete(tuple, cmp, true);
+				} catch (Exception e) {
+				}
 
-            }
+				if (rnd.nextInt() % compactFreq == 0) {
+					before = frame.printKeys(cmp, sers);
+					frame.compact(cmp);
+					after = frame.printKeys(cmp, sers);
+					Assert.assertEquals(before, after);
+				}
 
-            // delete records with random calls to compact and compress
-            for (int i = 0; i < numRecords; i++) {
+				if (rnd.nextInt() % compressFreq == 0) {
+					before = frame.printKeys(cmp, sers);
+					frame.compress(cmp);
+					after = frame.printKeys(cmp, sers);
+					Assert.assertEquals(before, after);
+				}
+			}
 
-                if ((i + 1) % 100 == 0)
-                    print("DELETING " + (i + 1) + " / " + numRecords + "\n");
+		} finally {
+			bufferCache.unpin(page);
+		}
 
-                ITupleReference tuple = createTuple(stageletCtx, savedFields[i][0], savedFields[i][1],
-                        savedFields[i][2], false);
-                try {
-                    frame.delete(tuple, cmp, true);
-                } catch (Exception e) {
-                }
-
-                if (rnd.nextInt() % compactFreq == 0) {
-                    before = frame.printKeys(cmp, sers);
-                    frame.compact(cmp);
-                    after = frame.printKeys(cmp, sers);
-                    Assert.assertEquals(before, after);
-                }
-
-                if (rnd.nextInt() % compressFreq == 0) {
-                    before = frame.printKeys(cmp, sers);
-                    frame.compress(cmp);
-                    after = frame.printKeys(cmp, sers);
-                    Assert.assertEquals(before, after);
-                }
-            }
-
-        } finally {
-            bufferCache.unpin(page);
-        }
-
-        bufferCache.closeFile(fileId);
-        bufferCache.close();
-    }
-}
\ No newline at end of file
+		bufferCache.closeFile(fileId);
+		bufferCache.close();
+	}
+}
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTest.java b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTest.java
index e725f7c..2985601 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTest.java
@@ -66,1168 +66,1275 @@
 import edu.uci.ics.hyracks.test.support.TestUtils;
 
 @SuppressWarnings("unchecked")
-public class BTreeTest {
+public class BTreeTest extends AbstractBTreeTest {
 
-    private static final int PAGE_SIZE = 256;
-    private static final int NUM_PAGES = 10;
-    private static final int HYRACKS_FRAME_SIZE = 128;
+	private static final int PAGE_SIZE = 256;
+	private static final int NUM_PAGES = 10;
+	private static final int HYRACKS_FRAME_SIZE = 128;
+	private IHyracksStageletContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
 
-    private String tmpDir = System.getProperty("java.io.tmpdir");
-    IHyracksStageletContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
+	public class BufferAllocator implements ICacheMemoryAllocator {
+		@Override
+		public ByteBuffer[] allocate(int pageSize, int numPages) {
+			ByteBuffer[] buffers = new ByteBuffer[numPages];
+			for (int i = 0; i < numPages; ++i) {
+				buffers[i] = ByteBuffer.allocate(pageSize);
+			}
+			return buffers;
+		}
+	}
 
-    // to help with the logger madness
-    private void print(String str) {
-        System.out.print(str);
+	// FIXED-LENGTH KEY TEST
+	// create a B-tree with one fixed-length "key" field and one fixed-length
+	// "value" field
+	// fill B-tree with random values using insertions (not bulk load)
+	// perform ordered scan and range search
+	@Test
+	public void test01() throws Exception {
 
-        // if(GlobalConfig.ASTERIX_LOGGER.isLoggable(Level.FINEST)) {
-        // GlobalConfig.ASTERIX_LOGGER.finest(str);
-        // }
-    }
+		print("FIXED-LENGTH KEY TEST\n");
 
-    public class BufferAllocator implements ICacheMemoryAllocator {
-        @Override
-        public ByteBuffer[] allocate(int pageSize, int numPages) {
-            ByteBuffer[] buffers = new ByteBuffer[numPages];
-            for (int i = 0; i < numPages; ++i) {
-                buffers[i] = ByteBuffer.allocate(pageSize);
-            }
-            return buffers;
-        }
-    }
+		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
+		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);
 
-    // FIXED-LENGTH KEY TEST
-    // create a B-tree with one fixed-length "key" field and one fixed-length
-    // "value" field
-    // fill B-tree with random values using insertions (not bulk load)
-    // perform ordered scan and range search
-    @Test
-    public void test01() throws Exception {
+		// declare fields
+		int fieldCount = 2;
+		ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
+		typeTraits[0] = new TypeTrait(4);
+		typeTraits[1] = new TypeTrait(4);
 
-        print("FIXED-LENGTH KEY TEST\n");
+		// declare keys
+		int keyFieldCount = 1;
+		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+		cmps[0] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
 
-        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
-        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
-        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
-        FileReference file = new FileReference(new File(tmpDir + "/" + "btreetest.bin"));
-        bufferCache.createFile(file);
-        int fileId = fmp.lookupFileId(file);
-        bufferCache.openFile(fileId);
+		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-        // declare fields
-        int fieldCount = 2;
-        ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
-        typeTraits[0] = new TypeTrait(4);
-        typeTraits[1] = new TypeTrait(4);
+		TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(
+				typeTraits);
+		// SimpleTupleWriterFactory tupleWriterFactory = new
+		// SimpleTupleWriterFactory();
+		IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory(
+				tupleWriterFactory);
+		IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory(
+				tupleWriterFactory);
+		IBTreeMetaDataFrameFactory metaFrameFactory = new MetaDataFrameFactory();
 
-        // declare keys
-        int keyFieldCount = 1;
-        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-        cmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+		IBTreeLeafFrame leafFrame = leafFrameFactory.getFrame();
+		IBTreeInteriorFrame interiorFrame = interiorFrameFactory.getFrame();
+		IBTreeMetaDataFrame metaFrame = metaFrameFactory.getFrame();
 
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+		BTree btree = new BTree(bufferCache, interiorFrameFactory,
+				leafFrameFactory, cmp);
+		btree.create(fileId, leafFrame, metaFrame);
+		btree.open(fileId);
 
-        TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(typeTraits);
-        // SimpleTupleWriterFactory tupleWriterFactory = new
-        // SimpleTupleWriterFactory();
-        IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory(tupleWriterFactory);
-        IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory(tupleWriterFactory);
-        IBTreeMetaDataFrameFactory metaFrameFactory = new MetaDataFrameFactory();
+		Random rnd = new Random();
+		rnd.setSeed(50);
 
-        IBTreeLeafFrame leafFrame = leafFrameFactory.getFrame();
-        IBTreeInteriorFrame interiorFrame = interiorFrameFactory.getFrame();
-        IBTreeMetaDataFrame metaFrame = metaFrameFactory.getFrame();
+		long start = System.currentTimeMillis();
 
-        BTree btree = new BTree(bufferCache, interiorFrameFactory, leafFrameFactory, cmp);
-        btree.create(fileId, leafFrame, metaFrame);
-        btree.open(fileId);
+		print("INSERTING INTO TREE\n");
 
-        Random rnd = new Random();
-        rnd.setSeed(50);
+		ByteBuffer frame = ctx.allocateFrame();
+		FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+		DataOutput dos = tb.getDataOutput();
 
-        long start = System.currentTimeMillis();
+		ISerializerDeserializer[] recDescSers = {
+				IntegerSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE };
+		RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
+		IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx
+				.getFrameSize(), recDesc);
+		accessor.reset(frame);
+		FrameTupleReference tuple = new FrameTupleReference();
 
-        print("INSERTING INTO TREE\n");
+		BTreeOpContext insertOpCtx = btree.createOpContext(BTreeOp.BTO_INSERT,
+				leafFrame, interiorFrame, metaFrame);
 
-        ByteBuffer frame = ctx.allocateFrame();
-        FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
-        DataOutput dos = tb.getDataOutput();
+		// 10000
+		for (int i = 0; i < 10000; i++) {
 
-        ISerializerDeserializer[] recDescSers = { IntegerSerializerDeserializer.INSTANCE,
-                IntegerSerializerDeserializer.INSTANCE };
-        RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
-        IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(), recDesc);
-        accessor.reset(frame);
-        FrameTupleReference tuple = new FrameTupleReference();
+			int f0 = rnd.nextInt() % 10000;
+			int f1 = 5;
 
-        BTreeOpContext insertOpCtx = btree.createOpContext(BTreeOp.BTO_INSERT, leafFrame, interiorFrame, metaFrame);
+			tb.reset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(f0, dos);
+			tb.addFieldEndOffset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(f1, dos);
+			tb.addFieldEndOffset();
 
-        // 10000
-        for (int i = 0; i < 10000; i++) {
+			appender.reset(frame, true);
+			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb
+					.getSize());
 
-            int f0 = rnd.nextInt() % 10000;
-            int f1 = 5;
+			tuple.reset(accessor, 0);
 
-            tb.reset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(f0, dos);
-            tb.addFieldEndOffset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(f1, dos);
-            tb.addFieldEndOffset();
+			// System.out.println(tuple.getFieldCount() + " " +
+			// tuple.getFieldLength(0) + " " + tuple.getFieldLength(1));
 
-            appender.reset(frame, true);
-            appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
+			if (i % 1000 == 0) {
+				long end = System.currentTimeMillis();
+				print("INSERTING " + i + " : " + f0 + " " + f1 + " "
+						+ (end - start) + "\n");
+			}
 
-            tuple.reset(accessor, 0);
+			try {
+				btree.insert(tuple, insertOpCtx);
+			} catch (BTreeException e) {
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
 
-            // System.out.println(tuple.getFieldCount() + " " +
-            // tuple.getFieldLength(0) + " " + tuple.getFieldLength(1));
+			// btree.printTree(leafFrame, interiorFrame);
+			// System.out.println();
+		}
+		// btree.printTree(leafFrame, interiorFrame);
+		// System.out.println();
 
-            if (i % 1000 == 0) {
-                long end = System.currentTimeMillis();
-                print("INSERTING " + i + " : " + f0 + " " + f1 + " " + (end - start) + "\n");
-            }
+		int maxPage = btree.getMaxPage(metaFrame);
+		System.out.println("MAXPAGE: " + maxPage);
 
-            try {
-                btree.insert(tuple, insertOpCtx);
-            } catch (BTreeException e) {
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
+		String stats = btree.printStats();
+		print(stats);
 
-            // btree.printTree(leafFrame, interiorFrame);
-            // System.out.println();
-        }
-        // btree.printTree(leafFrame, interiorFrame);
-        // System.out.println();
+		long end = System.currentTimeMillis();
+		long duration = end - start;
+		print("DURATION: " + duration + "\n");
 
-        int maxPage = btree.getMaxPage(metaFrame);
-        System.out.println("MAXPAGE: " + maxPage);
+		// ordered scan
 
-        String stats = btree.printStats();
-        print(stats);
+		print("ORDERED SCAN:\n");
+		IBTreeCursor scanCursor = new RangeSearchCursor(leafFrame);
+		RangePredicate nullPred = new RangePredicate(true, null, null, true,
+				true, null, null);
+		BTreeOpContext searchOpCtx = btree.createOpContext(BTreeOp.BTO_SEARCH,
+				leafFrame, interiorFrame, null);
+		btree.search(scanCursor, nullPred, searchOpCtx);
+		try {
+			while (scanCursor.hasNext()) {
+				scanCursor.next();
+				ITupleReference frameTuple = scanCursor.getTuple();
+				String rec = cmp.printTuple(frameTuple, recDescSers);
+				print(rec + "\n");
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			scanCursor.close();
+		}
 
-        long end = System.currentTimeMillis();
-        long duration = end - start;
-        print("DURATION: " + duration + "\n");
+		// disk-order scan
+		print("DISK-ORDER SCAN:\n");
+		DiskOrderScanCursor diskOrderCursor = new DiskOrderScanCursor(leafFrame);
+		btree.diskOrderScan(diskOrderCursor, leafFrame, metaFrame);
+		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();
+		}
 
-        // ordered scan
+		// range search in [-1000, 1000]
+		print("RANGE SEARCH:\n");
 
-        print("ORDERED SCAN:\n");
-        IBTreeCursor scanCursor = new RangeSearchCursor(leafFrame);
-        RangePredicate nullPred = new RangePredicate(true, null, null, true, true, null, null);
-        BTreeOpContext searchOpCtx = btree.createOpContext(BTreeOp.BTO_SEARCH, leafFrame, interiorFrame, null);
-        btree.search(scanCursor, nullPred, searchOpCtx);
-        try {
-            while (scanCursor.hasNext()) {
-                scanCursor.next();
-                ITupleReference frameTuple = scanCursor.getTuple();
-                String rec = cmp.printTuple(frameTuple, recDescSers);
-                print(rec + "\n");
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            scanCursor.close();
-        }
+		IBTreeCursor rangeCursor = new RangeSearchCursor(leafFrame);
 
-        // disk-order scan
-        print("DISK-ORDER SCAN:\n");
-        DiskOrderScanCursor diskOrderCursor = new DiskOrderScanCursor(leafFrame);
-        btree.diskOrderScan(diskOrderCursor, leafFrame, metaFrame);
-        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();
-        }
+		// build low and high keys
+		ArrayTupleBuilder ktb = new ArrayTupleBuilder(cmp.getKeyFieldCount());
+		DataOutput kdos = ktb.getDataOutput();
 
-        // range search in [-1000, 1000]
-        print("RANGE SEARCH:\n");
+		ISerializerDeserializer[] keyDescSers = { IntegerSerializerDeserializer.INSTANCE };
+		RecordDescriptor keyDesc = new RecordDescriptor(keyDescSers);
+		IFrameTupleAccessor keyAccessor = new FrameTupleAccessor(ctx
+				.getFrameSize(), keyDesc);
+		keyAccessor.reset(frame);
 
-        IBTreeCursor rangeCursor = new RangeSearchCursor(leafFrame);
+		appender.reset(frame, true);
 
-        // build low and high keys
-        ArrayTupleBuilder ktb = new ArrayTupleBuilder(cmp.getKeyFieldCount());
-        DataOutput kdos = ktb.getDataOutput();
+		// build and append low key
+		ktb.reset();
+		IntegerSerializerDeserializer.INSTANCE.serialize(-1000, kdos);
+		ktb.addFieldEndOffset();
+		appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb
+				.getSize());
 
-        ISerializerDeserializer[] keyDescSers = { IntegerSerializerDeserializer.INSTANCE };
-        RecordDescriptor keyDesc = new RecordDescriptor(keyDescSers);
-        IFrameTupleAccessor keyAccessor = new FrameTupleAccessor(ctx.getFrameSize(), keyDesc);
-        keyAccessor.reset(frame);
+		// build and append high key
+		ktb.reset();
+		IntegerSerializerDeserializer.INSTANCE.serialize(1000, kdos);
+		ktb.addFieldEndOffset();
+		appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb
+				.getSize());
 
-        appender.reset(frame, true);
+		// create tuplereferences for search keys
+		FrameTupleReference lowKey = new FrameTupleReference();
+		lowKey.reset(keyAccessor, 0);
 
-        // build and append low key
-        ktb.reset();
-        IntegerSerializerDeserializer.INSTANCE.serialize(-1000, kdos);
-        ktb.addFieldEndOffset();
-        appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb.getSize());
+		FrameTupleReference highKey = new FrameTupleReference();
+		highKey.reset(keyAccessor, 1);
 
-        // build and append high key
-        ktb.reset();
-        IntegerSerializerDeserializer.INSTANCE.serialize(1000, kdos);
-        ktb.addFieldEndOffset();
-        appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb.getSize());
+		IBinaryComparator[] searchCmps = new IBinaryComparator[1];
+		searchCmps[0] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		MultiComparator searchCmp = new MultiComparator(typeTraits, searchCmps);
 
-        // create tuplereferences for search keys
-        FrameTupleReference lowKey = new FrameTupleReference();
-        lowKey.reset(keyAccessor, 0);
+		RangePredicate rangePred = new RangePredicate(true, lowKey, highKey,
+				true, true, searchCmp, searchCmp);
+		btree.search(rangeCursor, rangePred, searchOpCtx);
 
-        FrameTupleReference highKey = new FrameTupleReference();
-        highKey.reset(keyAccessor, 1);
+		try {
+			while (rangeCursor.hasNext()) {
+				rangeCursor.next();
+				ITupleReference frameTuple = rangeCursor.getTuple();
+				String rec = cmp.printTuple(frameTuple, recDescSers);
+				print(rec + "\n");
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			rangeCursor.close();
+		}
 
-        IBinaryComparator[] searchCmps = new IBinaryComparator[1];
-        searchCmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        MultiComparator searchCmp = new MultiComparator(typeTraits, searchCmps);
+		btree.close();
+		bufferCache.closeFile(fileId);
+		bufferCache.close();
 
-        RangePredicate rangePred = new RangePredicate(true, lowKey, highKey, true, true, searchCmp, searchCmp);
-        btree.search(rangeCursor, rangePred, searchOpCtx);
+		print("\n");
+	}
 
-        try {
-            while (rangeCursor.hasNext()) {
-                rangeCursor.next();
-                ITupleReference frameTuple = rangeCursor.getTuple();
-                String rec = cmp.printTuple(frameTuple, recDescSers);
-                print(rec + "\n");
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            rangeCursor.close();
-        }
+	// COMPOSITE KEY TEST (NON-UNIQUE B-TREE)
+	// create a B-tree with one two fixed-length "key" fields and one
+	// fixed-length "value" field
+	// fill B-tree with random values using insertions (not bulk load)
+	// perform ordered scan and range search
+	@Test
+	public void test02() throws Exception {
 
-        btree.close();
-        bufferCache.closeFile(fileId);
-        bufferCache.close();
+		print("COMPOSITE KEY TEST\n");
 
-        print("\n");
-    }
+		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
+		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);
 
-    // COMPOSITE KEY TEST (NON-UNIQUE B-TREE)
-    // create a B-tree with one two fixed-length "key" fields and one
-    // fixed-length "value" field
-    // fill B-tree with random values using insertions (not bulk load)
-    // perform ordered scan and range search
-    @Test
-    public void test02() throws Exception {
+		// declare fields
+		int fieldCount = 3;
+		ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
+		typeTraits[0] = new TypeTrait(4);
+		typeTraits[1] = new TypeTrait(4);
+		typeTraits[2] = new TypeTrait(4);
 
-        print("COMPOSITE KEY TEST\n");
+		// declare keys
+		int keyFieldCount = 2;
+		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+		cmps[0] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		cmps[1] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
 
-        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
-        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
-        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
-        FileReference file = new FileReference(new File(tmpDir + "/" + "btreetest.bin"));
-        bufferCache.createFile(file);
-        int fileId = fmp.lookupFileId(file);
-        bufferCache.openFile(fileId);
+		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-        // declare fields
-        int fieldCount = 3;
-        ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
-        typeTraits[0] = new TypeTrait(4);
-        typeTraits[1] = new TypeTrait(4);
-        typeTraits[2] = new TypeTrait(4);
+		TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(
+				typeTraits);
+		// SimpleTupleWriterFactory tupleWriterFactory = new
+		// SimpleTupleWriterFactory();
+		IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory(
+				tupleWriterFactory);
+		IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory(
+				tupleWriterFactory);
+		IBTreeMetaDataFrameFactory metaFrameFactory = new MetaDataFrameFactory();
 
-        // declare keys
-        int keyFieldCount = 2;
-        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-        cmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        cmps[1] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+		IBTreeLeafFrame leafFrame = leafFrameFactory.getFrame();
+		IBTreeInteriorFrame interiorFrame = interiorFrameFactory.getFrame();
+		IBTreeMetaDataFrame metaFrame = metaFrameFactory.getFrame();
 
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+		BTree btree = new BTree(bufferCache, interiorFrameFactory,
+				leafFrameFactory, cmp);
+		btree.create(fileId, leafFrame, metaFrame);
+		btree.open(fileId);
 
-        TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(typeTraits);
-        // SimpleTupleWriterFactory tupleWriterFactory = new
-        // SimpleTupleWriterFactory();
-        IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory(tupleWriterFactory);
-        IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory(tupleWriterFactory);
-        IBTreeMetaDataFrameFactory metaFrameFactory = new MetaDataFrameFactory();
+		Random rnd = new Random();
+		rnd.setSeed(50);
 
-        IBTreeLeafFrame leafFrame = leafFrameFactory.getFrame();
-        IBTreeInteriorFrame interiorFrame = interiorFrameFactory.getFrame();
-        IBTreeMetaDataFrame metaFrame = metaFrameFactory.getFrame();
+		long start = System.currentTimeMillis();
 
-        BTree btree = new BTree(bufferCache, interiorFrameFactory, leafFrameFactory, cmp);
-        btree.create(fileId, leafFrame, metaFrame);
-        btree.open(fileId);
+		print("INSERTING INTO TREE\n");
 
-        Random rnd = new Random();
-        rnd.setSeed(50);
+		ByteBuffer frame = ctx.allocateFrame();
+		FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+		DataOutput dos = tb.getDataOutput();
 
-        long start = System.currentTimeMillis();
+		ISerializerDeserializer[] recDescSers = {
+				IntegerSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE };
+		RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
+		IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx
+				.getFrameSize(), recDesc);
+		accessor.reset(frame);
+		FrameTupleReference tuple = new FrameTupleReference();
 
-        print("INSERTING INTO TREE\n");
+		BTreeOpContext insertOpCtx = btree.createOpContext(BTreeOp.BTO_INSERT,
+				leafFrame, interiorFrame, metaFrame);
 
-        ByteBuffer frame = ctx.allocateFrame();
-        FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
-        DataOutput dos = tb.getDataOutput();
+		for (int i = 0; i < 10000; i++) {
+			int f0 = rnd.nextInt() % 2000;
+			int f1 = rnd.nextInt() % 1000;
+			int f2 = 5;
 
-        ISerializerDeserializer[] recDescSers = { IntegerSerializerDeserializer.INSTANCE,
-                IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
-        RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
-        IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(), recDesc);
-        accessor.reset(frame);
-        FrameTupleReference tuple = new FrameTupleReference();
+			tb.reset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(f0, dos);
+			tb.addFieldEndOffset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(f1, dos);
+			tb.addFieldEndOffset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(f2, dos);
+			tb.addFieldEndOffset();
 
-        BTreeOpContext insertOpCtx = btree.createOpContext(BTreeOp.BTO_INSERT, leafFrame, interiorFrame, metaFrame);
+			appender.reset(frame, true);
+			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb
+					.getSize());
 
-        for (int i = 0; i < 10000; i++) {
-            int f0 = rnd.nextInt() % 2000;
-            int f1 = rnd.nextInt() % 1000;
-            int f2 = 5;
+			tuple.reset(accessor, 0);
 
-            tb.reset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(f0, dos);
-            tb.addFieldEndOffset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(f1, dos);
-            tb.addFieldEndOffset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(f2, dos);
-            tb.addFieldEndOffset();
+			if (i % 1000 == 0) {
+				print("INSERTING " + i + " : " + f0 + " " + f1 + "\n");
+			}
 
-            appender.reset(frame, true);
-            appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
+			try {
+				btree.insert(tuple, insertOpCtx);
+			} catch (Exception e) {
+			}
+		}
+		// btree.printTree(leafFrame, interiorFrame);
 
-            tuple.reset(accessor, 0);
+		long end = System.currentTimeMillis();
+		long duration = end - start;
+		print("DURATION: " + duration + "\n");
 
-            if (i % 1000 == 0) {
-                print("INSERTING " + i + " : " + f0 + " " + f1 + "\n");
-            }
+		// try a simple index scan
+		print("ORDERED SCAN:\n");
+		IBTreeCursor scanCursor = new RangeSearchCursor(leafFrame);
+		RangePredicate nullPred = new RangePredicate(true, null, null, true,
+				true, null, null);
+		BTreeOpContext searchOpCtx = btree.createOpContext(BTreeOp.BTO_SEARCH,
+				leafFrame, interiorFrame, null);
+		btree.search(scanCursor, nullPred, searchOpCtx);
 
-            try {
-                btree.insert(tuple, insertOpCtx);
-            } catch (Exception e) {
-            }
-        }
-        // btree.printTree(leafFrame, interiorFrame);
+		try {
+			while (scanCursor.hasNext()) {
+				scanCursor.next();
+				ITupleReference frameTuple = scanCursor.getTuple();
+				String rec = cmp.printTuple(frameTuple, recDescSers);
+				print(rec + "\n");
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			scanCursor.close();
+		}
 
-        long end = System.currentTimeMillis();
-        long duration = end - start;
-        print("DURATION: " + duration + "\n");
+		// range search in [(-3),(3)]
+		print("RANGE SEARCH:\n");
+		IBTreeCursor rangeCursor = new RangeSearchCursor(leafFrame);
 
-        // try a simple index scan
-        print("ORDERED SCAN:\n");
-        IBTreeCursor scanCursor = new RangeSearchCursor(leafFrame);
-        RangePredicate nullPred = new RangePredicate(true, null, null, true, true, null, null);
-        BTreeOpContext searchOpCtx = btree.createOpContext(BTreeOp.BTO_SEARCH, leafFrame, interiorFrame, null);
-        btree.search(scanCursor, nullPred, searchOpCtx);
+		// build low and high keys
+		ArrayTupleBuilder ktb = new ArrayTupleBuilder(cmp.getKeyFieldCount());
+		DataOutput kdos = ktb.getDataOutput();
 
-        try {
-            while (scanCursor.hasNext()) {
-                scanCursor.next();
-                ITupleReference frameTuple = scanCursor.getTuple();
-                String rec = cmp.printTuple(frameTuple, recDescSers);
-                print(rec + "\n");
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            scanCursor.close();
-        }
+		ISerializerDeserializer[] keyDescSers = { IntegerSerializerDeserializer.INSTANCE };
+		RecordDescriptor keyDesc = new RecordDescriptor(keyDescSers);
+		IFrameTupleAccessor keyAccessor = new FrameTupleAccessor(ctx
+				.getFrameSize(), keyDesc);
+		keyAccessor.reset(frame);
 
-        // range search in [(-3),(3)]
-        print("RANGE SEARCH:\n");
-        IBTreeCursor rangeCursor = new RangeSearchCursor(leafFrame);
+		appender.reset(frame, true);
 
-        // build low and high keys
-        ArrayTupleBuilder ktb = new ArrayTupleBuilder(cmp.getKeyFieldCount());
-        DataOutput kdos = ktb.getDataOutput();
+		// build and append low key
+		ktb.reset();
+		IntegerSerializerDeserializer.INSTANCE.serialize(-3, kdos);
+		ktb.addFieldEndOffset();
+		appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb
+				.getSize());
 
-        ISerializerDeserializer[] keyDescSers = { IntegerSerializerDeserializer.INSTANCE };
-        RecordDescriptor keyDesc = new RecordDescriptor(keyDescSers);
-        IFrameTupleAccessor keyAccessor = new FrameTupleAccessor(ctx.getFrameSize(), keyDesc);
-        keyAccessor.reset(frame);
+		// build and append high key
+		ktb.reset();
+		IntegerSerializerDeserializer.INSTANCE.serialize(3, kdos);
+		ktb.addFieldEndOffset();
+		appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb
+				.getSize());
 
-        appender.reset(frame, true);
+		// create tuplereferences for search keys
+		FrameTupleReference lowKey = new FrameTupleReference();
+		lowKey.reset(keyAccessor, 0);
 
-        // build and append low key
-        ktb.reset();
-        IntegerSerializerDeserializer.INSTANCE.serialize(-3, kdos);
-        ktb.addFieldEndOffset();
-        appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb.getSize());
+		FrameTupleReference highKey = new FrameTupleReference();
+		highKey.reset(keyAccessor, 1);
 
-        // build and append high key
-        ktb.reset();
-        IntegerSerializerDeserializer.INSTANCE.serialize(3, kdos);
-        ktb.addFieldEndOffset();
-        appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb.getSize());
+		IBinaryComparator[] searchCmps = new IBinaryComparator[1];
+		searchCmps[0] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		MultiComparator searchCmp = new MultiComparator(typeTraits, searchCmps); // use
+		// only
+		// a
+		// single
+		// comparator
+		// for
+		// searching
 
-        // create tuplereferences for search keys
-        FrameTupleReference lowKey = new FrameTupleReference();
-        lowKey.reset(keyAccessor, 0);
+		RangePredicate rangePred = new RangePredicate(true, lowKey, highKey,
+				true, true, searchCmp, searchCmp);
+		btree.search(rangeCursor, rangePred, searchOpCtx);
 
-        FrameTupleReference highKey = new FrameTupleReference();
-        highKey.reset(keyAccessor, 1);
+		try {
+			while (rangeCursor.hasNext()) {
+				rangeCursor.next();
+				ITupleReference frameTuple = rangeCursor.getTuple();
+				String rec = cmp.printTuple(frameTuple, recDescSers);
+				print(rec + "\n");
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			rangeCursor.close();
+		}
 
-        IBinaryComparator[] searchCmps = new IBinaryComparator[1];
-        searchCmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        MultiComparator searchCmp = new MultiComparator(typeTraits, searchCmps); // use
-        // only
-        // a
-        // single
-        // comparator
-        // for
-        // searching
+		btree.close();
+		bufferCache.closeFile(fileId);
+		bufferCache.close();
 
-        RangePredicate rangePred = new RangePredicate(true, lowKey, highKey, true, true, searchCmp, searchCmp);
-        btree.search(rangeCursor, rangePred, searchOpCtx);
+		print("\n");
+	}
 
-        try {
-            while (rangeCursor.hasNext()) {
-                rangeCursor.next();
-                ITupleReference frameTuple = rangeCursor.getTuple();
-                String rec = cmp.printTuple(frameTuple, recDescSers);
-                print(rec + "\n");
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            rangeCursor.close();
-        }
+	// VARIABLE-LENGTH TEST
+	// create a B-tree with one variable-length "key" field and one
+	// variable-length "value" field
+	// fill B-tree with random values using insertions (not bulk load)
+	// perform ordered scan and range search
+	@Test
+	public void test03() throws Exception {
 
-        btree.close();
-        bufferCache.closeFile(fileId);
-        bufferCache.close();
+		print("VARIABLE-LENGTH KEY TEST\n");
 
-        print("\n");
-    }
+		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
+		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);
 
-    // VARIABLE-LENGTH TEST
-    // create a B-tree with one variable-length "key" field and one
-    // variable-length "value" field
-    // fill B-tree with random values using insertions (not bulk load)
-    // perform ordered scan and range search
-    @Test
-    public void test03() throws Exception {
+		// declare fields
+		int fieldCount = 2;
+		ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
+		typeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+		typeTraits[1] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
 
-        print("VARIABLE-LENGTH KEY TEST\n");
+		// declare keys
+		int keyFieldCount = 1;
+		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+		cmps[0] = UTF8StringBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
 
-        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
-        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
-        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
-        FileReference file = new FileReference(new File(tmpDir + "/" + "btreetest.bin"));
-        bufferCache.createFile(file);
-        int fileId = fmp.lookupFileId(file);
-        bufferCache.openFile(fileId);
+		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-        // declare fields
-        int fieldCount = 2;
-        ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
-        typeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-        typeTraits[1] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+		SimpleTupleWriterFactory tupleWriterFactory = new SimpleTupleWriterFactory();
+		// TypeAwareTupleWriterFactory tupleWriterFactory = new
+		// TypeAwareTupleWriterFactory(typeTraits);
+		IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory(
+				tupleWriterFactory);
+		IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory(
+				tupleWriterFactory);
+		IBTreeMetaDataFrameFactory metaFrameFactory = new MetaDataFrameFactory();
 
-        // declare keys
-        int keyFieldCount = 1;
-        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-        cmps[0] = UTF8StringBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+		IBTreeLeafFrame leafFrame = leafFrameFactory.getFrame();
+		IBTreeInteriorFrame interiorFrame = interiorFrameFactory.getFrame();
+		IBTreeMetaDataFrame metaFrame = metaFrameFactory.getFrame();
 
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+		BTree btree = new BTree(bufferCache, interiorFrameFactory,
+				leafFrameFactory, cmp);
+		btree.create(fileId, leafFrame, metaFrame);
+		btree.open(fileId);
 
-        SimpleTupleWriterFactory tupleWriterFactory = new SimpleTupleWriterFactory();
-        // TypeAwareTupleWriterFactory tupleWriterFactory = new
-        // TypeAwareTupleWriterFactory(typeTraits);
-        IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory(tupleWriterFactory);
-        IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory(tupleWriterFactory);
-        IBTreeMetaDataFrameFactory metaFrameFactory = new MetaDataFrameFactory();
+		Random rnd = new Random();
+		rnd.setSeed(50);
 
-        IBTreeLeafFrame leafFrame = leafFrameFactory.getFrame();
-        IBTreeInteriorFrame interiorFrame = interiorFrameFactory.getFrame();
-        IBTreeMetaDataFrame metaFrame = metaFrameFactory.getFrame();
+		ByteBuffer frame = ctx.allocateFrame();
+		FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+		DataOutput dos = tb.getDataOutput();
 
-        BTree btree = new BTree(bufferCache, interiorFrameFactory, leafFrameFactory, cmp);
-        btree.create(fileId, leafFrame, metaFrame);
-        btree.open(fileId);
+		ISerializerDeserializer[] recDescSers = {
+				UTF8StringSerializerDeserializer.INSTANCE,
+				UTF8StringSerializerDeserializer.INSTANCE };
+		RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
+		IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx
+				.getFrameSize(), recDesc);
+		accessor.reset(frame);
+		FrameTupleReference tuple = new FrameTupleReference();
 
-        Random rnd = new Random();
-        rnd.setSeed(50);
+		BTreeOpContext insertOpCtx = btree.createOpContext(BTreeOp.BTO_INSERT,
+				leafFrame, interiorFrame, metaFrame);
+		int maxLength = 10; // max string length to be generated
+		for (int i = 0; i < 10000; i++) {
 
-        ByteBuffer frame = ctx.allocateFrame();
-        FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
-        DataOutput dos = tb.getDataOutput();
+			String f0 = randomString(Math.abs(rnd.nextInt()) % maxLength + 1,
+					rnd);
+			String f1 = randomString(Math.abs(rnd.nextInt()) % maxLength + 1,
+					rnd);
 
-        ISerializerDeserializer[] recDescSers = { UTF8StringSerializerDeserializer.INSTANCE,
-                UTF8StringSerializerDeserializer.INSTANCE };
-        RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
-        IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(), recDesc);
-        accessor.reset(frame);
-        FrameTupleReference tuple = new FrameTupleReference();
+			tb.reset();
+			UTF8StringSerializerDeserializer.INSTANCE.serialize(f0, dos);
+			tb.addFieldEndOffset();
+			UTF8StringSerializerDeserializer.INSTANCE.serialize(f1, dos);
+			tb.addFieldEndOffset();
 
-        BTreeOpContext insertOpCtx = btree.createOpContext(BTreeOp.BTO_INSERT, leafFrame, interiorFrame, metaFrame);
-        int maxLength = 10; // max string length to be generated
-        for (int i = 0; i < 10000; i++) {
+			appender.reset(frame, true);
+			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb
+					.getSize());
 
-            String f0 = randomString(Math.abs(rnd.nextInt()) % maxLength + 1, rnd);
-            String f1 = randomString(Math.abs(rnd.nextInt()) % maxLength + 1, rnd);
+			tuple.reset(accessor, 0);
 
-            tb.reset();
-            UTF8StringSerializerDeserializer.INSTANCE.serialize(f0, dos);
-            tb.addFieldEndOffset();
-            UTF8StringSerializerDeserializer.INSTANCE.serialize(f1, dos);
-            tb.addFieldEndOffset();
+			if (i % 1000 == 0) {
+				// print("INSERTING " + i + ": " + cmp.printRecord(record, 0) +
+				// "\n");
+				print("INSERTING " + i + "\n");
+			}
 
-            appender.reset(frame, true);
-            appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
+			try {
+				btree.insert(tuple, insertOpCtx);
+			} catch (Exception e) {
+				// e.printStackTrace();
+			}
+		}
+		// btree.printTree();
 
-            tuple.reset(accessor, 0);
+		System.out.println("DONE INSERTING");
 
-            if (i % 1000 == 0) {
-                // print("INSERTING " + i + ": " + cmp.printRecord(record, 0) +
-                // "\n");
-                print("INSERTING " + i + "\n");
-            }
+		// ordered scan
+		print("ORDERED SCAN:\n");
+		IBTreeCursor scanCursor = new RangeSearchCursor(leafFrame);
+		RangePredicate nullPred = new RangePredicate(true, null, null, true,
+				true, null, null);
+		BTreeOpContext searchOpCtx = btree.createOpContext(BTreeOp.BTO_SEARCH,
+				leafFrame, interiorFrame, null);
+		btree.search(scanCursor, nullPred, searchOpCtx);
 
-            try {
-                btree.insert(tuple, insertOpCtx);
-            } catch (Exception e) {
-                // e.printStackTrace();
-            }
-        }
-        // btree.printTree();
+		try {
+			while (scanCursor.hasNext()) {
+				scanCursor.next();
+				ITupleReference frameTuple = scanCursor.getTuple();
+				String rec = cmp.printTuple(frameTuple, recDescSers);
+				print(rec + "\n");
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			scanCursor.close();
+		}
 
-        System.out.println("DONE INSERTING");
+		// range search in ["cbf", cc7"]
+		print("RANGE SEARCH:\n");
 
-        // ordered scan
-        print("ORDERED SCAN:\n");
-        IBTreeCursor scanCursor = new RangeSearchCursor(leafFrame);
-        RangePredicate nullPred = new RangePredicate(true, null, null, true, true, null, null);
-        BTreeOpContext searchOpCtx = btree.createOpContext(BTreeOp.BTO_SEARCH, leafFrame, interiorFrame, null);
-        btree.search(scanCursor, nullPred, searchOpCtx);
+		IBTreeCursor rangeCursor = new RangeSearchCursor(leafFrame);
 
-        try {
-            while (scanCursor.hasNext()) {
-                scanCursor.next();
-                ITupleReference frameTuple = scanCursor.getTuple();
-                String rec = cmp.printTuple(frameTuple, recDescSers);
-                print(rec + "\n");
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            scanCursor.close();
-        }
+		// build low and high keys
+		ArrayTupleBuilder ktb = new ArrayTupleBuilder(cmp.getKeyFieldCount());
+		DataOutput kdos = ktb.getDataOutput();
 
-        // range search in ["cbf", cc7"]
-        print("RANGE SEARCH:\n");
+		ISerializerDeserializer[] keyDescSers = { UTF8StringSerializerDeserializer.INSTANCE };
+		RecordDescriptor keyDesc = new RecordDescriptor(keyDescSers);
+		IFrameTupleAccessor keyAccessor = new FrameTupleAccessor(ctx
+				.getFrameSize(), keyDesc);
+		keyAccessor.reset(frame);
 
-        IBTreeCursor rangeCursor = new RangeSearchCursor(leafFrame);
+		appender.reset(frame, true);
 
-        // build low and high keys
-        ArrayTupleBuilder ktb = new ArrayTupleBuilder(cmp.getKeyFieldCount());
-        DataOutput kdos = ktb.getDataOutput();
+		// build and append low key
+		ktb.reset();
+		UTF8StringSerializerDeserializer.INSTANCE.serialize("cbf", kdos);
+		ktb.addFieldEndOffset();
+		appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb
+				.getSize());
 
-        ISerializerDeserializer[] keyDescSers = { UTF8StringSerializerDeserializer.INSTANCE };
-        RecordDescriptor keyDesc = new RecordDescriptor(keyDescSers);
-        IFrameTupleAccessor keyAccessor = new FrameTupleAccessor(ctx.getFrameSize(), keyDesc);
-        keyAccessor.reset(frame);
+		// build and append high key
+		ktb.reset();
+		UTF8StringSerializerDeserializer.INSTANCE.serialize("cc7", kdos);
+		ktb.addFieldEndOffset();
+		appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb
+				.getSize());
 
-        appender.reset(frame, true);
+		// create tuplereferences for search keys
+		FrameTupleReference lowKey = new FrameTupleReference();
+		lowKey.reset(keyAccessor, 0);
 
-        // build and append low key
-        ktb.reset();
-        UTF8StringSerializerDeserializer.INSTANCE.serialize("cbf", kdos);
-        ktb.addFieldEndOffset();
-        appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb.getSize());
+		FrameTupleReference highKey = new FrameTupleReference();
+		highKey.reset(keyAccessor, 1);
 
-        // build and append high key
-        ktb.reset();
-        UTF8StringSerializerDeserializer.INSTANCE.serialize("cc7", kdos);
-        ktb.addFieldEndOffset();
-        appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb.getSize());
+		IBinaryComparator[] searchCmps = new IBinaryComparator[1];
+		searchCmps[0] = UTF8StringBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		MultiComparator searchCmp = new MultiComparator(typeTraits, searchCmps);
 
-        // create tuplereferences for search keys
-        FrameTupleReference lowKey = new FrameTupleReference();
-        lowKey.reset(keyAccessor, 0);
+		RangePredicate rangePred = new RangePredicate(true, lowKey, highKey,
+				true, true, searchCmp, searchCmp);
+		btree.search(rangeCursor, rangePred, searchOpCtx);
 
-        FrameTupleReference highKey = new FrameTupleReference();
-        highKey.reset(keyAccessor, 1);
-
-        IBinaryComparator[] searchCmps = new IBinaryComparator[1];
-        searchCmps[0] = UTF8StringBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        MultiComparator searchCmp = new MultiComparator(typeTraits, searchCmps);
-
-        RangePredicate rangePred = new RangePredicate(true, lowKey, highKey, true, true, searchCmp, searchCmp);
-        btree.search(rangeCursor, rangePred, searchOpCtx);
-
-        try {
-            while (rangeCursor.hasNext()) {
-                rangeCursor.next();
-                ITupleReference frameTuple = rangeCursor.getTuple();
-                String rec = cmp.printTuple(frameTuple, recDescSers);
-                print(rec + "\n");
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            rangeCursor.close();
-        }
+		try {
+			while (rangeCursor.hasNext()) {
+				rangeCursor.next();
+				ITupleReference frameTuple = rangeCursor.getTuple();
+				String rec = cmp.printTuple(frameTuple, recDescSers);
+				print(rec + "\n");
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			rangeCursor.close();
+		}
 
-        btree.close();
-        bufferCache.closeFile(fileId);
-        bufferCache.close();
+		btree.close();
+		bufferCache.closeFile(fileId);
+		bufferCache.close();
 
-        print("\n");
-    }
+		print("\n");
+	}
 
-    // DELETION TEST
-    // create a B-tree with one variable-length "key" field and one
-    // variable-length "value" field
-    // fill B-tree with random values using insertions, then delete entries
-    // one-by-one
-    // repeat procedure a few times on same B-tree
-    @Test
-    public void test04() throws Exception {
+	// DELETION TEST
+	// create a B-tree with one variable-length "key" field and one
+	// variable-length "value" field
+	// fill B-tree with random values using insertions, then delete entries
+	// one-by-one
+	// repeat procedure a few times on same B-tree
+	@Test
+	public void test04() throws Exception {
 
-        print("DELETION TEST\n");
+		print("DELETION TEST\n");
 
-        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
-        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
-        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
-        FileReference file = new FileReference(new File(tmpDir + "/" + "btreetest.bin"));
-        bufferCache.createFile(file);
-        int fileId = fmp.lookupFileId(file);
-        bufferCache.openFile(fileId);
+		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
+		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 fields
-        int fieldCount = 2;
-        ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
-        typeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
-        typeTraits[1] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+		// declare fields
+		int fieldCount = 2;
+		ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
+		typeTraits[0] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
+		typeTraits[1] = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);
 
-        // declare keys
-        int keyFieldCount = 1;
-        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-        cmps[0] = UTF8StringBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+		// declare keys
+		int keyFieldCount = 1;
+		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+		cmps[0] = UTF8StringBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
 
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-        // SimpleTupleWriterFactory tupleWriterFactory = new
-        // SimpleTupleWriterFactory();
-        TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(typeTraits);
-        IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory(tupleWriterFactory);
-        IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory(tupleWriterFactory);
-        IBTreeMetaDataFrameFactory metaFrameFactory = new MetaDataFrameFactory();
+		// SimpleTupleWriterFactory tupleWriterFactory = new
+		// SimpleTupleWriterFactory();
+		TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(
+				typeTraits);
+		IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory(
+				tupleWriterFactory);
+		IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory(
+				tupleWriterFactory);
+		IBTreeMetaDataFrameFactory metaFrameFactory = new MetaDataFrameFactory();
 
-        IBTreeLeafFrame leafFrame = leafFrameFactory.getFrame();
-        IBTreeInteriorFrame interiorFrame = interiorFrameFactory.getFrame();
-        IBTreeMetaDataFrame metaFrame = metaFrameFactory.getFrame();
+		IBTreeLeafFrame leafFrame = leafFrameFactory.getFrame();
+		IBTreeInteriorFrame interiorFrame = interiorFrameFactory.getFrame();
+		IBTreeMetaDataFrame metaFrame = metaFrameFactory.getFrame();
 
-        BTree btree = new BTree(bufferCache, interiorFrameFactory, leafFrameFactory, cmp);
-        btree.create(fileId, leafFrame, metaFrame);
-        btree.open(fileId);
+		BTree btree = new BTree(bufferCache, interiorFrameFactory,
+				leafFrameFactory, cmp);
+		btree.create(fileId, leafFrame, metaFrame);
+		btree.open(fileId);
 
-        Random rnd = new Random();
-        rnd.setSeed(50);
+		Random rnd = new Random();
+		rnd.setSeed(50);
 
-        ByteBuffer frame = ctx.allocateFrame();
-        FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
-        DataOutput dos = tb.getDataOutput();
+		ByteBuffer frame = ctx.allocateFrame();
+		FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+		DataOutput dos = tb.getDataOutput();
 
-        ISerializerDeserializer[] recDescSers = { UTF8StringSerializerDeserializer.INSTANCE,
-                UTF8StringSerializerDeserializer.INSTANCE };
-        RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
-        IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(), recDesc);
-        accessor.reset(frame);
-        FrameTupleReference tuple = new FrameTupleReference();
+		ISerializerDeserializer[] recDescSers = {
+				UTF8StringSerializerDeserializer.INSTANCE,
+				UTF8StringSerializerDeserializer.INSTANCE };
+		RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
+		IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx
+				.getFrameSize(), recDesc);
+		accessor.reset(frame);
+		FrameTupleReference tuple = new FrameTupleReference();
 
-        BTreeOpContext insertOpCtx = btree.createOpContext(BTreeOp.BTO_INSERT, leafFrame, interiorFrame, metaFrame);
-        BTreeOpContext deleteOpCtx = btree.createOpContext(BTreeOp.BTO_DELETE, leafFrame, interiorFrame, metaFrame);
+		BTreeOpContext insertOpCtx = btree.createOpContext(BTreeOp.BTO_INSERT,
+				leafFrame, interiorFrame, metaFrame);
+		BTreeOpContext deleteOpCtx = btree.createOpContext(BTreeOp.BTO_DELETE,
+				leafFrame, interiorFrame, metaFrame);
 
-        int runs = 3;
-        for (int run = 0; run < runs; run++) {
+		int runs = 3;
+		for (int run = 0; run < runs; run++) {
 
-            print("DELETION TEST RUN: " + (run + 1) + "/" + runs + "\n");
+			print("DELETION TEST RUN: " + (run + 1) + "/" + runs + "\n");
 
-            print("INSERTING INTO BTREE\n");
-            int maxLength = 10;
-            int ins = 10000;
-            String[] f0s = new String[ins];
-            String[] f1s = new String[ins];
-            int insDone = 0;
-            int[] insDoneCmp = new int[ins];
-            for (int i = 0; i < ins; i++) {
-                String f0 = randomString(Math.abs(rnd.nextInt()) % maxLength + 1, rnd);
-                String f1 = randomString(Math.abs(rnd.nextInt()) % maxLength + 1, rnd);
+			print("INSERTING INTO BTREE\n");
+			int maxLength = 10;
+			int ins = 10000;
+			String[] f0s = new String[ins];
+			String[] f1s = new String[ins];
+			int insDone = 0;
+			int[] insDoneCmp = new int[ins];
+			for (int i = 0; i < ins; i++) {
+				String f0 = randomString(Math.abs(rnd.nextInt()) % maxLength
+						+ 1, rnd);
+				String f1 = randomString(Math.abs(rnd.nextInt()) % maxLength
+						+ 1, rnd);
 
-                f0s[i] = f0;
-                f1s[i] = f1;
+				f0s[i] = f0;
+				f1s[i] = f1;
 
-                tb.reset();
-                UTF8StringSerializerDeserializer.INSTANCE.serialize(f0, dos);
-                tb.addFieldEndOffset();
-                UTF8StringSerializerDeserializer.INSTANCE.serialize(f1, dos);
-                tb.addFieldEndOffset();
+				tb.reset();
+				UTF8StringSerializerDeserializer.INSTANCE.serialize(f0, dos);
+				tb.addFieldEndOffset();
+				UTF8StringSerializerDeserializer.INSTANCE.serialize(f1, dos);
+				tb.addFieldEndOffset();
 
-                appender.reset(frame, true);
-                appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
+				appender.reset(frame, true);
+				appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0,
+						tb.getSize());
 
-                tuple.reset(accessor, 0);
+				tuple.reset(accessor, 0);
 
-                if (i % 1000 == 0) {
-                    print("INSERTING " + i + "\n");
-                    // print("INSERTING " + i + ": " + cmp.printRecord(record,
-                    // 0) + "\n");
-                }
+				if (i % 1000 == 0) {
+					print("INSERTING " + i + "\n");
+					// print("INSERTING " + i + ": " + cmp.printRecord(record,
+					// 0) + "\n");
+				}
 
-                try {
-                    btree.insert(tuple, insertOpCtx);
-                    insDone++;
-                } catch (BTreeException e) {
-                    // e.printStackTrace();
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
+				try {
+					btree.insert(tuple, insertOpCtx);
+					insDone++;
+				} catch (BTreeException e) {
+					// e.printStackTrace();
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
 
-                insDoneCmp[i] = insDone;
-            }
-            // btree.printTree();
-            // btree.printStats();
+				insDoneCmp[i] = insDone;
+			}
+			// btree.printTree();
+			// btree.printStats();
 
-            print("DELETING FROM BTREE\n");
-            int delDone = 0;
-            for (int i = 0; i < ins; i++) {
+			print("DELETING FROM BTREE\n");
+			int delDone = 0;
+			for (int i = 0; i < ins; i++) {
 
-                tb.reset();
-                UTF8StringSerializerDeserializer.INSTANCE.serialize(f0s[i], dos);
-                tb.addFieldEndOffset();
-                UTF8StringSerializerDeserializer.INSTANCE.serialize(f1s[i], dos);
-                tb.addFieldEndOffset();
+				tb.reset();
+				UTF8StringSerializerDeserializer.INSTANCE
+						.serialize(f0s[i], dos);
+				tb.addFieldEndOffset();
+				UTF8StringSerializerDeserializer.INSTANCE
+						.serialize(f1s[i], dos);
+				tb.addFieldEndOffset();
 
-                appender.reset(frame, true);
-                appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
+				appender.reset(frame, true);
+				appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0,
+						tb.getSize());
 
-                tuple.reset(accessor, 0);
+				tuple.reset(accessor, 0);
 
-                if (i % 1000 == 0) {
-                    // print("DELETING " + i + ": " +
-                    // cmp.printRecord(records[i], 0) + "\n");
-                    print("DELETING " + i + "\n");
-                }
+				if (i % 1000 == 0) {
+					// print("DELETING " + i + ": " +
+					// cmp.printRecord(records[i], 0) + "\n");
+					print("DELETING " + i + "\n");
+				}
 
-                try {
-                    btree.delete(tuple, deleteOpCtx);
-                    delDone++;
-                } catch (BTreeException e) {
-                    // e.printStackTrace();
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
+				try {
+					btree.delete(tuple, deleteOpCtx);
+					delDone++;
+				} catch (BTreeException e) {
+					// e.printStackTrace();
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
 
-                if (insDoneCmp[i] != delDone) {
-                    print("INCONSISTENT STATE, ERROR IN DELETION TEST\n");
-                    print("INSDONECMP: " + insDoneCmp[i] + " " + delDone + "\n");
-                    break;
-                }
-                // btree.printTree();
-            }
-            // btree.printTree(leafFrame, interiorFrame);
+				if (insDoneCmp[i] != delDone) {
+					print("INCONSISTENT STATE, ERROR IN DELETION TEST\n");
+					print("INSDONECMP: " + insDoneCmp[i] + " " + delDone + "\n");
+					break;
+				}
+				// btree.printTree();
+			}
+			// btree.printTree(leafFrame, interiorFrame);
 
-            if (insDone != delDone) {
-                print("ERROR! INSDONE: " + insDone + " DELDONE: " + delDone);
-                break;
-            }
-        }
+			if (insDone != delDone) {
+				print("ERROR! INSDONE: " + insDone + " DELDONE: " + delDone);
+				break;
+			}
+		}
 
-        btree.close();
-        bufferCache.closeFile(fileId);
-        bufferCache.close();
+		btree.close();
+		bufferCache.closeFile(fileId);
+		bufferCache.close();
 
-        print("\n");
-    }
+		print("\n");
+	}
 
-    // BULK LOAD TEST
-    // insert 100,000 records in bulk
-    // B-tree has a composite key to "simulate" non-unique index creation
-    // do range search
-    @Test
-    public void test05() throws Exception {
+	// BULK LOAD TEST
+	// insert 100,000 records in bulk
+	// B-tree has a composite key to "simulate" non-unique index creation
+	// do range search
+	@Test
+	public void test05() throws Exception {
 
-        print("BULK LOAD TEST\n");
+		print("BULK LOAD TEST\n");
 
-        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
-        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
-        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
-        FileReference file = new FileReference(new File(tmpDir + "/" + "btreetest.bin"));
-        bufferCache.createFile(file);
-        int fileId = fmp.lookupFileId(file);
-        bufferCache.openFile(fileId);
+		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
+		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 fields
-        int fieldCount = 3;
-        ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
-        typeTraits[0] = new TypeTrait(4);
-        typeTraits[1] = new TypeTrait(4);
-        typeTraits[2] = new TypeTrait(4);
+		// declare fields
+		int fieldCount = 3;
+		ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
+		typeTraits[0] = new TypeTrait(4);
+		typeTraits[1] = new TypeTrait(4);
+		typeTraits[2] = new TypeTrait(4);
 
-        // declare keys
-        int keyFieldCount = 2;
-        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-        cmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        cmps[1] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+		// declare keys
+		int keyFieldCount = 2;
+		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+		cmps[0] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		cmps[1] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
 
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-        // SimpleTupleWriterFactory tupleWriterFactory = new
-        // SimpleTupleWriterFactory();
-        TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(typeTraits);
-        IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory(tupleWriterFactory);
-        IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory(tupleWriterFactory);
-        IBTreeMetaDataFrameFactory metaFrameFactory = new MetaDataFrameFactory();
+		// SimpleTupleWriterFactory tupleWriterFactory = new
+		// SimpleTupleWriterFactory();
+		TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(
+				typeTraits);
+		IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory(
+				tupleWriterFactory);
+		IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory(
+				tupleWriterFactory);
+		IBTreeMetaDataFrameFactory metaFrameFactory = new MetaDataFrameFactory();
 
-        IBTreeLeafFrame leafFrame = leafFrameFactory.getFrame();
-        IBTreeInteriorFrame interiorFrame = interiorFrameFactory.getFrame();
-        IBTreeMetaDataFrame metaFrame = metaFrameFactory.getFrame();
+		IBTreeLeafFrame leafFrame = leafFrameFactory.getFrame();
+		IBTreeInteriorFrame interiorFrame = interiorFrameFactory.getFrame();
+		IBTreeMetaDataFrame metaFrame = metaFrameFactory.getFrame();
 
-        BTree btree = new BTree(bufferCache, interiorFrameFactory, leafFrameFactory, cmp);
-        btree.create(fileId, leafFrame, metaFrame);
-        btree.open(fileId);
+		BTree btree = new BTree(bufferCache, interiorFrameFactory,
+				leafFrameFactory, cmp);
+		btree.create(fileId, leafFrame, metaFrame);
+		btree.open(fileId);
 
-        Random rnd = new Random();
-        rnd.setSeed(50);
+		Random rnd = new Random();
+		rnd.setSeed(50);
 
-        ByteBuffer frame = ctx.allocateFrame();
-        FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
-        DataOutput dos = tb.getDataOutput();
+		ByteBuffer frame = ctx.allocateFrame();
+		FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+		DataOutput dos = tb.getDataOutput();
 
-        ISerializerDeserializer[] recDescSers = { IntegerSerializerDeserializer.INSTANCE,
-                IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
-        RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
-        IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(), recDesc);
-        accessor.reset(frame);
-        FrameTupleReference tuple = new FrameTupleReference();
+		ISerializerDeserializer[] recDescSers = {
+				IntegerSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE };
+		RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
+		IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx
+				.getFrameSize(), recDesc);
+		accessor.reset(frame);
+		FrameTupleReference tuple = new FrameTupleReference();
 
-        BTree.BulkLoadContext bulkLoadCtx = btree.beginBulkLoad(0.7f, leafFrame, interiorFrame, metaFrame);
+		BTree.BulkLoadContext bulkLoadCtx = btree.beginBulkLoad(0.7f,
+				leafFrame, interiorFrame, metaFrame);
 
-        // generate sorted records
-        int ins = 100000;
-        print("BULK LOADING " + ins + " RECORDS\n");
-        long start = System.currentTimeMillis();
-        for (int i = 0; i < ins; i++) {
+		// generate sorted records
+		int ins = 100000;
+		print("BULK LOADING " + ins + " RECORDS\n");
+		long start = System.currentTimeMillis();
+		for (int i = 0; i < ins; i++) {
 
-            tb.reset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(i, dos);
-            tb.addFieldEndOffset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(i, dos);
-            tb.addFieldEndOffset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(5, dos);
-            tb.addFieldEndOffset();
+			tb.reset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(i, dos);
+			tb.addFieldEndOffset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(i, dos);
+			tb.addFieldEndOffset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(5, dos);
+			tb.addFieldEndOffset();
 
-            appender.reset(frame, true);
-            appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
+			appender.reset(frame, true);
+			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb
+					.getSize());
 
-            tuple.reset(accessor, 0);
+			tuple.reset(accessor, 0);
 
-            btree.bulkLoadAddTuple(bulkLoadCtx, tuple);
-        }
+			btree.bulkLoadAddTuple(bulkLoadCtx, tuple);
+		}
 
-        btree.endBulkLoad(bulkLoadCtx);
+		btree.endBulkLoad(bulkLoadCtx);
 
-        // btree.printTree(leafFrame, interiorFrame);
+		// btree.printTree(leafFrame, interiorFrame);
 
-        long end = System.currentTimeMillis();
-        long duration = end - start;
-        print("DURATION: " + duration + "\n");
+		long end = System.currentTimeMillis();
+		long duration = end - start;
+		print("DURATION: " + duration + "\n");
 
-        // range search
-        print("RANGE SEARCH:\n");
-        IBTreeCursor rangeCursor = new RangeSearchCursor(leafFrame);
+		// range search
+		print("RANGE SEARCH:\n");
+		IBTreeCursor rangeCursor = new RangeSearchCursor(leafFrame);
 
-        // build low and high keys
-        ArrayTupleBuilder ktb = new ArrayTupleBuilder(1);
-        DataOutput kdos = ktb.getDataOutput();
+		// build low and high keys
+		ArrayTupleBuilder ktb = new ArrayTupleBuilder(1);
+		DataOutput kdos = ktb.getDataOutput();
 
-        ISerializerDeserializer[] keyDescSers = { IntegerSerializerDeserializer.INSTANCE };
-        RecordDescriptor keyDesc = new RecordDescriptor(keyDescSers);
-        IFrameTupleAccessor keyAccessor = new FrameTupleAccessor(ctx.getFrameSize(), keyDesc);
-        keyAccessor.reset(frame);
+		ISerializerDeserializer[] keyDescSers = { IntegerSerializerDeserializer.INSTANCE };
+		RecordDescriptor keyDesc = new RecordDescriptor(keyDescSers);
+		IFrameTupleAccessor keyAccessor = new FrameTupleAccessor(ctx
+				.getFrameSize(), keyDesc);
+		keyAccessor.reset(frame);
 
-        appender.reset(frame, true);
+		appender.reset(frame, true);
 
-        // build and append low key
-        ktb.reset();
-        IntegerSerializerDeserializer.INSTANCE.serialize(44444, kdos);
-        ktb.addFieldEndOffset();
-        appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb.getSize());
+		// build and append low key
+		ktb.reset();
+		IntegerSerializerDeserializer.INSTANCE.serialize(44444, kdos);
+		ktb.addFieldEndOffset();
+		appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb
+				.getSize());
 
-        // build and append high key
-        ktb.reset();
-        IntegerSerializerDeserializer.INSTANCE.serialize(44500, kdos);
-        ktb.addFieldEndOffset();
-        appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb.getSize());
+		// build and append high key
+		ktb.reset();
+		IntegerSerializerDeserializer.INSTANCE.serialize(44500, kdos);
+		ktb.addFieldEndOffset();
+		appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb
+				.getSize());
 
-        // create tuplereferences for search keys
-        FrameTupleReference lowKey = new FrameTupleReference();
-        lowKey.reset(keyAccessor, 0);
+		// create tuplereferences for search keys
+		FrameTupleReference lowKey = new FrameTupleReference();
+		lowKey.reset(keyAccessor, 0);
 
-        FrameTupleReference highKey = new FrameTupleReference();
-        highKey.reset(keyAccessor, 1);
+		FrameTupleReference highKey = new FrameTupleReference();
+		highKey.reset(keyAccessor, 1);
 
-        IBinaryComparator[] searchCmps = new IBinaryComparator[1];
-        searchCmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        MultiComparator searchCmp = new MultiComparator(typeTraits, searchCmps);
+		IBinaryComparator[] searchCmps = new IBinaryComparator[1];
+		searchCmps[0] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		MultiComparator searchCmp = new MultiComparator(typeTraits, searchCmps);
 
-        // TODO: check when searching backwards
-        RangePredicate rangePred = new RangePredicate(true, lowKey, highKey, true, true, searchCmp, searchCmp);
-        BTreeOpContext searchOpCtx = btree.createOpContext(BTreeOp.BTO_SEARCH, leafFrame, interiorFrame, null);
-        btree.search(rangeCursor, rangePred, searchOpCtx);
+		// TODO: check when searching backwards
+		RangePredicate rangePred = new RangePredicate(true, lowKey, highKey,
+				true, true, searchCmp, searchCmp);
+		BTreeOpContext searchOpCtx = btree.createOpContext(BTreeOp.BTO_SEARCH,
+				leafFrame, interiorFrame, null);
+		btree.search(rangeCursor, rangePred, searchOpCtx);
 
-        try {
-            while (rangeCursor.hasNext()) {
-                rangeCursor.next();
-                ITupleReference frameTuple = rangeCursor.getTuple();
-                String rec = cmp.printTuple(frameTuple, recDescSers);
-                print(rec + "\n");
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            rangeCursor.close();
-        }
+		try {
+			while (rangeCursor.hasNext()) {
+				rangeCursor.next();
+				ITupleReference frameTuple = rangeCursor.getTuple();
+				String rec = cmp.printTuple(frameTuple, recDescSers);
+				print(rec + "\n");
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			rangeCursor.close();
+		}
 
-        btree.close();
-        bufferCache.closeFile(fileId);
-        bufferCache.close();
+		btree.close();
+		bufferCache.closeFile(fileId);
+		bufferCache.close();
 
-        print("\n");
-    }
+		print("\n");
+	}
 
-    // TIME-INTERVAL INTERSECTION DEMO FOR EVENT PEOPLE
-    // demo for Arjun to show easy support of intersection queries on
-    // time-intervals
-    @Test
-    public void test06() throws Exception {
+	// TIME-INTERVAL INTERSECTION DEMO FOR EVENT PEOPLE
+	// demo for Arjun to show easy support of intersection queries on
+	// time-intervals
+	@Test
+	public void test06() throws Exception {
 
-        print("TIME-INTERVAL INTERSECTION DEMO\n");
+		print("TIME-INTERVAL INTERSECTION DEMO\n");
 
-        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
-        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
-        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
-        FileReference file = new FileReference(new File(tmpDir + "/" + "btreetest.bin"));
-        bufferCache.createFile(file);
-        int fileId = fmp.lookupFileId(file);
-        bufferCache.openFile(fileId);
+		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
+		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 fields
-        int fieldCount = 3;
-        ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
-        typeTraits[0] = new TypeTrait(4);
-        typeTraits[1] = new TypeTrait(4);
-        typeTraits[2] = new TypeTrait(4);
+		// declare fields
+		int fieldCount = 3;
+		ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
+		typeTraits[0] = new TypeTrait(4);
+		typeTraits[1] = new TypeTrait(4);
+		typeTraits[2] = new TypeTrait(4);
 
-        // declare keys
-        int keyFieldCount = 2;
-        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-        cmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        cmps[1] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+		// declare keys
+		int keyFieldCount = 2;
+		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+		cmps[0] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		cmps[1] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-        // SimpleTupleWriterFactory tupleWriterFactory = new
-        // SimpleTupleWriterFactory();
-        TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(typeTraits);
-        IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory(tupleWriterFactory);
-        IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory(tupleWriterFactory);
-        IBTreeMetaDataFrameFactory metaFrameFactory = new MetaDataFrameFactory();
+		// SimpleTupleWriterFactory tupleWriterFactory = new
+		// SimpleTupleWriterFactory();
+		TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(
+				typeTraits);
+		IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory(
+				tupleWriterFactory);
+		IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory(
+				tupleWriterFactory);
+		IBTreeMetaDataFrameFactory metaFrameFactory = new MetaDataFrameFactory();
 
-        IBTreeLeafFrame leafFrame = leafFrameFactory.getFrame();
-        IBTreeInteriorFrame interiorFrame = interiorFrameFactory.getFrame();
-        IBTreeMetaDataFrame metaFrame = metaFrameFactory.getFrame();
+		IBTreeLeafFrame leafFrame = leafFrameFactory.getFrame();
+		IBTreeInteriorFrame interiorFrame = interiorFrameFactory.getFrame();
+		IBTreeMetaDataFrame metaFrame = metaFrameFactory.getFrame();
 
-        BTree btree = new BTree(bufferCache, interiorFrameFactory, leafFrameFactory, cmp);
-        btree.create(fileId, leafFrame, metaFrame);
-        btree.open(fileId);
+		BTree btree = new BTree(bufferCache, interiorFrameFactory,
+				leafFrameFactory, cmp);
+		btree.create(fileId, leafFrame, metaFrame);
+		btree.open(fileId);
 
-        Random rnd = new Random();
-        rnd.setSeed(50);
+		Random rnd = new Random();
+		rnd.setSeed(50);
 
-        ByteBuffer frame = ctx.allocateFrame();
-        FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
-        DataOutput dos = tb.getDataOutput();
+		ByteBuffer frame = ctx.allocateFrame();
+		FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+		DataOutput dos = tb.getDataOutput();
 
-        ISerializerDeserializer[] recDescSers = { IntegerSerializerDeserializer.INSTANCE,
-                IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
-        RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
-        IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(), recDesc);
-        accessor.reset(frame);
-        FrameTupleReference tuple = new FrameTupleReference();
+		ISerializerDeserializer[] recDescSers = {
+				IntegerSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE };
+		RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
+		IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx
+				.getFrameSize(), recDesc);
+		accessor.reset(frame);
+		FrameTupleReference tuple = new FrameTupleReference();
 
-        long start = System.currentTimeMillis();
+		long start = System.currentTimeMillis();
 
-        int intervalCount = 10;
-        int[][] intervals = new int[intervalCount][2];
+		int intervalCount = 10;
+		int[][] intervals = new int[intervalCount][2];
 
-        intervals[0][0] = 10;
-        intervals[0][1] = 20;
+		intervals[0][0] = 10;
+		intervals[0][1] = 20;
 
-        intervals[1][0] = 11;
-        intervals[1][1] = 20;
+		intervals[1][0] = 11;
+		intervals[1][1] = 20;
 
-        intervals[2][0] = 12;
-        intervals[2][1] = 20;
+		intervals[2][0] = 12;
+		intervals[2][1] = 20;
 
-        intervals[3][0] = 13;
-        intervals[3][1] = 20;
+		intervals[3][0] = 13;
+		intervals[3][1] = 20;
 
-        intervals[4][0] = 14;
-        intervals[4][1] = 20;
+		intervals[4][0] = 14;
+		intervals[4][1] = 20;
 
-        intervals[5][0] = 20;
-        intervals[5][1] = 30;
+		intervals[5][0] = 20;
+		intervals[5][1] = 30;
 
-        intervals[6][0] = 20;
-        intervals[6][1] = 31;
+		intervals[6][0] = 20;
+		intervals[6][1] = 31;
 
-        intervals[7][0] = 20;
-        intervals[7][1] = 32;
+		intervals[7][0] = 20;
+		intervals[7][1] = 32;
 
-        intervals[8][0] = 20;
-        intervals[8][1] = 33;
+		intervals[8][0] = 20;
+		intervals[8][1] = 33;
 
-        intervals[9][0] = 20;
-        intervals[9][1] = 35;
+		intervals[9][0] = 20;
+		intervals[9][1] = 35;
 
-        BTreeOpContext insertOpCtx = btree.createOpContext(BTreeOp.BTO_INSERT, leafFrame, interiorFrame, metaFrame);
+		BTreeOpContext insertOpCtx = btree.createOpContext(BTreeOp.BTO_INSERT,
+				leafFrame, interiorFrame, metaFrame);
 
-        // int exceptionCount = 0;
-        for (int i = 0; i < intervalCount; i++) {
-            int f0 = intervals[i][0];
-            int f1 = intervals[i][1];
-            int f2 = rnd.nextInt() % 100;
+		// int exceptionCount = 0;
+		for (int i = 0; i < intervalCount; i++) {
+			int f0 = intervals[i][0];
+			int f1 = intervals[i][1];
+			int f2 = rnd.nextInt() % 100;
 
-            tb.reset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(f0, dos);
-            tb.addFieldEndOffset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(f1, dos);
-            tb.addFieldEndOffset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(f2, dos);
-            tb.addFieldEndOffset();
+			tb.reset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(f0, dos);
+			tb.addFieldEndOffset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(f1, dos);
+			tb.addFieldEndOffset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(f2, dos);
+			tb.addFieldEndOffset();
 
-            appender.reset(frame, true);
-            appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
+			appender.reset(frame, true);
+			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb
+					.getSize());
 
-            tuple.reset(accessor, 0);
+			tuple.reset(accessor, 0);
 
-            // print("INSERTING " + i + " : " + f0 + " " + f1 + "\n");
-            print("INSERTING " + i + "\n");
+			// print("INSERTING " + i + " : " + f0 + " " + f1 + "\n");
+			print("INSERTING " + i + "\n");
 
-            try {
-                btree.insert(tuple, insertOpCtx);
-            } catch (Exception e) {
-                // e.printStackTrace();
-            }
-        }
-        // btree.printTree(leafFrame, interiorFrame);
-        // btree.printStats();
+			try {
+				btree.insert(tuple, insertOpCtx);
+			} catch (Exception e) {
+				// e.printStackTrace();
+			}
+		}
+		// btree.printTree(leafFrame, interiorFrame);
+		// btree.printStats();
 
-        long end = System.currentTimeMillis();
-        long duration = end - start;
-        print("DURATION: " + duration + "\n");
+		long end = System.currentTimeMillis();
+		long duration = end - start;
+		print("DURATION: " + duration + "\n");
 
-        // try a simple index scan
+		// try a simple index scan
 
-        print("ORDERED SCAN:\n");
-        IBTreeCursor scanCursor = new RangeSearchCursor(leafFrame);
-        RangePredicate nullPred = new RangePredicate(true, null, null, true, true, null, null);
-        BTreeOpContext searchOpCtx = btree.createOpContext(BTreeOp.BTO_SEARCH, leafFrame, interiorFrame, null);
-        btree.search(scanCursor, nullPred, searchOpCtx);
+		print("ORDERED SCAN:\n");
+		IBTreeCursor scanCursor = new RangeSearchCursor(leafFrame);
+		RangePredicate nullPred = new RangePredicate(true, null, null, true,
+				true, null, null);
+		BTreeOpContext searchOpCtx = btree.createOpContext(BTreeOp.BTO_SEARCH,
+				leafFrame, interiorFrame, null);
+		btree.search(scanCursor, nullPred, searchOpCtx);
 
-        try {
-            while (scanCursor.hasNext()) {
-                scanCursor.next();
-                ITupleReference frameTuple = scanCursor.getTuple();
-                String rec = cmp.printTuple(frameTuple, recDescSers);
-                print(rec + "\n");
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            scanCursor.close();
-        }
+		try {
+			while (scanCursor.hasNext()) {
+				scanCursor.next();
+				ITupleReference frameTuple = scanCursor.getTuple();
+				String rec = cmp.printTuple(frameTuple, recDescSers);
+				print(rec + "\n");
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			scanCursor.close();
+		}
 
-        // try a range search
-        print("RANGE SEARCH:\n");
-        IBTreeCursor rangeCursor = new RangeSearchCursor(leafFrame);
+		// try a range search
+		print("RANGE SEARCH:\n");
+		IBTreeCursor rangeCursor = new RangeSearchCursor(leafFrame);
 
-        // build low and high keys
-        ArrayTupleBuilder ktb = new ArrayTupleBuilder(cmp.getKeyFieldCount());
-        DataOutput kdos = ktb.getDataOutput();
+		// build low and high keys
+		ArrayTupleBuilder ktb = new ArrayTupleBuilder(cmp.getKeyFieldCount());
+		DataOutput kdos = ktb.getDataOutput();
 
-        ISerializerDeserializer[] keyDescSers = { IntegerSerializerDeserializer.INSTANCE,
-                IntegerSerializerDeserializer.INSTANCE };
-        RecordDescriptor keyDesc = new RecordDescriptor(keyDescSers);
-        IFrameTupleAccessor keyAccessor = new FrameTupleAccessor(ctx.getFrameSize(), keyDesc);
-        keyAccessor.reset(frame);
+		ISerializerDeserializer[] keyDescSers = {
+				IntegerSerializerDeserializer.INSTANCE,
+				IntegerSerializerDeserializer.INSTANCE };
+		RecordDescriptor keyDesc = new RecordDescriptor(keyDescSers);
+		IFrameTupleAccessor keyAccessor = new FrameTupleAccessor(ctx
+				.getFrameSize(), keyDesc);
+		keyAccessor.reset(frame);
 
-        appender.reset(frame, true);
+		appender.reset(frame, true);
 
-        // build and append low key
-        ktb.reset();
-        IntegerSerializerDeserializer.INSTANCE.serialize(12, kdos);
-        ktb.addFieldEndOffset();
-        IntegerSerializerDeserializer.INSTANCE.serialize(12, kdos);
-        ktb.addFieldEndOffset();
-        appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb.getSize());
+		// build and append low key
+		ktb.reset();
+		IntegerSerializerDeserializer.INSTANCE.serialize(12, kdos);
+		ktb.addFieldEndOffset();
+		IntegerSerializerDeserializer.INSTANCE.serialize(12, kdos);
+		ktb.addFieldEndOffset();
+		appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb
+				.getSize());
 
-        // build and append high key
-        ktb.reset();
-        IntegerSerializerDeserializer.INSTANCE.serialize(19, kdos);
-        ktb.addFieldEndOffset();
-        IntegerSerializerDeserializer.INSTANCE.serialize(19, kdos);
-        ktb.addFieldEndOffset();
-        appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb.getSize());
+		// build and append high key
+		ktb.reset();
+		IntegerSerializerDeserializer.INSTANCE.serialize(19, kdos);
+		ktb.addFieldEndOffset();
+		IntegerSerializerDeserializer.INSTANCE.serialize(19, kdos);
+		ktb.addFieldEndOffset();
+		appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb
+				.getSize());
 
-        // create tuplereferences for search keys
-        FrameTupleReference lowKey = new FrameTupleReference();
-        lowKey.reset(keyAccessor, 0);
+		// create tuplereferences for search keys
+		FrameTupleReference lowKey = new FrameTupleReference();
+		lowKey.reset(keyAccessor, 0);
 
-        FrameTupleReference highKey = new FrameTupleReference();
-        highKey.reset(keyAccessor, 1);
+		FrameTupleReference highKey = new FrameTupleReference();
+		highKey.reset(keyAccessor, 1);
 
-        IBinaryComparator[] searchCmps = new IBinaryComparator[2];
-        searchCmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        searchCmps[1] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        MultiComparator searchCmp = new MultiComparator(typeTraits, searchCmps);
+		IBinaryComparator[] searchCmps = new IBinaryComparator[2];
+		searchCmps[0] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		searchCmps[1] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		MultiComparator searchCmp = new MultiComparator(typeTraits, searchCmps);
 
-        // print("INDEX RANGE SEARCH ON: " + cmp.printKey(lowKey, 0) + " " +
-        // cmp.printKey(highKey, 0) + "\n");
+		// print("INDEX RANGE SEARCH ON: " + cmp.printKey(lowKey, 0) + " " +
+		// cmp.printKey(highKey, 0) + "\n");
 
-        RangePredicate rangePred = new RangePredicate(true, lowKey, highKey, true, true, searchCmp, searchCmp);
-        btree.search(rangeCursor, rangePred, searchOpCtx);
+		RangePredicate rangePred = new RangePredicate(true, lowKey, highKey,
+				true, true, searchCmp, searchCmp);
+		btree.search(rangeCursor, rangePred, searchOpCtx);
 
-        try {
-            while (rangeCursor.hasNext()) {
-                rangeCursor.next();
-                ITupleReference frameTuple = rangeCursor.getTuple();
-                String rec = cmp.printTuple(frameTuple, recDescSers);
-                print(rec + "\n");
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            rangeCursor.close();
-        }
+		try {
+			while (rangeCursor.hasNext()) {
+				rangeCursor.next();
+				ITupleReference frameTuple = rangeCursor.getTuple();
+				String rec = cmp.printTuple(frameTuple, recDescSers);
+				print(rec + "\n");
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			rangeCursor.close();
+		}
 
-        btree.close();
-        bufferCache.closeFile(fileId);
-        bufferCache.close();
+		btree.close();
+		bufferCache.closeFile(fileId);
+		bufferCache.close();
 
-        print("\n");
-    }
+		print("\n");
+	}
 
-    public static String randomString(int length, Random random) {
-        String s = Long.toHexString(Double.doubleToLongBits(random.nextDouble()));
-        StringBuilder strBuilder = new StringBuilder();
-        for (int i = 0; i < s.length() && i < length; i++) {
-            strBuilder.append(s.charAt(Math.abs(random.nextInt()) % s.length()));
-        }
-        return strBuilder.toString();
-    }
+	public static String randomString(int length, Random random) {
+		String s = Long.toHexString(Double
+				.doubleToLongBits(random.nextDouble()));
+		StringBuilder strBuilder = new StringBuilder();
+		for (int i = 0; i < s.length() && i < length; i++) {
+			strBuilder
+					.append(s.charAt(Math.abs(random.nextInt()) % s.length()));
+		}
+		return strBuilder.toString();
+	}
 }
\ No newline at end of file
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/RangeSearchCursorTest.java b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/RangeSearchCursorTest.java
index 1651d56..12371be 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/RangeSearchCursorTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/RangeSearchCursorTest.java
@@ -26,7 +26,6 @@
 import java.util.Random;
 import java.util.TreeSet;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -71,480 +70,552 @@
 import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
 import edu.uci.ics.hyracks.test.support.TestUtils;
 
-public class RangeSearchCursorTest {
-    private static final int PAGE_SIZE = 256;
-    private static final int NUM_PAGES = 10;
-    private static final int HYRACKS_FRAME_SIZE = 128;
+public class RangeSearchCursorTest extends AbstractBTreeTest {
+	private static final int PAGE_SIZE = 256;
+	private static final int NUM_PAGES = 10;
+	private static final int HYRACKS_FRAME_SIZE = 128;
 
-    private String tmpDir = System.getProperty("java.io.tmpdir");
+	public class BufferAllocator implements ICacheMemoryAllocator {
+		@Override
+		public ByteBuffer[] allocate(int pageSize, int numPages) {
+			ByteBuffer[] buffers = new ByteBuffer[numPages];
+			for (int i = 0; i < numPages; ++i) {
+				buffers[i] = ByteBuffer.allocate(pageSize);
+			}
+			return buffers;
+		}
+	}
 
-    public class BufferAllocator implements ICacheMemoryAllocator {
-        @Override
-        public ByteBuffer[] allocate(int pageSize, int numPages) {
-            ByteBuffer[] buffers = new ByteBuffer[numPages];
-            for (int i = 0; i < numPages; ++i) {
-                buffers[i] = ByteBuffer.allocate(pageSize);
-            }
-            return buffers;
-        }
-    }
+	// declare fields
+	int fieldCount = 2;
+	ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
 
-    // declare fields
-    int fieldCount = 2;
-    ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
+	TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(
+			typeTraits);
+	IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory(
+			tupleWriterFactory);
+	IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory(
+			tupleWriterFactory);
+	IBTreeMetaDataFrameFactory metaFrameFactory = new MetaDataFrameFactory();
 
-    TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(typeTraits);
-    IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory(tupleWriterFactory);
-    IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory(tupleWriterFactory);
-    IBTreeMetaDataFrameFactory metaFrameFactory = new MetaDataFrameFactory();
+	IBTreeLeafFrame leafFrame = leafFrameFactory.getFrame();
+	IBTreeInteriorFrame interiorFrame = interiorFrameFactory.getFrame();
+	IBTreeMetaDataFrame metaFrame = metaFrameFactory.getFrame();
 
-    IBTreeLeafFrame leafFrame = leafFrameFactory.getFrame();
-    IBTreeInteriorFrame interiorFrame = interiorFrameFactory.getFrame();
-    IBTreeMetaDataFrame metaFrame = metaFrameFactory.getFrame();
+	IHyracksStageletContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
+	ByteBuffer frame = ctx.allocateFrame();
+	FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
 
-    IHyracksStageletContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
-    ByteBuffer frame = ctx.allocateFrame();
-    FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+	ISerializerDeserializer[] recDescSers = {
+			IntegerSerializerDeserializer.INSTANCE,
+			IntegerSerializerDeserializer.INSTANCE };
+	RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
+	IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(),
+			recDesc);
+	FrameTupleReference tuple = new FrameTupleReference();
 
-    ISerializerDeserializer[] recDescSers = { IntegerSerializerDeserializer.INSTANCE,
-            IntegerSerializerDeserializer.INSTANCE };
-    RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
-    IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(), recDesc);
-    FrameTupleReference tuple = new FrameTupleReference();
+	Random rnd = new Random(50);
 
-    Random rnd = new Random(50);
+	@Before
+	public void setUp() {
+		typeTraits[0] = new TypeTrait(4);
+		typeTraits[1] = new TypeTrait(4);
+		accessor.reset(frame);
+	}
 
-    @Before
-    public void setUp() {
-        typeTraits[0] = new TypeTrait(4);
-        typeTraits[1] = new TypeTrait(4);
-        accessor.reset(frame);
-    }
+	@Test
+	public void uniqueIndexTest() throws Exception {
 
-    @Test
-    public void uniqueIndexTest() throws Exception {
+		System.out.println("TESTING RANGE SEARCH CURSOR ON UNIQUE INDEX");
 
-        System.out.println("TESTING RANGE SEARCH CURSOR ON UNIQUE INDEX");
-        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
-        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
-        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
-        FileReference file = new FileReference(new File(tmpDir + "/" + "btreetest.bin"));
-        bufferCache.createFile(file);
-        int fileId = fmp.lookupFileId(file);
-        bufferCache.openFile(fileId);
+		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
+		IBufferCache bufferCache = TestStorageManagerComponentHolder
+				.getBufferCache(ctx);
+		IFileMapProvider fmp = TestStorageManagerComponentHolder
+				.getFileMapProvider(ctx);
+		FileReference file = new FileReference(new File(fileName));
+		bufferCache.createFile(file);
+		int fileId = fmp.lookupFileId(file);
+		bufferCache.openFile(fileId);
 
-        // declare keys
-        int keyFieldCount = 1;
-        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-        cmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+		// declare keys
+		int keyFieldCount = 1;
+		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+		cmps[0] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
 
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-        BTree btree = new BTree(bufferCache, interiorFrameFactory, leafFrameFactory, cmp);
-        btree.create(fileId, leafFrame, metaFrame);
-        btree.open(fileId);
+		BTree btree = new BTree(bufferCache, interiorFrameFactory,
+				leafFrameFactory, cmp);
+		btree.create(fileId, leafFrame, metaFrame);
+		btree.open(fileId);
 
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
-        DataOutput dos = tb.getDataOutput();
+		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+		DataOutput dos = tb.getDataOutput();
 
-        BTreeOpContext insertOpCtx = btree.createOpContext(BTreeOp.BTO_INSERT, leafFrame, interiorFrame, metaFrame);
+		BTreeOpContext insertOpCtx = btree.createOpContext(BTreeOp.BTO_INSERT,
+				leafFrame, interiorFrame, metaFrame);
 
-        // generate keys
-        int numKeys = 50;
-        int maxKey = 1000;
-        TreeSet<Integer> uniqueKeys = new TreeSet<Integer>();
-        ArrayList<Integer> keys = new ArrayList<Integer>();
-        while (uniqueKeys.size() < numKeys) {
-            int key = rnd.nextInt() % maxKey;
-            uniqueKeys.add(key);
-        }
-        for (Integer i : uniqueKeys) {
-            keys.add(i);
-        }
+		// generate keys
+		int numKeys = 50;
+		int maxKey = 1000;
+		TreeSet<Integer> uniqueKeys = new TreeSet<Integer>();
+		ArrayList<Integer> keys = new ArrayList<Integer>();
+		while (uniqueKeys.size() < numKeys) {
+			int key = rnd.nextInt() % maxKey;
+			uniqueKeys.add(key);
+		}
+		for (Integer i : uniqueKeys) {
+			keys.add(i);
+		}
 
-        // insert keys into btree
-        for (int i = 0; i < keys.size(); i++) {
+		// insert keys into btree
+		for (int i = 0; i < keys.size(); i++) {
 
-            tb.reset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(keys.get(i).intValue(), dos);
-            tb.addFieldEndOffset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(i, dos);
-            tb.addFieldEndOffset();
+			tb.reset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(keys.get(i)
+					.intValue(), dos);
+			tb.addFieldEndOffset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(i, dos);
+			tb.addFieldEndOffset();
 
-            appender.reset(frame, true);
-            appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
+			appender.reset(frame, true);
+			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb
+					.getSize());
 
-            tuple.reset(accessor, 0);
+			tuple.reset(accessor, 0);
 
-            try {
-                btree.insert(tuple, insertOpCtx);
-            } catch (BTreeException e) {
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
+			try {
+				btree.insert(tuple, insertOpCtx);
+			} catch (BTreeException e) {
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
 
-        // btree.printTree(leafFrame, interiorFrame, recDescSers);
+		// btree.printTree(leafFrame, interiorFrame, recDescSers);
 
-        int minSearchKey = -100;
-        int maxSearchKey = 100;
+		int minSearchKey = -100;
+		int maxSearchKey = 100;
 
-        // System.out.println("STARTING SEARCH TESTS");
+		// System.out.println("STARTING SEARCH TESTS");
 
-        // forward searches
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, true, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, false, true, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, false, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, true, false);
+		// forward searches
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, true, true, true, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, true, false, true, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, true, true, false, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, true, true, true, false);
 
-        // backward searches
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, true, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, false, true, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, false, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, true, false);
+		// backward searches
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, false, true, true, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, false, false, true, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, false, true, false, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, false, true, true, false);
 
-        btree.close();
-        bufferCache.closeFile(fileId);
-        bufferCache.close();
-    }
+		btree.close();
+		bufferCache.closeFile(fileId);
+		bufferCache.close();
+	}
 
-    @Test
-    public void nonUniqueIndexTest() throws Exception {
+	@Test
+	public void nonUniqueIndexTest() throws Exception {
 
-        System.out.println("TESTING RANGE SEARCH CURSOR ON NONUNIQUE INDEX");
+		System.out.println("TESTING RANGE SEARCH CURSOR ON NONUNIQUE INDEX");
 
-        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
-        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
-        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
-        FileReference file = new FileReference(new File(tmpDir + "/" + "btreetest.bin"));
-        bufferCache.createFile(file);
-        int fileId = fmp.lookupFileId(file);
-        bufferCache.openFile(fileId);
+		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
+		IBufferCache bufferCache = TestStorageManagerComponentHolder
+				.getBufferCache(ctx);
+		IFileMapProvider fmp = TestStorageManagerComponentHolder
+				.getFileMapProvider(ctx);
+		FileReference file = new FileReference(new File(fileName));
+		bufferCache.createFile(file);
+		int fileId = fmp.lookupFileId(file);
+		bufferCache.openFile(fileId);
 
-        // declare keys
-        int keyFieldCount = 2;
-        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-        cmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        cmps[1] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+		// declare keys
+		int keyFieldCount = 2;
+		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+		cmps[0] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		cmps[1] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
 
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-        BTree btree = new BTree(bufferCache, interiorFrameFactory, leafFrameFactory, cmp);
-        btree.create(fileId, leafFrame, metaFrame);
-        btree.open(fileId);
+		BTree btree = new BTree(bufferCache, interiorFrameFactory,
+				leafFrameFactory, cmp);
+		btree.create(fileId, leafFrame, metaFrame);
+		btree.open(fileId);
 
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
-        DataOutput dos = tb.getDataOutput();
+		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+		DataOutput dos = tb.getDataOutput();
 
-        BTreeOpContext insertOpCtx = btree.createOpContext(BTreeOp.BTO_INSERT, leafFrame, interiorFrame, metaFrame);
+		BTreeOpContext insertOpCtx = btree.createOpContext(BTreeOp.BTO_INSERT,
+				leafFrame, interiorFrame, metaFrame);
 
-        // generate keys
-        int numKeys = 50;
-        int maxKey = 10;
-        ArrayList<Integer> keys = new ArrayList<Integer>();
-        for (int i = 0; i < numKeys; i++) {
-            int k = rnd.nextInt() % maxKey;
-            keys.add(k);
-        }
-        Collections.sort(keys);
+		// generate keys
+		int numKeys = 50;
+		int maxKey = 10;
+		ArrayList<Integer> keys = new ArrayList<Integer>();
+		for (int i = 0; i < numKeys; i++) {
+			int k = rnd.nextInt() % maxKey;
+			keys.add(k);
+		}
+		Collections.sort(keys);
 
-        // insert keys into btree
-        for (int i = 0; i < keys.size(); i++) {
+		// insert keys into btree
+		for (int i = 0; i < keys.size(); i++) {
 
-            tb.reset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(keys.get(i).intValue(), dos);
-            tb.addFieldEndOffset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(i, dos);
-            tb.addFieldEndOffset();
+			tb.reset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(keys.get(i)
+					.intValue(), dos);
+			tb.addFieldEndOffset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(i, dos);
+			tb.addFieldEndOffset();
 
-            appender.reset(frame, true);
-            appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
+			appender.reset(frame, true);
+			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb
+					.getSize());
 
-            tuple.reset(accessor, 0);
+			tuple.reset(accessor, 0);
 
-            try {
-                btree.insert(tuple, insertOpCtx);
-            } catch (BTreeException e) {
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
+			try {
+				btree.insert(tuple, insertOpCtx);
+			} catch (BTreeException e) {
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
 
-        // btree.printTree(leafFrame, interiorFrame, recDescSers);
+		// btree.printTree(leafFrame, interiorFrame, recDescSers);
 
-        int minSearchKey = -100;
-        int maxSearchKey = 100;
+		int minSearchKey = -100;
+		int maxSearchKey = 100;
 
-        // System.out.println("STARTING SEARCH TESTS");
+		// System.out.println("STARTING SEARCH TESTS");
 
-        // forward searches
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, true, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, false, true, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, false, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, true, false);
+		// forward searches
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, true, true, true, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, true, false, true, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, true, true, false, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, true, true, true, false);
 
-        // backward searches
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, true, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, false, true, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, false, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, true, false);
+		// backward searches
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, false, true, true, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, false, false, true, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, false, true, false, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, false, true, true, false);
 
-        btree.close();
-        bufferCache.closeFile(fileId);
-        bufferCache.close();
-    }
+		btree.close();
+		bufferCache.closeFile(fileId);
+		bufferCache.close();
+	}
 
-    @Test
-    public void nonUniqueFieldPrefixIndexTest() throws Exception {
+	@Test
+	public void nonUniqueFieldPrefixIndexTest() throws Exception {
 
-        System.out.println("TESTING RANGE SEARCH CURSOR ON NONUNIQUE FIELD-PREFIX COMPRESSED INDEX");
+		System.out
+				.println("TESTING RANGE SEARCH CURSOR ON NONUNIQUE FIELD-PREFIX COMPRESSED INDEX");
 
-        IBTreeLeafFrameFactory leafFrameFactory = new FieldPrefixNSMLeafFrameFactory(tupleWriterFactory);
-        IBTreeLeafFrame leafFrame = leafFrameFactory.getFrame();
+		IBTreeLeafFrameFactory leafFrameFactory = new FieldPrefixNSMLeafFrameFactory(
+				tupleWriterFactory);
+		IBTreeLeafFrame leafFrame = leafFrameFactory.getFrame();
 
-        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
-        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
-        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
-        FileReference file = new FileReference(new File(tmpDir + "/" + "btreetest.bin"));
-        bufferCache.createFile(file);
-        int fileId = fmp.lookupFileId(file);
-        bufferCache.openFile(fileId);
+		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
+		IBufferCache bufferCache = TestStorageManagerComponentHolder
+				.getBufferCache(ctx);
+		IFileMapProvider fmp = TestStorageManagerComponentHolder
+				.getFileMapProvider(ctx);
+		FileReference file = new FileReference(new File(fileName));
+		bufferCache.createFile(file);
+		int fileId = fmp.lookupFileId(file);
+		bufferCache.openFile(fileId);
 
-        // declare keys
-        int keyFieldCount = 2;
-        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-        cmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        cmps[1] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
-
-        BTree btree = new BTree(bufferCache, interiorFrameFactory, leafFrameFactory, cmp);
-        btree.create(fileId, leafFrame, metaFrame);
-        btree.open(fileId);
+		// declare keys
+		int keyFieldCount = 2;
+		IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+		cmps[0] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		cmps[1] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
 
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
-        DataOutput dos = tb.getDataOutput();
+		MultiComparator cmp = new MultiComparator(typeTraits, cmps);
 
-        BTreeOpContext insertOpCtx = btree.createOpContext(BTreeOp.BTO_INSERT, leafFrame, interiorFrame, metaFrame);
+		BTree btree = new BTree(bufferCache, interiorFrameFactory,
+				leafFrameFactory, cmp);
+		btree.create(fileId, leafFrame, metaFrame);
+		btree.open(fileId);
 
-        // generate keys
-        int numKeys = 50;
-        int maxKey = 10;
-        ArrayList<Integer> keys = new ArrayList<Integer>();
-        for (int i = 0; i < numKeys; i++) {
-            int k = rnd.nextInt() % maxKey;
-            keys.add(k);
-        }
-        Collections.sort(keys);
+		ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
+		DataOutput dos = tb.getDataOutput();
 
-        // insert keys into btree
-        for (int i = 0; i < keys.size(); i++) {
+		BTreeOpContext insertOpCtx = btree.createOpContext(BTreeOp.BTO_INSERT,
+				leafFrame, interiorFrame, metaFrame);
 
-            tb.reset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(keys.get(i).intValue(), dos);
-            tb.addFieldEndOffset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(i, dos);
-            tb.addFieldEndOffset();
+		// generate keys
+		int numKeys = 50;
+		int maxKey = 10;
+		ArrayList<Integer> keys = new ArrayList<Integer>();
+		for (int i = 0; i < numKeys; i++) {
+			int k = rnd.nextInt() % maxKey;
+			keys.add(k);
+		}
+		Collections.sort(keys);
 
-            appender.reset(frame, true);
-            appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
+		// insert keys into btree
+		for (int i = 0; i < keys.size(); i++) {
 
-            tuple.reset(accessor, 0);
+			tb.reset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(keys.get(i)
+					.intValue(), dos);
+			tb.addFieldEndOffset();
+			IntegerSerializerDeserializer.INSTANCE.serialize(i, dos);
+			tb.addFieldEndOffset();
 
-            try {
-                btree.insert(tuple, insertOpCtx);
-            } catch (BTreeException e) {
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
+			appender.reset(frame, true);
+			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb
+					.getSize());
 
-        // btree.printTree(leafFrame, interiorFrame, recDescSers);
+			tuple.reset(accessor, 0);
 
-        int minSearchKey = -100;
-        int maxSearchKey = 100;
+			try {
+				btree.insert(tuple, insertOpCtx);
+			} catch (BTreeException e) {
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
 
-        // System.out.println("STARTING SEARCH TESTS");
+		// btree.printTree(leafFrame, interiorFrame, recDescSers);
 
-        // forward searches
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, true, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, false, true, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, false, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, true, true, true, false);
+		int minSearchKey = -100;
+		int maxSearchKey = 100;
 
-        // backward searches
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, true, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, false, true, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, false, false);
-        performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey, maxSearchKey, false, true, true, false);
+		// System.out.println("STARTING SEARCH TESTS");
 
-        btree.close();
-        bufferCache.closeFile(fileId);
-        bufferCache.close();
-    }
+		// forward searches
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, true, true, true, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, true, false, true, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, true, true, false, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, true, true, true, false);
 
-    public RangePredicate createRangePredicate(int lk, int hk, boolean isForward, boolean lowKeyInclusive,
-            boolean highKeyInclusive, MultiComparator cmp, ITypeTrait[] typeTraits) throws HyracksDataException {
-        // build low and high keys
-        ArrayTupleBuilder ktb = new ArrayTupleBuilder(1);
-        DataOutput kdos = ktb.getDataOutput();
+		// backward searches
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, false, true, true, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, false, false, true, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, false, true, false, false);
+		performSearches(keys, btree, leafFrame, interiorFrame, minSearchKey,
+				maxSearchKey, false, true, true, false);
 
-        ISerializerDeserializer[] keyDescSers = { IntegerSerializerDeserializer.INSTANCE };
-        RecordDescriptor keyDesc = new RecordDescriptor(keyDescSers);
-        IFrameTupleAccessor keyAccessor = new FrameTupleAccessor(ctx.getFrameSize(), keyDesc);
-        keyAccessor.reset(frame);
+		btree.close();
+		bufferCache.closeFile(fileId);
+		bufferCache.close();
+	}
 
-        appender.reset(frame, true);
+	public RangePredicate createRangePredicate(int lk, int hk,
+			boolean isForward, boolean lowKeyInclusive,
+			boolean highKeyInclusive, MultiComparator cmp,
+			ITypeTrait[] typeTraits) throws HyracksDataException {
+		// build low and high keys
+		ArrayTupleBuilder ktb = new ArrayTupleBuilder(1);
+		DataOutput kdos = ktb.getDataOutput();
 
-        // build and append low key
-        ktb.reset();
-        IntegerSerializerDeserializer.INSTANCE.serialize(lk, kdos);
-        ktb.addFieldEndOffset();
-        appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb.getSize());
+		ISerializerDeserializer[] keyDescSers = { IntegerSerializerDeserializer.INSTANCE };
+		RecordDescriptor keyDesc = new RecordDescriptor(keyDescSers);
+		IFrameTupleAccessor keyAccessor = new FrameTupleAccessor(ctx
+				.getFrameSize(), keyDesc);
+		keyAccessor.reset(frame);
 
-        // build and append high key
-        ktb.reset();
-        IntegerSerializerDeserializer.INSTANCE.serialize(hk, kdos);
-        ktb.addFieldEndOffset();
-        appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb.getSize());
+		appender.reset(frame, true);
 
-        // create tuplereferences for search keys
-        FrameTupleReference lowKey = new FrameTupleReference();
-        lowKey.reset(keyAccessor, 0);
+		// build and append low key
+		ktb.reset();
+		IntegerSerializerDeserializer.INSTANCE.serialize(lk, kdos);
+		ktb.addFieldEndOffset();
+		appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb
+				.getSize());
 
-        FrameTupleReference highKey = new FrameTupleReference();
-        highKey.reset(keyAccessor, 1);
+		// build and append high key
+		ktb.reset();
+		IntegerSerializerDeserializer.INSTANCE.serialize(hk, kdos);
+		ktb.addFieldEndOffset();
+		appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb
+				.getSize());
 
-        IBinaryComparator[] searchCmps = new IBinaryComparator[1];
-        searchCmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        MultiComparator searchCmp = new MultiComparator(typeTraits, searchCmps);
+		// create tuplereferences for search keys
+		FrameTupleReference lowKey = new FrameTupleReference();
+		lowKey.reset(keyAccessor, 0);
 
-        RangePredicate rangePred = new RangePredicate(isForward, lowKey, highKey, lowKeyInclusive, highKeyInclusive,
-                searchCmp, searchCmp);
-        return rangePred;
-    }
+		FrameTupleReference highKey = new FrameTupleReference();
+		highKey.reset(keyAccessor, 1);
 
-    public void getExpectedResults(ArrayList<Integer> expectedResults, ArrayList<Integer> keys, int lk, int hk,
-            boolean isForward, boolean lowKeyInclusive, boolean highKeyInclusive) {
+		IBinaryComparator[] searchCmps = new IBinaryComparator[1];
+		searchCmps[0] = IntegerBinaryComparatorFactory.INSTANCE
+				.createBinaryComparator();
+		MultiComparator searchCmp = new MultiComparator(typeTraits, searchCmps);
 
-        // special cases
-        if (lk == hk && (!lowKeyInclusive || !highKeyInclusive))
-            return;
-        if (lk > hk)
-            return;
+		RangePredicate rangePred = new RangePredicate(isForward, lowKey,
+				highKey, lowKeyInclusive, highKeyInclusive, searchCmp,
+				searchCmp);
+		return rangePred;
+	}
 
-        if (isForward) {
-            for (int i = 0; i < keys.size(); i++) {
-                if ((lk == keys.get(i) && lowKeyInclusive) || (hk == keys.get(i) && highKeyInclusive)) {
-                    expectedResults.add(keys.get(i));
-                    continue;
-                }
+	public void getExpectedResults(ArrayList<Integer> expectedResults,
+			ArrayList<Integer> keys, int lk, int hk, boolean isForward,
+			boolean lowKeyInclusive, boolean highKeyInclusive) {
 
-                if (lk < keys.get(i) && hk > keys.get(i)) {
-                    expectedResults.add(keys.get(i));
-                    continue;
-                }
-            }
-        } else {
-            for (int i = keys.size() - 1; i >= 0; i--) {
-                if ((lk == keys.get(i) && lowKeyInclusive) || (hk == keys.get(i) && highKeyInclusive)) {
-                    expectedResults.add(keys.get(i));
-                    continue;
-                }
+		// special cases
+		if (lk == hk && (!lowKeyInclusive || !highKeyInclusive))
+			return;
+		if (lk > hk)
+			return;
 
-                if (lk < keys.get(i) && hk > keys.get(i)) {
-                    expectedResults.add(keys.get(i));
-                    continue;
-                }
-            }
-        }
-    }
+		if (isForward) {
+			for (int i = 0; i < keys.size(); i++) {
+				if ((lk == keys.get(i) && lowKeyInclusive)
+						|| (hk == keys.get(i) && highKeyInclusive)) {
+					expectedResults.add(keys.get(i));
+					continue;
+				}
 
-    public boolean performSearches(ArrayList<Integer> keys, BTree btree, IBTreeLeafFrame leafFrame,
-            IBTreeInteriorFrame interiorFrame, int minKey, int maxKey, boolean isForward, boolean lowKeyInclusive,
-            boolean highKeyInclusive, boolean printExpectedResults) throws Exception {
+				if (lk < keys.get(i) && hk > keys.get(i)) {
+					expectedResults.add(keys.get(i));
+					continue;
+				}
+			}
+		} else {
+			for (int i = keys.size() - 1; i >= 0; i--) {
+				if ((lk == keys.get(i) && lowKeyInclusive)
+						|| (hk == keys.get(i) && highKeyInclusive)) {
+					expectedResults.add(keys.get(i));
+					continue;
+				}
 
-        ArrayList<Integer> results = new ArrayList<Integer>();
-        ArrayList<Integer> expectedResults = new ArrayList<Integer>();
+				if (lk < keys.get(i) && hk > keys.get(i)) {
+					expectedResults.add(keys.get(i));
+					continue;
+				}
+			}
+		}
+	}
 
-        for (int i = minKey; i < maxKey; i++) {
-            for (int j = minKey; j < maxKey; j++) {
+	public boolean performSearches(ArrayList<Integer> keys, BTree btree,
+			IBTreeLeafFrame leafFrame, IBTreeInteriorFrame interiorFrame,
+			int minKey, int maxKey, boolean isForward, boolean lowKeyInclusive,
+			boolean highKeyInclusive, boolean printExpectedResults)
+			throws Exception {
 
-                // if(i != -100 || j != 1) continue;
+		ArrayList<Integer> results = new ArrayList<Integer>();
+		ArrayList<Integer> expectedResults = new ArrayList<Integer>();
 
-                results.clear();
-                expectedResults.clear();
+		for (int i = minKey; i < maxKey; i++) {
+			for (int j = minKey; j < maxKey; j++) {
 
-                int lowKey = i;
-                int highKey = j;
+				// if(i != -100 || j != 1) continue;
 
-                IBTreeCursor rangeCursor = new RangeSearchCursor(leafFrame);
-                RangePredicate rangePred = createRangePredicate(lowKey, highKey, isForward, lowKeyInclusive,
-                        highKeyInclusive, btree.getMultiComparator(), btree.getMultiComparator().getTypeTraits());
-                BTreeOpContext searchOpCtx = btree.createOpContext(BTreeOp.BTO_SEARCH, leafFrame, interiorFrame, null);
-                btree.search(rangeCursor, rangePred, searchOpCtx);
+				results.clear();
+				expectedResults.clear();
 
-                try {
-                    while (rangeCursor.hasNext()) {
-                        rangeCursor.next();
-                        ITupleReference frameTuple = rangeCursor.getTuple();
-                        ByteArrayInputStream inStream = new ByteArrayInputStream(frameTuple.getFieldData(0),
-                                frameTuple.getFieldStart(0), frameTuple.getFieldLength(0));
-                        DataInput dataIn = new DataInputStream(inStream);
-                        Integer res = IntegerSerializerDeserializer.INSTANCE.deserialize(dataIn);
-                        results.add(res);
-                    }
-                } catch (Exception e) {
-                    e.printStackTrace();
-                } finally {
-                    rangeCursor.close();
-                }
+				int lowKey = i;
+				int highKey = j;
 
-                getExpectedResults(expectedResults, keys, lowKey, highKey, isForward, lowKeyInclusive, highKeyInclusive);
+				IBTreeCursor rangeCursor = new RangeSearchCursor(leafFrame);
+				RangePredicate rangePred = createRangePredicate(lowKey,
+						highKey, isForward, lowKeyInclusive, highKeyInclusive,
+						btree.getMultiComparator(), btree.getMultiComparator()
+								.getTypeTraits());
+				BTreeOpContext searchOpCtx = btree.createOpContext(
+						BTreeOp.BTO_SEARCH, leafFrame, interiorFrame, null);
+				btree.search(rangeCursor, rangePred, searchOpCtx);
 
-                if (printExpectedResults) {
-                    if (expectedResults.size() > 0) {
-                        char l, u;
+				try {
+					while (rangeCursor.hasNext()) {
+						rangeCursor.next();
+						ITupleReference frameTuple = rangeCursor.getTuple();
+						ByteArrayInputStream inStream = new ByteArrayInputStream(
+								frameTuple.getFieldData(0), frameTuple
+										.getFieldStart(0), frameTuple
+										.getFieldLength(0));
+						DataInput dataIn = new DataInputStream(inStream);
+						Integer res = IntegerSerializerDeserializer.INSTANCE
+								.deserialize(dataIn);
+						results.add(res);
+					}
+				} catch (Exception e) {
+					e.printStackTrace();
+				} finally {
+					rangeCursor.close();
+				}
 
-                        if (lowKeyInclusive)
-                            l = '[';
-                        else
-                            l = '(';
+				getExpectedResults(expectedResults, keys, lowKey, highKey,
+						isForward, lowKeyInclusive, highKeyInclusive);
 
-                        if (highKeyInclusive)
-                            u = ']';
-                        else
-                            u = ')';
+				if (printExpectedResults) {
+					if (expectedResults.size() > 0) {
+						char l, u;
 
-                        System.out.println("RANGE: " + l + " " + lowKey + " , " + highKey + " " + u);
-                        for (Integer r : expectedResults)
-                            System.out.print(r + " ");
-                        System.out.println();
-                    }
-                }
+						if (lowKeyInclusive)
+							l = '[';
+						else
+							l = '(';
 
-                if (results.size() == expectedResults.size()) {
-                    for (int k = 0; k < results.size(); k++) {
-                        if (!results.get(k).equals(expectedResults.get(k))) {
-                            System.out.println("DIFFERENT RESULTS AT: i=" + i + " j=" + j + " k=" + k);
-                            System.out.println(results.get(k) + " " + expectedResults.get(k));
-                            return false;
-                        }
-                    }
-                } else {
-                    System.out.println("UNEQUAL NUMBER OF RESULTS AT: i=" + i + " j=" + j);
-                    System.out.println("RESULTS: " + results.size());
-                    System.out.println("EXPECTED RESULTS: " + expectedResults.size());
-                    return false;
-                }
-            }
-        }
+						if (highKeyInclusive)
+							u = ']';
+						else
+							u = ')';
 
-        return true;
-    }
+						System.out.println("RANGE: " + l + " " + lowKey + " , "
+								+ highKey + " " + u);
+						for (Integer r : expectedResults)
+							System.out.print(r + " ");
+						System.out.println();
+					}
+				}
 
-    @After
-    public void tearDown() {
+				if (results.size() == expectedResults.size()) {
+					for (int k = 0; k < results.size(); k++) {
+						if (!results.get(k).equals(expectedResults.get(k))) {
+							System.out.println("DIFFERENT RESULTS AT: i=" + i
+									+ " j=" + j + " k=" + k);
+							System.out.println(results.get(k) + " "
+									+ expectedResults.get(k));
+							return false;
+						}
+					}
+				} else {
+					System.out.println("UNEQUAL NUMBER OF RESULTS AT: i=" + i
+							+ " j=" + j);
+					System.out.println("RESULTS: " + results.size());
+					System.out.println("EXPECTED RESULTS: "
+							+ expectedResults.size());
+					return false;
+				}
+			}
+		}
 
-    }
+		return true;
+	}
 }
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/StorageManagerTest.java b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/StorageManagerTest.java
index 28c360c..430a33c 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/StorageManagerTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/StorageManagerTest.java
@@ -33,228 +33,237 @@
 import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
 import edu.uci.ics.hyracks.test.support.TestUtils;
 
-public class StorageManagerTest {
-    private static final int PAGE_SIZE = 256;
-    private static final int NUM_PAGES = 10;
+public class StorageManagerTest extends AbstractBTreeTest {
+	private static final int PAGE_SIZE = 256;
+	private static final int NUM_PAGES = 10;
+	private IHyracksStageletContext ctx = TestUtils.create(32768);
 
-    private String tmpDir = System.getProperty("java.io.tmpdir");
+	public class PinnedLatchedPage {
+		public final ICachedPage page;
+		public final LatchType latch;
+		public final int pageId;
 
-    public class PinnedLatchedPage {
-        public final ICachedPage page;
-        public final LatchType latch;
-        public final int pageId;
+		public PinnedLatchedPage(ICachedPage page, int pageId, LatchType latch) {
+			this.page = page;
+			this.pageId = pageId;
+			this.latch = latch;
+		}
+	}
 
-        public PinnedLatchedPage(ICachedPage page, int pageId, LatchType latch) {
-            this.page = page;
-            this.pageId = pageId;
-            this.latch = latch;
-        }
-    }
+	public enum FileAccessType {
+		FTA_READONLY, FTA_WRITEONLY, FTA_MIXED, FTA_UNLATCHED
+	}
 
-    public enum FileAccessType {
-        FTA_READONLY,
-        FTA_WRITEONLY,
-        FTA_MIXED,
-        FTA_UNLATCHED
-    }
+	public class FileAccessWorker implements Runnable {
+		private int workerId;
+		private final IBufferCache bufferCache;
+		private final int maxPages;
+		private final int fileId;
+		private final long thinkTime;
+		private final int maxLoopCount;
+		private final int maxPinnedPages;
+		private final int closeFileChance;
+		private final FileAccessType fta;
+		private int loopCount = 0;
+		private boolean fileIsOpen = false;
+		private Random rnd = new Random(50);
+		private List<PinnedLatchedPage> pinnedPages = new LinkedList<PinnedLatchedPage>();
 
-    public class FileAccessWorker implements Runnable {
-        private int workerId;
-        private final IBufferCache bufferCache;
-        private final int maxPages;
-        private final int fileId;
-        private final long thinkTime;
-        private final int maxLoopCount;
-        private final int maxPinnedPages;
-        private final int closeFileChance;
-        private final FileAccessType fta;
-        private int loopCount = 0;
-        private boolean fileIsOpen = false;
-        private Random rnd = new Random(50);
-        private List<PinnedLatchedPage> pinnedPages = new LinkedList<PinnedLatchedPage>();
+		public FileAccessWorker(int workerId, IBufferCache bufferCache,
+				FileAccessType fta, int fileId, int maxPages,
+				int maxPinnedPages, int maxLoopCount, int closeFileChance,
+				long thinkTime) {
+			this.bufferCache = bufferCache;
+			this.fileId = fileId;
+			this.maxPages = maxPages;
+			this.maxLoopCount = maxLoopCount;
+			this.maxPinnedPages = maxPinnedPages;
+			this.thinkTime = thinkTime;
+			this.closeFileChance = closeFileChance;
+			this.workerId = workerId;
+			this.fta = fta;
+		}
 
-        public FileAccessWorker(int workerId, IBufferCache bufferCache, FileAccessType fta, int fileId, int maxPages,
-                int maxPinnedPages, int maxLoopCount, int closeFileChance, long thinkTime) {
-            this.bufferCache = bufferCache;
-            this.fileId = fileId;
-            this.maxPages = maxPages;
-            this.maxLoopCount = maxLoopCount;
-            this.maxPinnedPages = maxPinnedPages;
-            this.thinkTime = thinkTime;
-            this.closeFileChance = closeFileChance;
-            this.workerId = workerId;
-            this.fta = fta;
-        }
+		private void pinRandomPage() {
+			int pageId = Math.abs(rnd.nextInt() % maxPages);
 
-        private void pinRandomPage() {
-            int pageId = Math.abs(rnd.nextInt() % maxPages);
+			System.out.println(workerId + " PINNING PAGE: " + pageId);
 
-            System.out.println(workerId + " PINNING PAGE: " + pageId);
+			try {
+				ICachedPage page = bufferCache.pin(BufferedFileHandle
+						.getDiskPageId(fileId, pageId), false);
+				LatchType latch = null;
 
-            try {
-                ICachedPage page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, pageId), false);
-                LatchType latch = null;
+				switch (fta) {
 
-                switch (fta) {
+				case FTA_UNLATCHED: {
+					latch = null;
+				}
+					break;
 
-                    case FTA_UNLATCHED: {
-                        latch = null;
-                    }
-                        break;
+				case FTA_READONLY: {
+					System.out.println(workerId + " S LATCHING: " + pageId);
+					page.acquireReadLatch();
+					latch = LatchType.LATCH_S;
+				}
+					break;
 
-                    case FTA_READONLY: {
-                        System.out.println(workerId + " S LATCHING: " + pageId);
-                        page.acquireReadLatch();
-                        latch = LatchType.LATCH_S;
-                    }
-                        break;
+				case FTA_WRITEONLY: {
+					System.out.println(workerId + " X LATCHING: " + pageId);
+					page.acquireWriteLatch();
+					latch = LatchType.LATCH_X;
+				}
+					break;
 
-                    case FTA_WRITEONLY: {
-                        System.out.println(workerId + " X LATCHING: " + pageId);
-                        page.acquireWriteLatch();
-                        latch = LatchType.LATCH_X;
-                    }
-                        break;
+				case FTA_MIXED: {
+					if (rnd.nextInt() % 2 == 0) {
+						System.out.println(workerId + " S LATCHING: " + pageId);
+						page.acquireReadLatch();
+						latch = LatchType.LATCH_S;
+					} else {
+						System.out.println(workerId + " X LATCHING: " + pageId);
+						page.acquireWriteLatch();
+						latch = LatchType.LATCH_X;
+					}
+				}
+					break;
 
-                    case FTA_MIXED: {
-                        if (rnd.nextInt() % 2 == 0) {
-                            System.out.println(workerId + " S LATCHING: " + pageId);
-                            page.acquireReadLatch();
-                            latch = LatchType.LATCH_S;
-                        } else {
-                            System.out.println(workerId + " X LATCHING: " + pageId);
-                            page.acquireWriteLatch();
-                            latch = LatchType.LATCH_X;
-                        }
-                    }
-                        break;
+				}
 
-                }
+				PinnedLatchedPage plPage = new PinnedLatchedPage(page, pageId,
+						latch);
+				pinnedPages.add(plPage);
+			} catch (HyracksDataException e) {
+				e.printStackTrace();
+			}
+		}
 
-                PinnedLatchedPage plPage = new PinnedLatchedPage(page, pageId, latch);
-                pinnedPages.add(plPage);
-            } catch (HyracksDataException e) {
-                e.printStackTrace();
-            }
-        }
+		private void unpinRandomPage() {
+			int index = Math.abs(rnd.nextInt() % pinnedPages.size());
+			try {
+				PinnedLatchedPage plPage = pinnedPages.get(index);
 
-        private void unpinRandomPage() {
-            int index = Math.abs(rnd.nextInt() % pinnedPages.size());
-            try {
-                PinnedLatchedPage plPage = pinnedPages.get(index);
+				if (plPage.latch != null) {
+					if (plPage.latch == LatchType.LATCH_S) {
+						System.out.println(workerId + " S UNLATCHING: "
+								+ plPage.pageId);
+						plPage.page.releaseReadLatch();
+					} else {
+						System.out.println(workerId + " X UNLATCHING: "
+								+ plPage.pageId);
+						plPage.page.releaseWriteLatch();
+					}
+				}
+				System.out.println(workerId + " UNPINNING PAGE: "
+						+ plPage.pageId);
 
-                if (plPage.latch != null) {
-                    if (plPage.latch == LatchType.LATCH_S) {
-                        System.out.println(workerId + " S UNLATCHING: " + plPage.pageId);
-                        plPage.page.releaseReadLatch();
-                    } else {
-                        System.out.println(workerId + " X UNLATCHING: " + plPage.pageId);
-                        plPage.page.releaseWriteLatch();
-                    }
-                }
-                System.out.println(workerId + " UNPINNING PAGE: " + plPage.pageId);
+				bufferCache.unpin(plPage.page);
+				pinnedPages.remove(index);
+			} catch (HyracksDataException e) {
+				e.printStackTrace();
+			}
+		}
 
-                bufferCache.unpin(plPage.page);
-                pinnedPages.remove(index);
-            } catch (HyracksDataException e) {
-                e.printStackTrace();
-            }
-        }
+		private void openFile() {
+			System.out.println(workerId + " OPENING FILE: " + fileId);
+			try {
+				bufferCache.openFile(fileId);
+				fileIsOpen = true;
+			} catch (HyracksDataException e) {
+				e.printStackTrace();
+			}
+		}
 
-        private void openFile() {
-            System.out.println(workerId + " OPENING FILE: " + fileId);
-            try {
-                bufferCache.openFile(fileId);
-                fileIsOpen = true;
-            } catch (HyracksDataException e) {
-                e.printStackTrace();
-            }
-        }
+		private void closeFile() {
+			System.out.println(workerId + " CLOSING FILE: " + fileId);
+			try {
+				bufferCache.closeFile(fileId);
+				fileIsOpen = false;
+			} catch (HyracksDataException e) {
+				e.printStackTrace();
+			}
+		}
 
-        private void closeFile() {
-            System.out.println(workerId + " CLOSING FILE: " + fileId);
-            try {
-                bufferCache.closeFile(fileId);
-                fileIsOpen = false;
-            } catch (HyracksDataException e) {
-                e.printStackTrace();
-            }
-        }
+		@Override
+		public void run() {
 
-        @Override
-        public void run() {
+			openFile();
 
-            openFile();
+			while (loopCount < maxLoopCount) {
+				loopCount++;
 
-            while (loopCount < maxLoopCount) {
-                loopCount++;
+				System.out.println(workerId + " LOOP: " + loopCount + "/"
+						+ maxLoopCount);
 
-                System.out.println(workerId + " LOOP: " + loopCount + "/" + maxLoopCount);
+				if (fileIsOpen) {
 
-                if (fileIsOpen) {
+					// pin some pages
+					int pagesToPin = Math.abs(rnd.nextInt())
+							% (maxPinnedPages - pinnedPages.size());
+					for (int i = 0; i < pagesToPin; i++) {
+						pinRandomPage();
+					}
 
-                    // pin some pages
-                    int pagesToPin = Math.abs(rnd.nextInt()) % (maxPinnedPages - pinnedPages.size());
-                    for (int i = 0; i < pagesToPin; i++) {
-                        pinRandomPage();
-                    }
+					// do some thinking
+					try {
+						Thread.sleep(thinkTime);
+					} catch (InterruptedException e) {
+						e.printStackTrace();
+					}
 
-                    // do some thinking
-                    try {
-                        Thread.sleep(thinkTime);
-                    } catch (InterruptedException e) {
-                        e.printStackTrace();
-                    }
+					// unpin some pages
+					if (!pinnedPages.isEmpty()) {
+						int pagesToUnpin = Math.abs(rnd.nextInt())
+								% pinnedPages.size();
+						for (int i = 0; i < pagesToUnpin; i++) {
+							unpinRandomPage();
+						}
+					}
 
-                    // unpin some pages
-                    if (!pinnedPages.isEmpty()) {
-                        int pagesToUnpin = Math.abs(rnd.nextInt()) % pinnedPages.size();
-                        for (int i = 0; i < pagesToUnpin; i++) {
-                            unpinRandomPage();
-                        }
-                    }
+					// possibly close file
+					int closeFileCheck = Math.abs(rnd.nextInt())
+							% closeFileChance;
+					if (pinnedPages.isEmpty() || closeFileCheck == 0) {
+						int numPinnedPages = pinnedPages.size();
+						for (int i = 0; i < numPinnedPages; i++) {
+							unpinRandomPage();
+						}
+						closeFile();
+					}
+				} else {
+					openFile();
+				}
+			}
 
-                    // possibly close file
-                    int closeFileCheck = Math.abs(rnd.nextInt()) % closeFileChance;
-                    if (pinnedPages.isEmpty() || closeFileCheck == 0) {
-                        int numPinnedPages = pinnedPages.size();
-                        for (int i = 0; i < numPinnedPages; i++) {
-                            unpinRandomPage();
-                        }
-                        closeFile();
-                    }
-                } else {
-                    openFile();
-                }
-            }
+			if (fileIsOpen) {
+				int numPinnedPages = pinnedPages.size();
+				for (int i = 0; i < numPinnedPages; i++) {
+					unpinRandomPage();
+				}
+				closeFile();
+			}
+		}
+	}
 
-            if (fileIsOpen) {
-                int numPinnedPages = pinnedPages.size();
-                for (int i = 0; i < numPinnedPages; i++) {
-                    unpinRandomPage();
-                }
-                closeFile();
-            }
-        }
-    }
+	@Test
+	public void oneThreadOneFileTest() throws Exception {
+		TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
+		IBufferCache bufferCache = TestStorageManagerComponentHolder
+				.getBufferCache(ctx);
+		IFileMapProvider fmp = TestStorageManagerComponentHolder
+				.getFileMapProvider(ctx);
+		FileReference file = new FileReference(new File(fileName));
+		bufferCache.createFile(file);
+		int fileId = fmp.lookupFileId(file);
+		bufferCache.openFile(fileId);
 
-    @Test
-    public void oneThreadOneFileTest() throws Exception {
-        IHyracksStageletContext ctx = TestUtils.create(32768);
-        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
-        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
-        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
-        FileReference file = new FileReference(new File(tmpDir + "/" + "testfile01.bin"));
-        bufferCache.createFile(file);
-        int fileId = fmp.lookupFileId(file);
+		Thread worker = new Thread(new FileAccessWorker(0, bufferCache,
+				FileAccessType.FTA_UNLATCHED, fileId, 10, 10, 100, 10, 0));
 
-        Thread worker = new Thread(new FileAccessWorker(0, bufferCache, FileAccessType.FTA_UNLATCHED, fileId, 10, 10,
-                100, 10, 0));
+		worker.start();
 
-        worker.start();
+		worker.join();
 
-        worker.join();
-
-        bufferCache.close();
-    }
-}
\ No newline at end of file
+		bufferCache.close();
+	}
+}
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/searchers/AbstractInvIndexTest.java b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/searchers/AbstractInvIndexTest.java
new file mode 100644
index 0000000..5d2cfff
--- /dev/null
+++ b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/searchers/AbstractInvIndexTest.java
@@ -0,0 +1,25 @@
+package edu.uci.ics.hyracks.storage.am.invertedindex.searchers;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.junit.AfterClass;
+
+public abstract class AbstractInvIndexTest {
+
+    protected final static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMyy-hhmmssSS");
+    protected final static String tmpDir = System.getProperty("java.io.tmpdir");
+    protected final static String sep = System.getProperty("file.separator");
+    protected final static String fileName = tmpDir + sep + simpleDateFormat.format(new Date());
+
+    protected void print(String str) {
+        System.out.print(str);
+    }
+
+    @AfterClass
+    public static void cleanup() throws Exception {
+        File f = new File(fileName);
+        f.deleteOnExit();
+    }
+}
diff --git a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/searchers/SimpleConjunctiveSearcherTest.java b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/searchers/SimpleConjunctiveSearcherTest.java
index 0e53d3f..f61249b 100644
--- a/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/searchers/SimpleConjunctiveSearcherTest.java
+++ b/hyracks/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/searchers/SimpleConjunctiveSearcherTest.java
@@ -24,14 +24,10 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Random;
-import java.util.UUID;
 
 import org.junit.Test;
 
-import edu.uci.ics.hyracks.api.application.INCApplicationContext;
 import edu.uci.ics.hyracks.api.comm.IFrameTupleAccessor;
-import edu.uci.ics.hyracks.api.context.IHyracksJobletContext;
-import edu.uci.ics.hyracks.api.context.IHyracksRootContext;
 import edu.uci.ics.hyracks.api.context.IHyracksStageletContext;
 import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
 import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
@@ -65,18 +61,14 @@
 import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedIndexResultCursor;
 import edu.uci.ics.hyracks.storage.am.invertedindex.impls.SimpleConjunctiveSearcher;
 import edu.uci.ics.hyracks.storage.am.invertedindex.tokenizers.DelimitedUTF8StringBinaryTokenizer;
-import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
 import edu.uci.ics.hyracks.storage.common.buffercache.ICacheMemoryAllocator;
 import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
-import edu.uci.ics.hyracks.test.support.TestJobletContext;
-import edu.uci.ics.hyracks.test.support.TestNCApplicationContext;
-import edu.uci.ics.hyracks.test.support.TestRootContext;
-import edu.uci.ics.hyracks.test.support.TestStageletContext;
 import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
-import edu.uci.ics.hyracks.test.support.TestStorageManagerInterface;
+import edu.uci.ics.hyracks.test.support.TestUtils;
 
-public class SimpleConjunctiveSearcherTest {
+public class SimpleConjunctiveSearcherTest extends AbstractInvIndexTest {
+
     // testing params
     // private static final int PAGE_SIZE = 256;
     // private static final int NUM_PAGES = 10;
@@ -87,12 +79,7 @@
     private static final int PAGE_SIZE = 32768;
     private static final int NUM_PAGES = 10;
     private static final int HYRACKS_FRAME_SIZE = 32768;
-
-    static {
-        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
-    }
-
-    private String tmpDir = System.getProperty("java.io.tmpdir");
+    private IHyracksStageletContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
 
     public class BufferAllocator implements ICacheMemoryAllocator {
         @Override
@@ -107,16 +94,11 @@
 
     @Test
     public void test01() throws Exception {
-        IHyracksRootContext rootCtx = new TestRootContext(HYRACKS_FRAME_SIZE);
-        INCApplicationContext appCtx = new TestNCApplicationContext(rootCtx);
-        IHyracksJobletContext jobletCtx = new TestJobletContext(appCtx, UUID.randomUUID(), 0);
-        IHyracksStageletContext stageletCtx = new TestStageletContext(jobletCtx, UUID.randomUUID());
 
-        IStorageManagerInterface smi = new TestStorageManagerInterface();
-
-        IBufferCache bufferCache = smi.getBufferCache(stageletCtx);
-        IFileMapProvider fmp = smi.getFileMapProvider(stageletCtx);
-        FileReference file = new FileReference(new File(tmpDir + "/" + "btreetest.bin"));
+        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
+        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);
@@ -155,15 +137,15 @@
         Random rnd = new Random();
         rnd.setSeed(50);
 
-        ByteBuffer frame = stageletCtx.allocateFrame();
-        FrameTupleAppender appender = new FrameTupleAppender(stageletCtx.getFrameSize());
+        ByteBuffer frame = ctx.allocateFrame();
+        FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
         ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
         DataOutput dos = tb.getDataOutput();
 
         ISerializerDeserializer[] btreeSerde = { UTF8StringSerializerDeserializer.INSTANCE,
                 IntegerSerializerDeserializer.INSTANCE };
         RecordDescriptor btreeRecDesc = new RecordDescriptor(btreeSerde);
-        IFrameTupleAccessor accessor = new FrameTupleAccessor(stageletCtx.getFrameSize(), btreeRecDesc);
+        IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(), btreeRecDesc);
         accessor.reset(frame);
         FrameTupleReference tuple = new FrameTupleReference();
 
@@ -213,11 +195,11 @@
         ISerializerDeserializer[] querySerde = { UTF8StringSerializerDeserializer.INSTANCE };
         RecordDescriptor queryRecDesc = new RecordDescriptor(querySerde);
 
-        FrameTupleAppender queryAppender = new FrameTupleAppender(stageletCtx.getFrameSize());
+        FrameTupleAppender queryAppender = new FrameTupleAppender(ctx.getFrameSize());
         ArrayTupleBuilder queryTb = new ArrayTupleBuilder(querySerde.length);
         DataOutput queryDos = queryTb.getDataOutput();
 
-        IFrameTupleAccessor queryAccessor = new FrameTupleAccessor(stageletCtx.getFrameSize(), queryRecDesc);
+        IFrameTupleAccessor queryAccessor = new FrameTupleAccessor(ctx.getFrameSize(), queryRecDesc);
         queryAccessor.reset(frame);
         FrameTupleReference queryTuple = new FrameTupleReference();
 
@@ -240,11 +222,11 @@
             resultSerde[i] = btreeSerde[numKeyFields + i];
         }
         RecordDescriptor resultRecDesc = new RecordDescriptor(resultSerde);
-        FrameTupleAccessor resultAccessor = new FrameTupleAccessor(stageletCtx.getFrameSize(), resultRecDesc);
+        FrameTupleAccessor resultAccessor = new FrameTupleAccessor(ctx.getFrameSize(), resultRecDesc);
         FrameTupleReference resultTuple = new FrameTupleReference();
-
-        SimpleConjunctiveSearcher searcher = new SimpleConjunctiveSearcher(stageletCtx, btree, btreeRecDesc,
-                queryTokenizer, numKeyFields, numValueFields);
+        
+        SimpleConjunctiveSearcher searcher = new SimpleConjunctiveSearcher(ctx, btree, btreeRecDesc, queryTokenizer,
+                numKeyFields, numValueFields);
 
         long timeStart = System.currentTimeMillis();
         searcher.search(queryTuple, 0);
@@ -259,8 +241,8 @@
             for (int i = 0; i < resultAccessor.getTupleCount(); i++) {
                 resultTuple.reset(resultAccessor, i);
                 for (int j = 0; j < resultTuple.getFieldCount(); j++) {
-                    ByteArrayInputStream inStream = new ByteArrayInputStream(resultTuple.getFieldData(j),
-                            resultTuple.getFieldStart(j), resultTuple.getFieldLength(j));
+                    ByteArrayInputStream inStream = new ByteArrayInputStream(resultTuple.getFieldData(j), resultTuple
+                            .getFieldStart(j), resultTuple.getFieldLength(j));
                     DataInput dataIn = new DataInputStream(inStream);
                     Object o = resultSerde[j].deserialize(dataIn);
                     System.out.print(o + " ");
