Starting implementation of Inverted Index operators. Did some refactoring of the BTree in the process.

git-svn-id: https://hyracks.googlecode.com/svn/branches/hyracks_indexes@472 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/InsertPipelineExample.java b/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/InsertPipelineExample.java
index 282b242..b8d5f21 100644
--- a/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/InsertPipelineExample.java
+++ b/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/InsertPipelineExample.java
@@ -47,9 +47,10 @@
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeInsertUpdateDeleteOperatorDescriptor;
-import edu.uci.ics.hyracks.storage.am.btree.dataflow.IBTreeRegistryProvider;
 import edu.uci.ics.hyracks.storage.am.btree.frames.NSMInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.frames.NSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.TreeIndexOp;
 import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleWriterFactory;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
@@ -127,7 +128,7 @@
         // run data generator on first nodecontroller given
         PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, dataGen, splitNCs[0]);
 
-        IBTreeRegistryProvider btreeRegistryProvider = BTreeRegistryProvider.INSTANCE;
+        IIndexRegistryProvider<BTree> btreeRegistryProvider = BTreeRegistryProvider.INSTANCE;
         IStorageManagerInterface storageManager = StorageManagerInterface.INSTANCE;
 
         // prepare insertion into primary index
diff --git a/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexBulkLoadExample.java b/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexBulkLoadExample.java
index 87b9d36..8fec2af 100644
--- a/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexBulkLoadExample.java
+++ b/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexBulkLoadExample.java
@@ -45,9 +45,10 @@
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeBulkLoadOperatorDescriptor;
-import edu.uci.ics.hyracks.storage.am.btree.dataflow.IBTreeRegistryProvider;
 import edu.uci.ics.hyracks.storage.am.btree.frames.NSMInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.frames.NSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
 import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleWriterFactory;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 
@@ -146,7 +147,7 @@
         TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(typeTraits);
         IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory(tupleWriterFactory);
         IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory(tupleWriterFactory);
-        IBTreeRegistryProvider btreeRegistryProvider = BTreeRegistryProvider.INSTANCE;
+        IIndexRegistryProvider<BTree> btreeRegistryProvider = BTreeRegistryProvider.INSTANCE;
         IStorageManagerInterface storageManager = StorageManagerInterface.INSTANCE;
 
         // the B-Tree expects its keyfields to be at the front of its input
diff --git a/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexEnlistFilesExample.java b/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexEnlistFilesExample.java
index 403b611..8259edc 100644
--- a/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexEnlistFilesExample.java
+++ b/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexEnlistFilesExample.java
@@ -36,9 +36,10 @@
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeFileEnlistmentOperatorDescriptor;
-import edu.uci.ics.hyracks.storage.am.btree.dataflow.IBTreeRegistryProvider;
 import edu.uci.ics.hyracks.storage.am.btree.frames.NSMInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.frames.NSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
 import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleWriterFactory;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 
@@ -101,7 +102,7 @@
         TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(typeTraits);
         IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory(tupleWriterFactory);
         IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory(tupleWriterFactory);
-        IBTreeRegistryProvider btreeRegistryProvider = BTreeRegistryProvider.INSTANCE;
+        IIndexRegistryProvider<BTree> btreeRegistryProvider = BTreeRegistryProvider.INSTANCE;
         IStorageManagerInterface storageManager = StorageManagerInterface.INSTANCE;
 
         IBinaryComparatorFactory[] comparatorFactories = new IBinaryComparatorFactory[1];
diff --git a/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexSearchExample.java b/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexSearchExample.java
index 40f3199..7453c28 100644
--- a/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexSearchExample.java
+++ b/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/PrimaryIndexSearchExample.java
@@ -42,9 +42,10 @@
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeSearchOperatorDescriptor;
-import edu.uci.ics.hyracks.storage.am.btree.dataflow.IBTreeRegistryProvider;
 import edu.uci.ics.hyracks.storage.am.btree.frames.NSMInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.frames.NSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
 import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleWriterFactory;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 
@@ -103,7 +104,7 @@
         TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(typeTraits);
         IBTreeInteriorFrameFactory interiorFrameFactory = new NSMInteriorFrameFactory(tupleWriterFactory);
         IBTreeLeafFrameFactory leafFrameFactory = new NSMLeafFrameFactory(tupleWriterFactory);
-        IBTreeRegistryProvider btreeRegistryProvider = BTreeRegistryProvider.INSTANCE;
+        IIndexRegistryProvider<BTree> btreeRegistryProvider = BTreeRegistryProvider.INSTANCE;
         IStorageManagerInterface storageManager = StorageManagerInterface.INSTANCE;
 
         // schema of tuples coming out of primary index
diff --git a/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/SecondaryIndexBulkLoadExample.java b/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/SecondaryIndexBulkLoadExample.java
index 8ac8176..a108c91 100644
--- a/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/SecondaryIndexBulkLoadExample.java
+++ b/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/SecondaryIndexBulkLoadExample.java
@@ -40,9 +40,10 @@
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeBulkLoadOperatorDescriptor;
 import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeDiskOrderScanOperatorDescriptor;
-import edu.uci.ics.hyracks.storage.am.btree.dataflow.IBTreeRegistryProvider;
 import edu.uci.ics.hyracks.storage.am.btree.frames.NSMInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.frames.NSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
 import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleWriterFactory;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 
@@ -96,7 +97,7 @@
 
         String[] splitNCs = options.ncs.split(",");
 
-        IBTreeRegistryProvider btreeRegistryProvider = BTreeRegistryProvider.INSTANCE;
+        IIndexRegistryProvider<BTree> btreeRegistryProvider = BTreeRegistryProvider.INSTANCE;
         IStorageManagerInterface storageManager = StorageManagerInterface.INSTANCE;
 
         // schema of tuples that we are retrieving from the primary index
diff --git a/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/SecondaryIndexSearchExample.java b/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/SecondaryIndexSearchExample.java
index 621f868..7b0e714 100644
--- a/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/SecondaryIndexSearchExample.java
+++ b/hyracks-examples/btree-example/btreeclient/src/main/java/edu/uci/ics/hyracks/examples/btree/client/SecondaryIndexSearchExample.java
@@ -42,9 +42,10 @@
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeSearchOperatorDescriptor;
-import edu.uci.ics.hyracks.storage.am.btree.dataflow.IBTreeRegistryProvider;
 import edu.uci.ics.hyracks.storage.am.btree.frames.NSMInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.frames.NSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
 import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleWriterFactory;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 
@@ -95,7 +96,7 @@
 
         String[] splitNCs = options.ncs.split(",");
 
-        IBTreeRegistryProvider btreeRegistryProvider = BTreeRegistryProvider.INSTANCE;
+        IIndexRegistryProvider<BTree> btreeRegistryProvider = BTreeRegistryProvider.INSTANCE;
         IStorageManagerInterface storageManager = StorageManagerInterface.INSTANCE;
 
         // schema of tuples coming out of secondary index
diff --git a/hyracks-examples/btree-example/btreehelper/src/main/java/edu/uci/ics/hyracks/examples/btree/helper/BTreeRegistryProvider.java b/hyracks-examples/btree-example/btreehelper/src/main/java/edu/uci/ics/hyracks/examples/btree/helper/BTreeRegistryProvider.java
index 57b10a3..7bfb11b 100644
--- a/hyracks-examples/btree-example/btreehelper/src/main/java/edu/uci/ics/hyracks/examples/btree/helper/BTreeRegistryProvider.java
+++ b/hyracks-examples/btree-example/btreehelper/src/main/java/edu/uci/ics/hyracks/examples/btree/helper/BTreeRegistryProvider.java
@@ -16,10 +16,11 @@
 package edu.uci.ics.hyracks.examples.btree.helper;
 
 import edu.uci.ics.hyracks.api.context.IHyracksStageletContext;
-import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeRegistry;
-import edu.uci.ics.hyracks.storage.am.btree.dataflow.IBTreeRegistryProvider;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexRegistry;
 
-public class BTreeRegistryProvider implements IBTreeRegistryProvider {
+public class BTreeRegistryProvider implements IIndexRegistryProvider<BTree> {
     private static final long serialVersionUID = 1L;
 
     public static final BTreeRegistryProvider INSTANCE = new BTreeRegistryProvider();
@@ -28,7 +29,7 @@
     }
 
     @Override
-    public BTreeRegistry getBTreeRegistry(IHyracksStageletContext ctx) {
+    public IndexRegistry<BTree> getRegistry(IHyracksStageletContext ctx) {
         return RuntimeContext.get(ctx).getBTreeRegistry();
     }
 }
\ No newline at end of file
diff --git a/hyracks-examples/btree-example/btreehelper/src/main/java/edu/uci/ics/hyracks/examples/btree/helper/RuntimeContext.java b/hyracks-examples/btree-example/btreehelper/src/main/java/edu/uci/ics/hyracks/examples/btree/helper/RuntimeContext.java
index 623e625..282621f 100644
--- a/hyracks-examples/btree-example/btreehelper/src/main/java/edu/uci/ics/hyracks/examples/btree/helper/RuntimeContext.java
+++ b/hyracks-examples/btree-example/btreehelper/src/main/java/edu/uci/ics/hyracks/examples/btree/helper/RuntimeContext.java
@@ -17,7 +17,8 @@
 
 import edu.uci.ics.hyracks.api.application.INCApplicationContext;
 import edu.uci.ics.hyracks.api.context.IHyracksStageletContext;
-import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeRegistry;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexRegistry;
 import edu.uci.ics.hyracks.storage.common.buffercache.BufferCache;
 import edu.uci.ics.hyracks.storage.common.buffercache.ClockPageReplacementStrategy;
 import edu.uci.ics.hyracks.storage.common.buffercache.HeapBufferAllocator;
@@ -29,7 +30,7 @@
 import edu.uci.ics.hyracks.storage.common.smi.TransientFileMapManager;
 
 public class RuntimeContext {
-    private BTreeRegistry btreeRegistry;
+    private IndexRegistry<BTree> btreeRegistry;
     private IBufferCache bufferCache;
     private IFileMapManager fileMapManager;
 
@@ -38,7 +39,7 @@
         ICacheMemoryAllocator allocator = new HeapBufferAllocator();
         IPageReplacementStrategy prs = new ClockPageReplacementStrategy();
         bufferCache = new BufferCache(appCtx.getRootContext().getIOManager(), allocator, prs, fileMapManager, 32768, 50, 100);
-        btreeRegistry = new BTreeRegistry();
+        btreeRegistry = new IndexRegistry<BTree>();
     }
 
     public void close() {
@@ -53,7 +54,7 @@
         return fileMapManager;
     }
 
-    public BTreeRegistry getBTreeRegistry() {
+    public IndexRegistry<BTree> getBTreeRegistry() {
         return btreeRegistry;
     }
     
diff --git a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeOperatorsTest.java b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeOperatorsTest.java
index 6a10daa..2ffc96c 100644
--- a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeOperatorsTest.java
+++ b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/btree/BTreeOperatorsTest.java
@@ -53,9 +53,10 @@
 import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeInsertUpdateDeleteOperatorDescriptor;
 import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeSearchOperatorDescriptor;
 import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeStatsOperatorDescriptor;
-import edu.uci.ics.hyracks.storage.am.btree.dataflow.IBTreeRegistryProvider;
 import edu.uci.ics.hyracks.storage.am.btree.frames.NSMInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.frames.NSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.TreeIndexOp;
 import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleWriterFactory;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
@@ -70,7 +71,7 @@
 	}
 
 	private IStorageManagerInterface storageManager = new TestStorageManagerInterface();
-	private IBTreeRegistryProvider btreeRegistryProvider = new TestBTreeRegistryProvider();
+	private IIndexRegistryProvider<BTree> btreeRegistryProvider = new TestBTreeRegistryProvider();
 
 	private final static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
 			"ddMMyy-hhmmssSS");
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/AbstractBTreeOperatorDescriptor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/AbstractBTreeOperatorDescriptor.java
index 35e6951..137eb77 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/AbstractBTreeOperatorDescriptor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/AbstractBTreeOperatorDescriptor.java
@@ -23,9 +23,12 @@
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 
-public abstract class AbstractBTreeOperatorDescriptor extends AbstractSingleActivityOperatorDescriptor {
+public abstract class AbstractBTreeOperatorDescriptor extends AbstractSingleActivityOperatorDescriptor implements
+        IBTreeOperatorDescriptorHelper {
 
     private static final long serialVersionUID = 1L;
 
@@ -37,13 +40,13 @@
     protected final IBTreeLeafFrameFactory leafFrameFactory;
 
     protected final IStorageManagerInterface storageManager;
-    protected final IBTreeRegistryProvider btreeRegistryProvider;
+    protected final IIndexRegistryProvider<BTree> btreeRegistryProvider;
 
     protected final ITypeTrait[] typeTraits;
 
     public AbstractBTreeOperatorDescriptor(JobSpecification spec, int inputArity, int outputArity,
             RecordDescriptor recDesc, IStorageManagerInterface storageManager,
-            IBTreeRegistryProvider btreeRegistryProvider, IFileSplitProvider fileSplitProvider,
+            IIndexRegistryProvider<BTree> btreeRegistryProvider, IFileSplitProvider fileSplitProvider,
             IBTreeInteriorFrameFactory interiorFactory, IBTreeLeafFrameFactory leafFactory, ITypeTrait[] typeTraits,
             IBinaryComparatorFactory[] comparatorFactories) {
         super(spec, inputArity, outputArity);
@@ -58,34 +61,42 @@
             recordDescriptors[0] = recDesc;
     }
 
-    public IFileSplitProvider getFileSplitProvider() {
+    @Override
+    public IFileSplitProvider getBTreeFileSplitProvider() {
         return fileSplitProvider;
     }
 
-    public IBinaryComparatorFactory[] getComparatorFactories() {
+    @Override
+    public IBinaryComparatorFactory[] getBTreeComparatorFactories() {
         return comparatorFactories;
     }
 
-    public ITypeTrait[] getTypeTraits() {
+    @Override
+    public ITypeTrait[] getBTreeTypeTraits() {
         return typeTraits;
     }
 
-    public IBTreeInteriorFrameFactory getInteriorFactory() {
+    @Override
+    public IBTreeInteriorFrameFactory getBTreeInteriorFactory() {
         return interiorFrameFactory;
     }
 
-    public IBTreeLeafFrameFactory getLeafFactory() {
+    @Override
+    public IBTreeLeafFrameFactory getBTreeLeafFactory() {
         return leafFrameFactory;
     }
 
+    @Override
     public IStorageManagerInterface getStorageManager() {
         return storageManager;
     }
 
-    public IBTreeRegistryProvider getBtreeRegistryProvider() {
+    @Override
+    public IIndexRegistryProvider<BTree> getBTreeRegistryProvider() {
         return btreeRegistryProvider;
     }
 
+    @Override
     public RecordDescriptor getRecordDescriptor() {
         return recordDescriptors[0];
     }
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorDescriptor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorDescriptor.java
index a4c4b61..2f8e4a9 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorDescriptor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorDescriptor.java
@@ -25,6 +25,8 @@
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 
 public class BTreeBulkLoadOperatorDescriptor extends AbstractBTreeOperatorDescriptor {
@@ -35,7 +37,7 @@
     private final float fillFactor;
 
     public BTreeBulkLoadOperatorDescriptor(JobSpecification spec, IStorageManagerInterface storageManager,
-            IBTreeRegistryProvider btreeRegistryProvider, IFileSplitProvider fileSplitProvider,
+            IIndexRegistryProvider<BTree> btreeRegistryProvider, IFileSplitProvider fileSplitProvider,
             IBTreeInteriorFrameFactory interiorFactory, IBTreeLeafFrameFactory leafFactory, ITypeTrait[] typeTraits,
             IBinaryComparatorFactory[] comparatorFactories, int[] fieldPermutation, float fillFactor) {
         super(spec, 1, 0, null, storageManager, btreeRegistryProvider, fileSplitProvider, interiorFactory, leafFactory,
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorNodePushable.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorNodePushable.java
index f2f347f..e13a82a 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorNodePushable.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeBulkLoadOperatorNodePushable.java
@@ -24,72 +24,66 @@
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractUnaryInputSinkOperatorNodePushable;
 import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrame;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexHelperOpenMode;
 import edu.uci.ics.hyracks.storage.am.common.frames.LIFOMetaDataFrame;
 
-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, IndexHelperOpenMode.CREATE);
+        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);
-		ITreeIndexMetaDataFrame metaFrame = new LIFOMetaDataFrame();
-		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 open() throws HyracksDataException {
+        AbstractBTreeOperatorDescriptor opDesc = (AbstractBTreeOperatorDescriptor) btreeOpHelper
+                .getOperatorDescriptor();
+        RecordDescriptor recDesc = recordDescProvider.getInputRecordDescriptor(opDesc.getOperatorId(), 0);
+        accessor = new FrameTupleAccessor(btreeOpHelper.getHyracksStageletContext().getFrameSize(), recDesc);
+        ITreeIndexMetaDataFrame metaFrame = new LIFOMetaDataFrame();
+        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-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorDescriptor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorDescriptor.java
index 17fbf97..e684ff4 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorDescriptor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorDescriptor.java
@@ -25,6 +25,8 @@
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 
 public class BTreeDiskOrderScanOperatorDescriptor extends AbstractBTreeOperatorDescriptor {
@@ -32,7 +34,7 @@
     private static final long serialVersionUID = 1L;
 
     public BTreeDiskOrderScanOperatorDescriptor(JobSpecification spec, RecordDescriptor recDesc,
-            IStorageManagerInterface storageManager, IBTreeRegistryProvider btreeRegistryProvider,
+            IStorageManagerInterface storageManager, IIndexRegistryProvider<BTree> btreeRegistryProvider,
             IFileSplitProvider fileSplitProvider, IBTreeInteriorFrameFactory interiorFactory,
             IBTreeLeafFrameFactory leafFactory, ITypeTrait[] typeTraits) {
         super(spec, 0, 1, recDesc, storageManager, btreeRegistryProvider, fileSplitProvider, interiorFactory,
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorNodePushable.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorNodePushable.java
index a3eb2f3..16a1d05 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorNodePushable.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDiskOrderScanOperatorNodePushable.java
@@ -27,6 +27,7 @@
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrame;
 import edu.uci.ics.hyracks.storage.am.btree.impls.DiskOrderScanCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrame;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexHelperOpenMode;
 import edu.uci.ics.hyracks.storage.am.common.frames.LIFOMetaDataFrame;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
 
@@ -35,13 +36,13 @@
 
     public BTreeDiskOrderScanOperatorNodePushable(AbstractBTreeOperatorDescriptor opDesc, IHyracksStageletContext ctx,
             int partition) {
-        btreeOpHelper = new BTreeOpHelper(opDesc, ctx, partition, BTreeOpHelper.BTreeMode.OPEN_BTREE);
+        btreeOpHelper = new BTreeOpHelper(opDesc, ctx, partition, IndexHelperOpenMode.OPEN);
     }
 
     @Override
     public void initialize() throws HyracksDataException {
 
-        IBTreeLeafFrame cursorFrame = btreeOpHelper.getOperatorDescriptor().getLeafFactory().getFrame();
+        IBTreeLeafFrame cursorFrame = btreeOpHelper.getOperatorDescriptor().getBTreeLeafFactory().getFrame();
         DiskOrderScanCursor cursor = new DiskOrderScanCursor(cursorFrame);
         ITreeIndexMetaDataFrame metaFrame = new LIFOMetaDataFrame();
 
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDropOperatorDescriptor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDropOperatorDescriptor.java
index 970d44a..0a41bd4 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDropOperatorDescriptor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDropOperatorDescriptor.java
@@ -22,6 +22,8 @@
 import edu.uci.ics.hyracks.api.job.JobSpecification;
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractSingleActivityOperatorDescriptor;
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 
 public class BTreeDropOperatorDescriptor extends AbstractSingleActivityOperatorDescriptor {
@@ -29,11 +31,11 @@
     private static final long serialVersionUID = 1L;
 
     private IStorageManagerInterface storageManager;
-    private IBTreeRegistryProvider btreeRegistryProvider;
+    private IIndexRegistryProvider<BTree> btreeRegistryProvider;
     private IFileSplitProvider fileSplitProvider;
-
+    
     public BTreeDropOperatorDescriptor(JobSpecification spec, IStorageManagerInterface storageManager,
-            IBTreeRegistryProvider btreeRegistryProvider, IFileSplitProvider fileSplitProvider) {
+            IIndexRegistryProvider<BTree> btreeRegistryProvider, IFileSplitProvider fileSplitProvider) {
         super(spec, 0, 0);
         this.storageManager = storageManager;
         this.btreeRegistryProvider = btreeRegistryProvider;
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDropOperatorNodePushable.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDropOperatorNodePushable.java
index c087fdd..c5f3d32 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDropOperatorNodePushable.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDropOperatorNodePushable.java
@@ -25,6 +25,9 @@
 import edu.uci.ics.hyracks.api.io.FileReference;
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractOperatorNodePushable;
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexRegistry;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
 import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
@@ -33,13 +36,13 @@
 	private static final Logger LOGGER = Logger.getLogger(BTreeDropOperatorNodePushable.class.getName());
 	
 	private final IHyracksStageletContext ctx;
-    private IBTreeRegistryProvider btreeRegistryProvider;
+    private IIndexRegistryProvider<BTree> btreeRegistryProvider;
     private IStorageManagerInterface storageManager;
     private IFileSplitProvider fileSplitProvider;
     private int partition;
 
     public BTreeDropOperatorNodePushable(IHyracksStageletContext ctx, IStorageManagerInterface storageManager,
-            IBTreeRegistryProvider btreeRegistryProvider, IFileSplitProvider fileSplitProvider, int partition) {
+            IIndexRegistryProvider<BTree> btreeRegistryProvider, IFileSplitProvider fileSplitProvider, int partition) {
         this.ctx = ctx;
         this.storageManager = storageManager;
         this.btreeRegistryProvider = btreeRegistryProvider;
@@ -65,7 +68,7 @@
     public void initialize() throws HyracksDataException {
     	try {
 
-    		BTreeRegistry btreeRegistry = btreeRegistryProvider.getBTreeRegistry(ctx);
+    		IndexRegistry<BTree> btreeRegistry = btreeRegistryProvider.getRegistry(ctx);
     		IBufferCache bufferCache = storageManager.getBufferCache(ctx);
     		IFileMapProvider fileMapProvider = storageManager.getFileMapProvider(ctx);
 
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeFileEnlistmentOperatorDescriptor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeFileEnlistmentOperatorDescriptor.java
index c105274..2694963 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeFileEnlistmentOperatorDescriptor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeFileEnlistmentOperatorDescriptor.java
@@ -27,6 +27,8 @@
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 
 // re-create in-memory state for a btree that has already been built (i.e., the file exists):
@@ -39,7 +41,7 @@
     private static final long serialVersionUID = 1L;
 
     public BTreeFileEnlistmentOperatorDescriptor(JobSpecification spec, RecordDescriptor recDesc,
-            IStorageManagerInterface storageManager, IBTreeRegistryProvider btreeRegistryProvider,
+            IStorageManagerInterface storageManager, IIndexRegistryProvider<BTree> btreeRegistryProvider,
             IFileSplitProvider fileSplitProvider, IBTreeInteriorFrameFactory interiorFactory,
             IBTreeLeafFrameFactory leafFactory, ITypeTrait[] typeTraits, IBinaryComparatorFactory[] comparatorFactories) {
         super(spec, 0, 0, recDesc, storageManager, btreeRegistryProvider, fileSplitProvider, interiorFactory,
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeFileEnlistmentOperatorNodePushable.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeFileEnlistmentOperatorNodePushable.java
index 023cd40..ef78a2d 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeFileEnlistmentOperatorNodePushable.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeFileEnlistmentOperatorNodePushable.java
@@ -20,6 +20,7 @@
 import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractOperatorNodePushable;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexHelperOpenMode;
 
 public class BTreeFileEnlistmentOperatorNodePushable extends AbstractOperatorNodePushable {
 
@@ -27,7 +28,7 @@
 
     public BTreeFileEnlistmentOperatorNodePushable(AbstractBTreeOperatorDescriptor opDesc, IHyracksStageletContext ctx,
             int partition) {
-        btreeOpHelper = new BTreeOpHelper(opDesc, ctx, partition, BTreeOpHelper.BTreeMode.ENLIST_BTREE);
+        btreeOpHelper = new BTreeOpHelper(opDesc, ctx, partition, IndexHelperOpenMode.ENLIST);
     }
 
     @Override
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorDescriptor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorDescriptor.java
index 84cd89d..264bf12 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorDescriptor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorDescriptor.java
@@ -26,6 +26,8 @@
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.TreeIndexOp;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 
@@ -38,7 +40,7 @@
     private TreeIndexOp op;
 
     public BTreeInsertUpdateDeleteOperatorDescriptor(JobSpecification spec, RecordDescriptor recDesc,
-            IStorageManagerInterface storageManager, IBTreeRegistryProvider btreeRegistryProvider,
+            IStorageManagerInterface storageManager, IIndexRegistryProvider<BTree> btreeRegistryProvider,
             IFileSplitProvider fileSplitProvider, IBTreeInteriorFrameFactory interiorFactory,
             IBTreeLeafFrameFactory leafFactory, ITypeTrait[] typeTraits,
             IBinaryComparatorFactory[] comparatorFactories, int[] fieldPermutation, TreeIndexOp op) {
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorNodePushable.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorNodePushable.java
index 7d54060..a8d6725 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorNodePushable.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeInsertUpdateDeleteOperatorNodePushable.java
@@ -25,6 +25,7 @@
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractUnaryInputUnaryOutputOperatorNodePushable;
 import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
 import edu.uci.ics.hyracks.storage.am.btree.impls.BTreeOpContext;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexHelperOpenMode;
 import edu.uci.ics.hyracks.storage.am.common.frames.LIFOMetaDataFrame;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.TreeIndexOp;
 
@@ -40,7 +41,7 @@
     public BTreeInsertUpdateDeleteOperatorNodePushable(AbstractBTreeOperatorDescriptor opDesc,
             IHyracksStageletContext ctx, int partition, int[] fieldPermutation,
             IRecordDescriptorProvider recordDescProvider, TreeIndexOp op) {
-        btreeOpHelper = new BTreeOpHelper(opDesc, ctx, partition, BTreeOpHelper.BTreeMode.OPEN_BTREE);
+        btreeOpHelper = new BTreeOpHelper(opDesc, ctx, partition, IndexHelperOpenMode.OPEN);
         this.recordDescProvider = recordDescProvider;
         this.op = op;
         tuple.setFieldPermutation(fieldPermutation);
@@ -48,7 +49,7 @@
 
     @Override
     public void open() throws HyracksDataException {
-    	AbstractBTreeOperatorDescriptor opDesc = btreeOpHelper.getOperatorDescriptor();
+        AbstractBTreeOperatorDescriptor opDesc = (AbstractBTreeOperatorDescriptor)btreeOpHelper.getOperatorDescriptor();
     	RecordDescriptor inputRecDesc = recordDescProvider.getInputRecordDescriptor(opDesc.getOperatorId(), 0);
     	accessor = new FrameTupleAccessor(btreeOpHelper.getHyracksStageletContext().getFrameSize(), inputRecDesc);
     	writeBuffer = btreeOpHelper.getHyracksStageletContext().allocateFrame();
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeOpHelper.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeOpHelper.java
index 501436a..5e723fb 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeOpHelper.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeOpHelper.java
@@ -25,18 +25,16 @@
 import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrame;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexHelperOpenMode;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexRegistry;
 import edu.uci.ics.hyracks.storage.am.common.frames.LIFOMetaDataFrameFactory;
 import edu.uci.ics.hyracks.storage.am.common.freepage.LinkedListFreePageManager;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
 import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
 import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
 
-final class BTreeOpHelper {
-
-	public enum BTreeMode {
-		OPEN_BTREE, CREATE_BTREE, ENLIST_BTREE
-	}
-	
+public final class BTreeOpHelper {   
+    
 	private IBTreeInteriorFrame interiorFrame;
 	private IBTreeLeafFrame leafFrame;
 
@@ -44,30 +42,30 @@
 	private int btreeFileId = -1;
 	private int partition;
 
-    private AbstractBTreeOperatorDescriptor opDesc;
+    private IBTreeOperatorDescriptorHelper opDesc;
     private IHyracksStageletContext ctx;
 
-	private BTreeMode mode;
+	private IndexHelperOpenMode mode;
 
-    BTreeOpHelper(AbstractBTreeOperatorDescriptor opDesc, final IHyracksStageletContext ctx, int partition,
-            BTreeMode mode) {
+    public BTreeOpHelper(IBTreeOperatorDescriptorHelper opDesc, final IHyracksStageletContext ctx, int partition,
+            IndexHelperOpenMode mode) {
         this.opDesc = opDesc;
         this.ctx = ctx;
         this.mode = mode;
         this.partition = partition;
     }
 
-	void init() throws HyracksDataException {
+	public void init() throws HyracksDataException {
         IBufferCache bufferCache = opDesc.getStorageManager().getBufferCache(ctx);
         IFileMapProvider fileMapProvider = opDesc.getStorageManager().getFileMapProvider(ctx);
-        IFileSplitProvider fileSplitProvider = opDesc.getFileSplitProvider();
+        IFileSplitProvider fileSplitProvider = opDesc.getBTreeFileSplitProvider();
 
         FileReference f = fileSplitProvider.getFileSplits()[partition].getLocalFile();
         boolean fileIsMapped = fileMapProvider.isMapped(f);
 
 		switch (mode) {
 		
-		case OPEN_BTREE: {
+		case OPEN: {
 			if (!fileIsMapped) {
 				throw new HyracksDataException(
 						"Trying to open btree from unmapped file " + f.toString());
@@ -75,8 +73,8 @@
 		}
 		break;
 
-		case CREATE_BTREE:
-		case ENLIST_BTREE: {
+		case CREATE:
+		case ENLIST: {
 			if (!fileIsMapped) {
 				bufferCache.createFile(f);
 			}
@@ -100,10 +98,10 @@
         // otherwise deinit() will try to close the file that failed to open
         btreeFileId = fileId;
 
-		interiorFrame = opDesc.getInteriorFactory().getFrame();
-		leafFrame = opDesc.getLeafFactory().getFrame();
+		interiorFrame = opDesc.getBTreeInteriorFactory().getFrame();
+		leafFrame = opDesc.getBTreeLeafFactory().getFrame();
 
-        BTreeRegistry btreeRegistry = opDesc.getBtreeRegistryProvider().getBTreeRegistry(ctx);
+        IndexRegistry<BTree> btreeRegistry = opDesc.getBTreeRegistryProvider().getRegistry(ctx);
         btree = btreeRegistry.get(btreeFileId);
         if (btree == null) {
 
@@ -116,21 +114,21 @@
 					// 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]
+							.getBTreeComparatorFactories().length];
+					for (int i = 0; i < opDesc.getBTreeComparatorFactories().length; i++) {
+						comparators[i] = opDesc.getBTreeComparatorFactories()[i]
 								.createBinaryComparator();
 					}
 
 					MultiComparator cmp = new MultiComparator(opDesc
-							.getTypeTraits(), comparators);
+							.getBTreeTypeTraits(), comparators);
 
 					// TODO: abstract away in some kind of factory
 					ITreeIndexMetaDataFrameFactory metaDataFrameFactory = new LIFOMetaDataFrameFactory();
 					IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, btreeFileId, 0, metaDataFrameFactory);
-					btree = new BTree(bufferCache, freePageManager, opDesc.getInteriorFactory(),
-							opDesc.getLeafFactory(), cmp);
-					if (mode == BTreeMode.CREATE_BTREE) {
+					btree = new BTree(bufferCache, freePageManager, opDesc.getBTreeInteriorFactory(),
+							opDesc.getBTreeLeafFactory(), cmp);
+					if (mode == IndexHelperOpenMode.CREATE) {
 						ITreeIndexMetaDataFrame metaFrame = btree.getFreePageManager().getMetaDataFrameFactory().getFrame();
 						try {
 							btree.create(btreeFileId, leafFrame, metaFrame);							
@@ -162,7 +160,7 @@
         return ctx;
     }
 
-	public AbstractBTreeOperatorDescriptor getOperatorDescriptor() {
+	public IBTreeOperatorDescriptorHelper getOperatorDescriptor() {
 		return opDesc;
 	}
 
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorDescriptor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorDescriptor.java
index 21f37a3..6e13941 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorDescriptor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorDescriptor.java
@@ -26,6 +26,8 @@
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 
 public class BTreeSearchOperatorDescriptor extends AbstractBTreeOperatorDescriptor {
@@ -40,7 +42,7 @@
     private boolean highKeyInclusive;
 
     public BTreeSearchOperatorDescriptor(JobSpecification spec, RecordDescriptor recDesc,
-            IStorageManagerInterface storageManager, IBTreeRegistryProvider btreeRegistryProvider,
+            IStorageManagerInterface storageManager, IIndexRegistryProvider<BTree> btreeRegistryProvider,
             IFileSplitProvider fileSplitProvider, IBTreeInteriorFrameFactory interiorFactory,
             IBTreeLeafFrameFactory leafFactory, ITypeTrait[] typeTraits,
             IBinaryComparatorFactory[] comparatorFactories, boolean isForward, int[] lowKeyFields, int[] highKeyFields,
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorNodePushable.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorNodePushable.java
index 49e3599..a9729ed 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorNodePushable.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeSearchOperatorNodePushable.java
@@ -34,197 +34,177 @@
 import edu.uci.ics.hyracks.storage.am.btree.impls.BTreeOpContext;
 import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
 import edu.uci.ics.hyracks.storage.am.btree.impls.RangeSearchCursor;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexHelperOpenMode;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.TreeIndexOp;
 
-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, IndexHelperOpenMode.OPEN);
+        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 = (AbstractBTreeOperatorDescriptor) btreeOpHelper
+                .getOperatorDescriptor();
+        accessor = new FrameTupleAccessor(btreeOpHelper.getHyracksStageletContext().getFrameSize(), recDesc);
 
-		cursorFrame = opDesc.getLeafFactory().getFrame();
-		cursor = new RangeSearchCursor(cursorFrame);
+        cursorFrame = opDesc.getBTreeLeafFactory().getFrame();
+        cursor = new RangeSearchCursor(cursorFrame);
 
-		try {
+        try {
 
-			btreeOpHelper.init();
-			btree = btreeOpHelper.getBTree();
+            btreeOpHelper.init();
+            btree = btreeOpHelper.getBTree();
 
-			// construct range predicate
+            // construct range predicate
 
-			int lowKeySearchFields = btree.getMultiComparator()
-					.getComparators().length;
-			int highKeySearchFields = btree.getMultiComparator()
-					.getComparators().length;
-			if (lowKey != null)
-				lowKeySearchFields = lowKey.getFieldCount();
-			if (highKey != null)
-				highKeySearchFields = highKey.getFieldCount();
+            int lowKeySearchFields = btree.getMultiComparator().getComparators().length;
+            int highKeySearchFields = btree.getMultiComparator().getComparators().length;
+            if (lowKey != null)
+                lowKeySearchFields = lowKey.getFieldCount();
+            if (highKey != null)
+                highKeySearchFields = highKey.getFieldCount();
 
-			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);
+            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);
+            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);
+            rangePred = new RangePredicate(isForward, null, null, lowKeyInclusive, highKeyInclusive, lowKeySearchCmp,
+                    highKeySearchCmp);
 
-			accessor = new FrameTupleAccessor(btreeOpHelper
-					.getHyracksStageletContext().getFrameSize(), recDesc);
+            accessor = new FrameTupleAccessor(btreeOpHelper.getHyracksStageletContext().getFrameSize(), recDesc);
 
-			writeBuffer = btreeOpHelper.getHyracksStageletContext()
-					.allocateFrame();
-			tb = new ArrayTupleBuilder(btree.getMultiComparator()
-					.getFieldCount());
-			dos = tb.getDataOutput();
-			appender = new FrameTupleAppender(btreeOpHelper
-					.getHyracksStageletContext().getFrameSize());
-			appender.reset(writeBuffer, true);
+            writeBuffer = btreeOpHelper.getHyracksStageletContext().allocateFrame();
+            tb = new ArrayTupleBuilder(btree.getMultiComparator().getFieldCount());
+            dos = tb.getDataOutput();
+            appender = new FrameTupleAppender(btreeOpHelper.getHyracksStageletContext().getFrameSize());
+            appender.reset(writeBuffer, true);
 
-			opCtx = btree.createOpContext(TreeIndexOp.TI_SEARCH, btreeOpHelper
-					.getLeafFrame(), btreeOpHelper.getInteriorFrame(), null);
+            opCtx = btree.createOpContext(TreeIndexOp.TI_SEARCH, btreeOpHelper.getLeafFrame(), btreeOpHelper
+                    .getInteriorFrame(), null);
 
-		} catch (Exception e) {
-			btreeOpHelper.deinit();
-		}
-	}
+        } catch (Exception e) {
+            btreeOpHelper.deinit();
+        }
+    }
 
-	private void writeSearchResults() throws Exception {
-		while (cursor.hasNext()) {
-			tb.reset();
-			cursor.next();
+    private void writeSearchResults() throws Exception {
+        while (cursor.hasNext()) {
+            tb.reset();
+            cursor.next();
 
-			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();
-			}
+            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();
+            }
 
-			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();
-				}
-			}
-		}
-	}
+            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();
+                }
+            }
+        }
+    }
 
-	@Override
-	public void nextFrame(ByteBuffer buffer) throws HyracksDataException {
-		accessor.reset(buffer);
+    @Override
+    public void nextFrame(ByteBuffer buffer) throws HyracksDataException {
+        accessor.reset(buffer);
 
-		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);
+        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);
-		}
-	}
+                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 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);
-		}
-	}
+    @Override
+    public void flush() throws HyracksDataException {
+        if (appender.getTupleCount() > 0) {
+            FrameUtils.flushFrame(writeBuffer, writer);
+        }
+    }
 }
\ No newline at end of file
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeStatsOperatorDescriptor.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeStatsOperatorDescriptor.java
index a0b0545..61bc973 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeStatsOperatorDescriptor.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeStatsOperatorDescriptor.java
@@ -10,6 +10,8 @@
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 
 public class BTreeStatsOperatorDescriptor extends AbstractBTreeOperatorDescriptor {
@@ -17,7 +19,7 @@
     private static final long serialVersionUID = 1L;
     
     public BTreeStatsOperatorDescriptor(JobSpecification spec, IStorageManagerInterface storageManager,
-            IBTreeRegistryProvider btreeRegistryProvider, IFileSplitProvider fileSplitProvider,
+            IIndexRegistryProvider<BTree> btreeRegistryProvider, IFileSplitProvider fileSplitProvider,
             IBTreeInteriorFrameFactory interiorFactory, IBTreeLeafFrameFactory leafFactory, ITypeTrait[] typeTraits,
             IBinaryComparatorFactory[] comparatorFactories) {
         super(spec, 0, 0, null, storageManager, btreeRegistryProvider, fileSplitProvider, interiorFactory, leafFactory,
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeStatsOperatorNodePushable.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeStatsOperatorNodePushable.java
index 111b2da..8fc77e83 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeStatsOperatorNodePushable.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeStatsOperatorNodePushable.java
@@ -20,6 +20,7 @@
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractOperatorNodePushable;
 import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexHelperOpenMode;
 import edu.uci.ics.hyracks.storage.am.common.utility.TreeIndexStats;
 import edu.uci.ics.hyracks.storage.am.common.utility.TreeIndexStatsGatherer;
 import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
@@ -34,7 +35,7 @@
 			AbstractBTreeOperatorDescriptor opDesc,
 			IHyracksStageletContext ctx, int partition) {
 		btreeOpHelper = new BTreeOpHelper(opDesc, ctx, partition,
-				BTreeOpHelper.BTreeMode.CREATE_BTREE);
+		        IndexHelperOpenMode.CREATE);
 		this.ctx = ctx;
 	}
 
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/IBTreeRegistryProvider.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IIndexRegistryProvider.java
similarity index 77%
rename from hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/IBTreeRegistryProvider.java
rename to hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IIndexRegistryProvider.java
index 7b66d0a..aadcaf9 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/IBTreeRegistryProvider.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IIndexRegistryProvider.java
@@ -13,12 +13,12 @@
  * limitations under the License.
  */
 
-package edu.uci.ics.hyracks.storage.am.btree.dataflow;
+package edu.uci.ics.hyracks.storage.am.common.dataflow;
 
 import java.io.Serializable;
 
 import edu.uci.ics.hyracks.api.context.IHyracksStageletContext;
 
-public interface IBTreeRegistryProvider extends Serializable {
-    public BTreeRegistry getBTreeRegistry(IHyracksStageletContext ctx);
+public interface IIndexRegistryProvider<IndexType> extends Serializable {
+    public IndexRegistry<IndexType> getRegistry(IHyracksStageletContext ctx);
 }
\ No newline at end of file
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeRegistry.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IndexRegistry.java
similarity index 74%
rename from hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeRegistry.java
rename to hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IndexRegistry.java
index 9b90e22..e62b41d 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeRegistry.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IndexRegistry.java
@@ -13,24 +13,21 @@
  * limitations under the License.
  */
 
-package edu.uci.ics.hyracks.storage.am.btree.dataflow;
+package edu.uci.ics.hyracks.storage.am.common.dataflow;
 
 import java.util.HashMap;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
-import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+public class IndexRegistry<IndexType> {
 
-public class BTreeRegistry {
-
-    private HashMap<Integer, BTree> map = new HashMap<Integer, BTree>();
+    private HashMap<Integer, IndexType> map = new HashMap<Integer, IndexType>();
     private Lock registryLock = new ReentrantLock();
 
-    public BTree get(int fileId) {
+    public IndexType get(int fileId) {
         return map.get(fileId);
     }
-
-    // TODO: not very high concurrency, but good enough for now
+    
     public void lock() {
         registryLock.lock();
     }
@@ -39,8 +36,8 @@
         registryLock.unlock();
     }
 
-    public void register(int fileId, BTree btree) {
-        map.put(fileId, btree);
+    public void register(int fileId, IndexType index) {
+        map.put(fileId, index);
     }
 
     public void unregister(int fileId) {
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/InvertedIndex.java b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/InvertedIndex.java
index 9309772..21a5e4c 100644
--- a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/InvertedIndex.java
+++ b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/InvertedIndex.java
@@ -49,8 +49,8 @@
     	this.fileId = -1;
     }
     
-    public BulkLoadContext beginBulkLoad(IInvertedListBuilder invListBuilder, int hyracksFrameSize) throws HyracksDataException {
-        BulkLoadContext ctx = new BulkLoadContext(invListBuilder, hyracksFrameSize);
+    public BulkLoadContext beginBulkLoad(IInvertedListBuilder invListBuilder, int hyracksFrameSize, float btreeFillFactor) throws HyracksDataException {
+        BulkLoadContext ctx = new BulkLoadContext(invListBuilder, hyracksFrameSize, btreeFillFactor);
         ctx.init(rootPageId, fileId);
         return ctx;
     }
@@ -207,6 +207,7 @@
         private final FrameTupleAppender btreeTupleAppender;
         private final FrameTupleAccessor btreeFrameTupleAccessor;
         private final FrameTupleReference btreeFrameTupleReference = new FrameTupleReference();
+        private final float btreeFillFactor;
         private BTree.BulkLoadContext btreeBulkLoadCtx;
 
         private int currentInvListStartPageId;
@@ -219,7 +220,7 @@
         private final IInvertedListBuilder invListBuilder;
         private final MultiComparator tokenCmp;        
         
-        public BulkLoadContext(IInvertedListBuilder invListBuilder, int hyracksFrameSize) {
+        public BulkLoadContext(IInvertedListBuilder invListBuilder, int hyracksFrameSize, float btreeFillFactor) {
             this.invListBuilder = invListBuilder;
             this.tokenCmp = btree.getMultiComparator();
             this.btreeTupleBuffer = ByteBuffer.allocate(hyracksFrameSize);
@@ -232,6 +233,7 @@
                     IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE,
                     IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE });
             this.btreeFrameTupleAccessor = new FrameTupleAccessor(hyracksFrameSize, recDesc);
+            this.btreeFillFactor = btreeFillFactor;
         }
 
         public void init(int startPageId, int fileId) throws HyracksDataException {
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/test/support/TestBTreeRegistryProvider.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/test/support/TestBTreeRegistryProvider.java
index 3ab0427..e1c0feb 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/test/support/TestBTreeRegistryProvider.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/test/support/TestBTreeRegistryProvider.java
@@ -15,14 +15,15 @@
 package edu.uci.ics.hyracks.test.support;
 
 import edu.uci.ics.hyracks.api.context.IHyracksStageletContext;
-import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeRegistry;
-import edu.uci.ics.hyracks.storage.am.btree.dataflow.IBTreeRegistryProvider;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexRegistry;
 
-public class TestBTreeRegistryProvider implements IBTreeRegistryProvider {
+public class TestBTreeRegistryProvider implements IIndexRegistryProvider<BTree> {
     private static final long serialVersionUID = 1L;
-
-    @Override
-    public BTreeRegistry getBTreeRegistry(IHyracksStageletContext ctx) {
-        return TestStorageManagerComponentHolder.getBTreeRegistry(ctx);
-    }
+    
+	@Override
+	public IndexRegistry<BTree> getRegistry(IHyracksStageletContext ctx) {
+		return TestStorageManagerComponentHolder.getBTreeRegistry(ctx);
+	}
 }
\ No newline at end of file
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/test/support/TestStorageManagerComponentHolder.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/test/support/TestStorageManagerComponentHolder.java
index 3dfeac4..b9e7ec4 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/test/support/TestStorageManagerComponentHolder.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/test/support/TestStorageManagerComponentHolder.java
@@ -15,7 +15,8 @@
 package edu.uci.ics.hyracks.test.support;
 
 import edu.uci.ics.hyracks.api.context.IHyracksStageletContext;
-import edu.uci.ics.hyracks.storage.am.btree.dataflow.BTreeRegistry;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexRegistry;
 import edu.uci.ics.hyracks.storage.common.buffercache.BufferCache;
 import edu.uci.ics.hyracks.storage.common.buffercache.ClockPageReplacementStrategy;
 import edu.uci.ics.hyracks.storage.common.buffercache.HeapBufferAllocator;
@@ -29,7 +30,7 @@
 public class TestStorageManagerComponentHolder {
     private static IBufferCache bufferCache;
     private static IFileMapProvider fileMapProvider;
-    private static BTreeRegistry btreeRegistry;
+    private static IndexRegistry<BTree> btreeRegistry;
 
     private static int pageSize;
     private static int numPages;
@@ -62,9 +63,9 @@
         return fileMapProvider;
     }
 
-    public synchronized static BTreeRegistry getBTreeRegistry(IHyracksStageletContext ctx) {
+    public synchronized static IndexRegistry<BTree> getBTreeRegistry(IHyracksStageletContext ctx) {
         if (btreeRegistry == null) {
-            btreeRegistry = new BTreeRegistry();
+            btreeRegistry = new IndexRegistry<BTree>();
         }
         return btreeRegistry;
     }
diff --git a/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/BulkLoadTest.java b/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/BulkLoadTest.java
index d4a9c4f..5eeb403 100644
--- a/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/BulkLoadTest.java
+++ b/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/BulkLoadTest.java
@@ -166,10 +166,10 @@
         
         int maxId = 1000000;
         int addProb = 0;
-        int addProbStep = 10;        
+        int addProbStep = 10;   
 
         IInvertedListBuilder invListBuilder = new FixedSizeElementInvertedListBuilder(invListTypeTraits);
-        InvertedIndex.BulkLoadContext ctx = invIndex.beginBulkLoad(invListBuilder, HYRACKS_FRAME_SIZE);
+        InvertedIndex.BulkLoadContext ctx = invIndex.beginBulkLoad(invListBuilder, HYRACKS_FRAME_SIZE, BTree.DEFAULT_FILL_FACTOR);
         
         int totalElements = 0;
         for (int i = 0; i < tokens.size(); i++) {
diff --git a/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/SearchTest.java b/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/SearchTest.java
index 761bd12..6d68ac2 100644
--- a/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/SearchTest.java
+++ b/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/SearchTest.java
@@ -232,7 +232,7 @@
         int addProbStep = 10;        
         
         IInvertedListBuilder invListBuilder = new FixedSizeElementInvertedListBuilder(invListTypeTraits);
-        InvertedIndex.BulkLoadContext ctx = invIndex.beginBulkLoad(invListBuilder, HYRACKS_FRAME_SIZE);
+        InvertedIndex.BulkLoadContext ctx = invIndex.beginBulkLoad(invListBuilder, HYRACKS_FRAME_SIZE, BTree.DEFAULT_FILL_FACTOR);
         
         int totalElements = 0;        
         for (int i = 0; i < tokens.size(); i++) {