- Merged interface changes from hyracks_inverted_index_updates
- Set ignore properties to keep out pesky files


git-svn-id: https://hyracks.googlecode.com/svn/branches/hyracks_lsm_tree@1225 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/invertedindex/BinaryTokenizerOperatorTest.java b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/invertedindex/BinaryTokenizerOperatorTest.java
index eed4185..06b52de 100644
--- a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/invertedindex/BinaryTokenizerOperatorTest.java
+++ b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/invertedindex/BinaryTokenizerOperatorTest.java
@@ -22,7 +22,6 @@
 import edu.uci.ics.hyracks.dataflow.std.file.FileSplit;
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
 import edu.uci.ics.hyracks.dataflow.std.file.PlainFileWriterOperatorDescriptor;
-import edu.uci.ics.hyracks.dataflow.std.misc.PrinterOperatorDescriptor;
 import edu.uci.ics.hyracks.storage.am.invertedindex.dataflow.BinaryTokenizerOperatorDescriptor;
 import edu.uci.ics.hyracks.storage.am.invertedindex.tokenizers.DelimitedUTF8StringBinaryTokenizerFactory;
 import edu.uci.ics.hyracks.storage.am.invertedindex.tokenizers.IBinaryTokenizerFactory;
diff --git a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/invertedindex/WordInvertedIndexTest.java b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/invertedindex/WordInvertedIndexTest.java
index c44d690..a3afcbd 100644
--- a/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/invertedindex/WordInvertedIndexTest.java
+++ b/hyracks-examples/hyracks-integration-tests/src/test/java/edu/uci/ics/hyracks/tests/am/invertedindex/WordInvertedIndexTest.java
@@ -240,7 +240,7 @@
         InvertedIndexBulkLoadOperatorDescriptor invIndexBulkLoadOp = new InvertedIndexBulkLoadOperatorDescriptor(spec,
                 fieldPermutation, storageManager, btreeFileSplitProvider, invListsFileSplitProvider,
                 indexRegistryProvider, tokenTypeTraits, tokenComparatorFactories, invListsTypeTraits,
-                invListsComparatorFactories, btreeDataflowHelperFactory);
+                invListsComparatorFactories, tokenizerFactory, btreeDataflowHelperFactory);
         PartitionConstraintHelper.addAbsoluteLocationConstraint(spec, invIndexBulkLoadOp, NC1_ID);
         return invIndexBulkLoadOp;
     }
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTree.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTree.java
index 8726030..8177d16 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTree.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTree.java
@@ -32,6 +32,7 @@
 import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMInteriorFrame;
 import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexBulkLoadContext;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
@@ -1023,10 +1024,10 @@
 		}
         
         @Override
-        public void search(ITreeIndexCursor cursor, ISearchPredicate searchPred) throws HyracksDataException,
+        public void search(IIndexCursor cursor, ISearchPredicate searchPred) throws HyracksDataException,
                 TreeIndexException {
             ctx.reset(IndexOp.SEARCH);
-            btree.search(cursor, searchPred, ctx);
+            btree.search((ITreeIndexCursor) cursor, searchPred, ctx);
         }
 
         @Override
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexAccessor.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexAccessor.java
new file mode 100644
index 0000000..e799599
--- /dev/null
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexAccessor.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.common.api;
+
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+
+/**
+ * Client handle for performing operations (insert/delete/update/search) on an
+ * IIndex. An IIndexAccessor is not thread safe, but different IIndexAccessors
+ * can concurrently operate on the same IIndex (i.e., the IIndex must allow
+ * concurrent operations).
+ */
+public interface IIndexAccessor {
+    /**
+     * Inserts the given tuple.
+     * 
+     * @param tuple
+     *            Tuple to be inserted.
+     * @throws HyracksDataException
+     *             If the BufferCache throws while un/pinning or un/latching.
+     * @throws IndexException
+     *             If an index-specific constraint is violated, e.g., the key
+     *             already exists.
+     */
+    public void insert(ITupleReference tuple) throws HyracksDataException, IndexException;
+
+    /**
+     * Updates the tuple in the index matching the given tuple with the new
+     * contents in the given tuple.
+     * 
+     * @param tuple
+     *            Tuple whose match in the index is to be update with the given
+     *            tuples contents.
+     * @throws HyracksDataException
+     *             If the BufferCache throws while un/pinning or un/latching.
+     * @throws IndexException
+     *             If there is no matching tuple in the index.
+     */
+    public void update(ITupleReference tuple) throws HyracksDataException, IndexException;
+
+    /**
+     * Deletes the tuple in the index matching the given tuple.
+     * 
+     * @param tuple
+     *            Tuple to be deleted.
+     * @throws HyracksDataException
+     *             If the BufferCache throws while un/pinning or un/latching.
+     * @throws IndexException
+     *             If there is no matching tuple in the index.
+     */
+    public void delete(ITupleReference tuple) throws HyracksDataException, IndexException;
+
+    /**
+     * Creates a cursor appropriate for passing into search().
+     * 
+     */
+    public IIndexCursor createSearchCursor();
+
+    /**
+     * Open the given cursor for an index search using the given predicate as
+     * search condition.
+     * 
+     * @param icursor
+     *            Cursor over the index entries satisfying searchPred.
+     * @param searchPred
+     *            Search condition.
+     * @throws HyracksDataException
+     *             If the BufferCache throws while un/pinning or un/latching.
+     * @throws IndexException
+     */
+    public void search(IIndexCursor cursor, ISearchPredicate searchPred) throws HyracksDataException, IndexException;
+}
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/api/IInvertedIndexResultCursor.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexCursor.java
similarity index 61%
copy from hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/api/IInvertedIndexResultCursor.java
copy to hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexCursor.java
index fb73a65..d29fd73 100644
--- a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/api/IInvertedIndexResultCursor.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexCursor.java
@@ -13,16 +13,22 @@
  * limitations under the License.
  */
 
-package edu.uci.ics.hyracks.storage.am.invertedindex.api;
+package edu.uci.ics.hyracks.storage.am.common.api;
 
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
 
-public interface IInvertedIndexResultCursor {
-    public boolean hasNext();
+public interface IIndexCursor {
+    public void open(ICursorInitialState initialState,
+            ISearchPredicate searchPred) throws HyracksDataException;      
 
-    public void next();
+    public boolean hasNext() throws HyracksDataException;
+
+    public void next() throws HyracksDataException;
+
+    public void close() throws HyracksDataException;
+
+    public void reset();
 
     public ITupleReference getTuple();
-
-    public void reset(IInvertedIndexSearcher invIndexSearcher);
 }
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndex.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndex.java
index 7b3af70..52626cf 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndex.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndex.java
@@ -16,10 +16,7 @@
 package edu.uci.ics.hyracks.storage.am.common.api;
 
 import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
-import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
-import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndex;
-import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
 
 /**
  * Interface describing the operations of tree-based index structures. Indexes
@@ -28,98 +25,38 @@
  * Users must perform operations on an ITreeIndex via an ITreeIndexAccessor.
  */
 public interface ITreeIndex extends IIndex {
+    /**
+     * @return The index's leaf frame factory.
+     */
+    public ITreeIndexFrameFactory getLeafFrameFactory();
 
-	/**
-	 * Creates an index accessor for performing operations on this index.
-	 * (insert/delete/update/search/diskorderscan). An ITreeIndexAccessor is not
-	 * thread safe, but different ITreeIndexAccessors can concurrently operate
-	 * on the same ITreeIndex
-	 * 
-	 * @returns ITreeIndexAccessor A tree index accessor for this tree.
-	 */
-	public ITreeIndexAccessor createAccessor();
+    /**
+     * @return The index's interior frame factory.
+     */
+    public ITreeIndexFrameFactory getInteriorFrameFactory();
 
-	/**
-	 * Prepares the index for bulk loading, returning a bulk load context. The
-	 * index must be empty for bulk loading to be possible.
-	 * 
-	 * @param fillFactor
-	 *            Desired fill factor in [0, 1.0].
-	 * @throws HyracksDataException
-	 *             If the BufferCache throws while un/pinning or un/latching.
-	 * @throws TreeIndexException
-	 *             If the tree is not empty.
-	 * @returns A new context for bulk loading, required for appending tuples.
-	 */
-	public IIndexBulkLoadContext beginBulkLoad(float fillFactor)
-			throws TreeIndexException, HyracksDataException;
+    /**
+     * @return The index's free page manager.
+     */
+    public IFreePageManager getFreePageManager();
 
-	/**
-	 * Append a tuple to the index in the context of a bulk load.
-	 * 
-	 * @param tuple
-	 *            Tuple to be inserted.
-	 * @param ictx
-	 *            Existing bulk load context.
-	 * @throws HyracksDataException
-	 *             If the BufferCache throws while un/pinning or un/latching.
-	 */
-	public void bulkLoadAddTuple(ITupleReference tuple,
-			IIndexBulkLoadContext ictx) throws HyracksDataException;
+    /**
+     * @return The number of fields tuples of this index have.
+     */
+    public int getFieldCount();
 
-	/**
-	 * Finalize the bulk loading operation in the given context.
-	 * 
-	 * @param ictx
-	 *            Existing bulk load context to be finalized.
-	 * @throws HyracksDataException
-	 *             If the BufferCache throws while un/pinning or un/latching.
-	 */
-	public void endBulkLoad(IIndexBulkLoadContext ictx)
-			throws HyracksDataException;
+    /**
+     * @return The current root page id of this index.
+     */
+    public int getRootPageId();
 
-	/**
-	 * @return The index's leaf frame factory.
-	 */
-	public ITreeIndexFrameFactory getLeafFrameFactory();
-
-	/**
-	 * @return The index's interior frame factory.
-	 */
-	public ITreeIndexFrameFactory getInteriorFrameFactory();
-
-	/**
-	 * @return The index's free page manager.
-	 */
-	public IFreePageManager getFreePageManager();
-
-	/**
-	 * @return The number of fields tuples of this index have.
-	 */
-	public int getFieldCount();
-
-	/**
-	 * @return The current root page id of this index.
-	 */
-	public int getRootPageId();
-
-	/**
-	 * @return An enum of the concrete type of this index.
-	 */
-	public IndexType getIndexType();
-	
-	/**
+    /**
      * @return The file id of this index.
      */
     public int getFileId();
-    
-    /**
-     * @return BufferCache underlying this tree index.
-     */
-    public IBufferCache getBufferCache();
-    
+
     /**
      * @return Comparator factories.
      */
-    public IBinaryComparatorFactory[] getComparatorFactories(); 
+    public IBinaryComparatorFactory[] getComparatorFactories();
 }
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexAccessor.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexAccessor.java
index e0271f3..da8fc3b 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexAccessor.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexAccessor.java
@@ -16,7 +16,6 @@
 package edu.uci.ics.hyracks.storage.am.common.api;
 
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
-import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
 
 /**
  * Client handle for performing operations
@@ -25,70 +24,7 @@
  * concurrently operate on the same ITreeIndex (i.e., the ITreeIndex must allow
  * concurrent operations).
  */
-public interface ITreeIndexAccessor {
-	/**
-	 * Inserts the given tuple.
-	 * 
-	 * @param tuple
-	 *            Tuple to be inserted.
-	 * @throws HyracksDataException
-	 *             If the BufferCache throws while un/pinning or un/latching.
-	 * @throws TreeIndexException
-	 *             If an index-specific constraint is violated, e.g., the key
-	 *             already exists.
-	 */
-	public void insert(ITupleReference tuple) throws HyracksDataException,
-			TreeIndexException;
-
-	/**
-	 * Updates the tuple in the index matching the given tuple with the new
-	 * contents in the given tuple.
-	 * 
-	 * @param tuple
-	 *            Tuple whose match in the index is to be update with the given
-	 *            tuples contents.
-	 * @throws HyracksDataException
-	 *             If the BufferCache throws while un/pinning or un/latching.
-	 * @throws TreeIndexException
-	 *             If there is no matching tuple in the index.
-	 */
-	public void update(ITupleReference tuple) throws HyracksDataException,
-			TreeIndexException;
-
-	/**
-	 * Deletes the tuple in the index matching the given tuple.
-	 * 
-	 * @param tuple
-	 *            Tuple to be deleted.
-	 * @throws HyracksDataException
-	 *             If the BufferCache throws while un/pinning or un/latching.
-	 * @throws TreeIndexException
-	 *             If there is no matching tuple in the index.
-	 */
-	public void delete(ITupleReference tuple) throws HyracksDataException,
-			TreeIndexException;
-
-	/**
-	 * Creates a cursor appropriate for passing into search().
-	 * 
-	 */
-	public ITreeIndexCursor createSearchCursor();
-	
-	/**
-	 * Open the given cursor for an index search using the given predicate as
-	 * search condition.
-	 * 
-	 * @param icursor
-	 *            Cursor over the index entries satisfying searchPred.
-	 * @param searchPred
-	 *            Search condition.
-	 * @throws HyracksDataException
-	 *             If the BufferCache throws while un/pinning or un/latching.
-	 * @throws TreeIndexException
-	 */
-	public void search(ITreeIndexCursor cursor, ISearchPredicate searchPred)
-			throws HyracksDataException, TreeIndexException;
-
+public interface ITreeIndexAccessor extends IIndexAccessor {
 	/**
 	 * Creates a cursor appropriate for passing into diskOrderScan().
 	 * 
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexCursor.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexCursor.java
index 24e552d..229613c 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexCursor.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ITreeIndexCursor.java
@@ -15,31 +15,17 @@
 
 package edu.uci.ics.hyracks.storage.am.common.api;
 
-import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
-import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
 import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
 import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
 
-public interface ITreeIndexCursor {
-	public void reset();
-
-	public boolean hasNext() throws HyracksDataException;
-
-	public void next() throws HyracksDataException;
-
-	public void open(ICursorInitialState initialState,
-			ISearchPredicate searchPred) throws HyracksDataException;
+public interface ITreeIndexCursor extends IIndexCursor {
 
 	public ICachedPage getPage();
 
-	public void close() throws HyracksDataException;
-
 	public void setBufferCache(IBufferCache bufferCache);
 
 	public void setFileId(int fileId);
 
-	public ITupleReference getTuple();
-	
 	// For allowing updates.
 	public boolean exclusiveLatchNodes();
 }
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/api/IInvertedIndexResultCursor.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IndexException.java
similarity index 64%
rename from hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/api/IInvertedIndexResultCursor.java
rename to hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IndexException.java
index fb73a65..0aeaf82 100644
--- a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/api/IInvertedIndexResultCursor.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IndexException.java
@@ -13,16 +13,16 @@
  * limitations under the License.
  */
 
-package edu.uci.ics.hyracks.storage.am.invertedindex.api;
+package edu.uci.ics.hyracks.storage.am.common.api;
 
-import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+public class IndexException extends Exception {
+    private static final long serialVersionUID = 1L;
 
-public interface IInvertedIndexResultCursor {
-    public boolean hasNext();
+    public IndexException(Exception e) {        
+        super(e);
+    }
 
-    public void next();
-
-    public ITupleReference getTuple();
-
-    public void reset(IInvertedIndexSearcher invIndexSearcher);
+    public IndexException(String message) {
+        super(message);
+    }
 }
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/TreeIndexException.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/TreeIndexException.java
index 4cf596f..c3f3f1a 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/TreeIndexException.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/TreeIndexException.java
@@ -15,7 +15,7 @@
 
 package edu.uci.ics.hyracks.storage.am.common.api;
 
-public class TreeIndexException extends Exception {
+public class TreeIndexException extends IndexException {
 
 	private static final long serialVersionUID = 1L;
 	private boolean handled = false;
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IIndex.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IIndex.java
index 3543564..64cbd58 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IIndex.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IIndex.java
@@ -16,14 +16,22 @@
 package edu.uci.ics.hyracks.storage.am.common.dataflow;
 
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexBulkLoadContext;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexType;
+import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
 
 /**
- * Interface describing the operations common to all indexes.
+ * Interface describing the operations common to all index structures. Indexes
+ * implementing this interface can easily reuse existing index operators for
+ * dataflow. Users must perform operations on an IIndex via an IIndexAccessor.
  */
 public interface IIndex {
     /**
-     * Initializes the persistent state of an index, e.g., the root page,
-     * and metadata pages.
+     * Initializes the persistent state of an index, e.g., the root page, and
+     * metadata pages.
      * 
      * @param indexFileId
      *            The file id to use for this index.
@@ -39,9 +47,66 @@
      *            The file id backing this index.
      */
     public void open(int indexFileId) throws HyracksDataException;
-    
+
     /**
      * Closes the index.
      */
     public void close() throws HyracksDataException;
+
+    /**
+     * Creates an index accessor for performing operations on this index.
+     * (insert/delete/update/search/diskorderscan). An IIndexAccessor is not
+     * thread safe, but different IIndexAccessors can concurrently operate
+     * on the same IIndex
+     * 
+     * @returns IIndexAccessor An accessor for this tree.
+     */
+    public IIndexAccessor createAccessor();
+
+    /**
+     * Prepares the index for bulk loading, returning a bulk load context. The
+     * index may require to be empty for bulk loading.
+     * 
+     * @param fillFactor
+     *            Desired fill factor in [0, 1.0].
+     * @throws HyracksDataException
+     *             If the BufferCache throws while un/pinning or un/latching.
+     * @throws IndexException
+     *             For example, if the index was already loaded and only
+     *             supports a single load.
+     * @returns A new context for bulk loading, required for appending tuples.
+     */
+    public IIndexBulkLoadContext beginBulkLoad(float fillFactor) throws IndexException, HyracksDataException;
+
+    /**
+     * Append a tuple to the index in the context of a bulk load.
+     * 
+     * @param tuple
+     *            Tuple to be inserted.
+     * @param ictx
+     *            Existing bulk load context.
+     * @throws HyracksDataException
+     *             If the BufferCache throws while un/pinning or un/latching.
+     */
+    public void bulkLoadAddTuple(ITupleReference tuple, IIndexBulkLoadContext ictx) throws HyracksDataException;
+
+    /**
+     * Finalize the bulk loading operation in the given context.
+     * 
+     * @param ictx
+     *            Existing bulk load context to be finalized.
+     * @throws HyracksDataException
+     *             If the BufferCache throws while un/pinning or un/latching.
+     */
+    public void endBulkLoad(IIndexBulkLoadContext ictx) throws HyracksDataException;
+
+    /**
+     * @return BufferCache underlying this index.
+     */
+    public IBufferCache getBufferCache();
+
+    /**
+     * @return An enum of the concrete type of this index.
+     */
+    public IndexType getIndexType();
 }
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDiskOrderScanOperatorNodePushable.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDiskOrderScanOperatorNodePushable.java
index d7a680c..d207314 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDiskOrderScanOperatorNodePushable.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDiskOrderScanOperatorNodePushable.java
@@ -46,7 +46,7 @@
             treeIndex = (ITreeIndex) treeIndexHelper.getIndex();
             ITreeIndexFrame cursorFrame = treeIndex.getLeafFrameFactory().createFrame();
             ITreeIndexCursor cursor = treeIndexHelper.createDiskOrderScanCursor(cursorFrame);
-            ITreeIndexAccessor indexAccessor = treeIndex.createAccessor();
+            ITreeIndexAccessor indexAccessor = (ITreeIndexAccessor) treeIndex.createAccessor();
             writer.open();
             try {
                 indexAccessor.diskOrderScan(cursor);
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexInsertUpdateDeleteOperatorNodePushable.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexInsertUpdateDeleteOperatorNodePushable.java
index bf78249..ddef338 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexInsertUpdateDeleteOperatorNodePushable.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexInsertUpdateDeleteOperatorNodePushable.java
@@ -23,8 +23,8 @@
 import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAccessor;
 import edu.uci.ics.hyracks.dataflow.common.comm.util.FrameUtils;
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractUnaryInputUnaryOutputOperatorNodePushable;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
 
 public class TreeIndexInsertUpdateDeleteOperatorNodePushable extends AbstractUnaryInputUnaryOutputOperatorNodePushable {
@@ -34,7 +34,7 @@
     private final IndexOp op;
     private final PermutingFrameTupleReference tuple = new PermutingFrameTupleReference();
     private ByteBuffer writeBuffer;
-    private ITreeIndexAccessor indexAccessor;
+    private IIndexAccessor indexAccessor;
 
     public TreeIndexInsertUpdateDeleteOperatorNodePushable(AbstractTreeIndexOperatorDescriptor opDesc,
             IHyracksTaskContext ctx, int partition, int[] fieldPermutation,
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexSearchOperatorNodePushable.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexSearchOperatorNodePushable.java
index f51cdf3..399643e 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexSearchOperatorNodePushable.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexSearchOperatorNodePushable.java
@@ -27,10 +27,10 @@
 import edu.uci.ics.hyracks.dataflow.common.comm.util.FrameUtils;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractUnaryInputUnaryOutputOperatorNodePushable;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrame;
 
 public abstract class TreeIndexSearchOperatorNodePushable extends AbstractUnaryInputUnaryOutputOperatorNodePushable {
@@ -44,9 +44,9 @@
 
 	protected ITreeIndex treeIndex;
 	protected ISearchPredicate searchPred;
-	protected ITreeIndexCursor cursor;
+	protected IIndexCursor cursor;
 	protected ITreeIndexFrame cursorFrame;
-	protected ITreeIndexAccessor indexAccessor;
+	protected IIndexAccessor indexAccessor;
 
 	protected RecordDescriptor recDesc;
 
@@ -61,7 +61,7 @@
     
     protected abstract void resetSearchPredicate(int tupleIndex);
     
-    protected ITreeIndexCursor createCursor() {
+    protected IIndexCursor createCursor() {
         return indexAccessor.createSearchCursor();
     }
     
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/api/IInvertedIndexOperatorDescriptor.java b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/api/IInvertedIndexOperatorDescriptor.java
index 1dc753e..042042f 100644
--- a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/api/IInvertedIndexOperatorDescriptor.java
+++ b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/api/IInvertedIndexOperatorDescriptor.java
@@ -19,10 +19,13 @@
 import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
 import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.ITreeIndexOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.invertedindex.tokenizers.IBinaryTokenizerFactory;
 
 public interface IInvertedIndexOperatorDescriptor extends ITreeIndexOperatorDescriptor {
     public IBinaryComparatorFactory[] getInvListsComparatorFactories();
 
+    public IBinaryTokenizerFactory getTokenizerFactory();
+    
     public ITypeTraits[] getInvListsTypeTraits();
     
     public IFileSplitProvider getInvListsFileSplitProvider();
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/api/IInvertedIndexSearcher.java b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/api/IInvertedIndexSearcher.java
index 36d64ea..d633c34 100644
--- a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/api/IInvertedIndexSearcher.java
+++ b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/api/IInvertedIndexSearcher.java
@@ -19,11 +19,15 @@
 import java.util.List;
 
 import edu.uci.ics.hyracks.api.comm.IFrameTupleAccessor;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
+import edu.uci.ics.hyracks.storage.am.invertedindex.impls.InvertedIndexSearchCursor;
+import edu.uci.ics.hyracks.storage.am.invertedindex.impls.InvertedIndexSearchPredicate;
 
 public interface IInvertedIndexSearcher {
-    public void search(IInvertedIndexResultCursor resultCursor, ITupleReference queryTuple, int queryFieldIndex,
-            IInvertedIndexSearchModifier searchModifier) throws Exception;
+    public void search(InvertedIndexSearchCursor resultCursor, InvertedIndexSearchPredicate searchPred)
+            throws HyracksDataException, IndexException;
 
     public IFrameTupleAccessor createResultFrameTupleAccessor();
 
@@ -32,4 +36,6 @@
     public List<ByteBuffer> getResultBuffers();
 
     public int getNumValidResultBuffers();
+    
+    public void reset();
 }
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/AbstractInvertedIndexOperatorDescriptor.java b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/AbstractInvertedIndexOperatorDescriptor.java
index 733c1a5..aed46c9 100644
--- a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/AbstractInvertedIndexOperatorDescriptor.java
+++ b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/AbstractInvertedIndexOperatorDescriptor.java
@@ -30,6 +30,7 @@
 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.am.invertedindex.api.IInvertedIndexOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.invertedindex.tokenizers.IBinaryTokenizerFactory;
 import edu.uci.ics.hyracks.storage.am.invertedindex.util.InvertedIndexUtils;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 
@@ -53,6 +54,7 @@
     // Inverted index.
     protected final ITypeTraits[] invListsTypeTraits;
     protected final IBinaryComparatorFactory[] invListComparatorFactories;
+    protected final IBinaryTokenizerFactory tokenizerFactory;
     protected final IFileSplitProvider invListsFileSplitProvider;
 
     public AbstractInvertedIndexOperatorDescriptor(JobSpecification spec, int inputArity, int outputArity,
@@ -60,7 +62,7 @@
             IFileSplitProvider btreeFileSplitProvider, IFileSplitProvider invListsFileSplitProvider,
             IIndexRegistryProvider<IIndex> indexRegistryProvider, ITypeTraits[] tokenTypeTraits,
             IBinaryComparatorFactory[] tokenComparatorFactories, ITypeTraits[] invListsTypeTraits,
-            IBinaryComparatorFactory[] invListComparatorFactories,
+            IBinaryComparatorFactory[] invListComparatorFactories, IBinaryTokenizerFactory tokenizerFactory,
             IIndexDataflowHelperFactory btreeDataflowHelperFactory) {
         super(spec, inputArity, outputArity);
 
@@ -80,6 +82,7 @@
         // Inverted index.
         this.invListsTypeTraits = invListsTypeTraits;
         this.invListComparatorFactories = invListComparatorFactories;
+        this.tokenizerFactory = tokenizerFactory;
         this.invListsFileSplitProvider = invListsFileSplitProvider;
 
         if (outputArity > 0) {
@@ -123,6 +126,11 @@
     }
 
     @Override
+    public IBinaryTokenizerFactory getTokenizerFactory() {
+        return tokenizerFactory;
+    }
+    
+    @Override
     public ITypeTraits[] getInvListsTypeTraits() {
         return invListsTypeTraits;
     }
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexBulkLoadOperatorDescriptor.java b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexBulkLoadOperatorDescriptor.java
index e91aa08..d271a38 100644
--- a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexBulkLoadOperatorDescriptor.java
+++ b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexBulkLoadOperatorDescriptor.java
@@ -25,6 +25,7 @@
 import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndex;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexDataflowHelperFactory;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
+import edu.uci.ics.hyracks.storage.am.invertedindex.tokenizers.IBinaryTokenizerFactory;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 
 public class InvertedIndexBulkLoadOperatorDescriptor extends AbstractInvertedIndexOperatorDescriptor {
@@ -38,10 +39,10 @@
             IFileSplitProvider invListsFileSplitProvider, IIndexRegistryProvider<IIndex> indexRegistryProvider,
             ITypeTraits[] tokenTypeTraits, IBinaryComparatorFactory[] tokenComparatorFactories,
             ITypeTraits[] invListsTypeTraits, IBinaryComparatorFactory[] invListComparatorFactories,
-            IIndexDataflowHelperFactory btreeDataflowHelperFactory) {
+            IBinaryTokenizerFactory tokenizerFactory, IIndexDataflowHelperFactory btreeDataflowHelperFactory) {
         super(spec, 1, 0, null, storageManager, btreeFileSplitProvider, invListsFileSplitProvider,
                 indexRegistryProvider, tokenTypeTraits, tokenComparatorFactories, invListsTypeTraits,
-                invListComparatorFactories, btreeDataflowHelperFactory);
+                invListComparatorFactories, tokenizerFactory, btreeDataflowHelperFactory);
         this.fieldPermutation = fieldPermutation;
     }
 
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexBulkLoadOperatorNodePushable.java b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexBulkLoadOperatorNodePushable.java
index f6cd4cd..5106d52 100644
--- a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexBulkLoadOperatorNodePushable.java
+++ b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexBulkLoadOperatorNodePushable.java
@@ -25,18 +25,14 @@
 import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.PermutingFrameTupleReference;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexDataflowHelper;
-import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedListBuilder;
-import edu.uci.ics.hyracks.storage.am.invertedindex.impls.FixedSizeElementInvertedListBuilder;
 import edu.uci.ics.hyracks.storage.am.invertedindex.impls.InvertedIndex;
+import edu.uci.ics.hyracks.storage.am.invertedindex.impls.InvertedIndex.InvertedIndexBulkLoadContext;
 
 public class InvertedIndexBulkLoadOperatorNodePushable extends AbstractUnaryInputSinkOperatorNodePushable {
     private final TreeIndexDataflowHelper btreeDataflowHelper;
     private final InvertedIndexDataflowHelper invIndexDataflowHelper;
-    private final IInvertedListBuilder invListBuilder;
     private InvertedIndex invIndex;
-    private InvertedIndex.BulkLoadContext bulkLoadCtx;
-
-    private final IHyracksTaskContext ctx;
+    private InvertedIndex.InvertedIndexBulkLoadContext bulkLoadCtx;
 
     private FrameTupleAccessor accessor;
     private PermutingFrameTupleReference tuple = new PermutingFrameTupleReference();
@@ -49,8 +45,6 @@
                 .createIndexDataflowHelper(opDesc, ctx, partition, true);
         invIndexDataflowHelper = new InvertedIndexDataflowHelper(btreeDataflowHelper, opDesc, ctx, partition, true);
         this.recordDescProvider = recordDescProvider;
-        this.ctx = ctx;
-        this.invListBuilder = new FixedSizeElementInvertedListBuilder(opDesc.getInvListsTypeTraits());
         tuple.setFieldPermutation(fieldPermutation);
     }
 
@@ -78,7 +72,7 @@
         try {
             invIndexDataflowHelper.init();
             invIndex = (InvertedIndex) invIndexDataflowHelper.getIndex();
-            bulkLoadCtx = invIndex.beginBulkLoad(invListBuilder, ctx.getFrameSize(), BTree.DEFAULT_FILL_FACTOR);
+            bulkLoadCtx = (InvertedIndexBulkLoadContext) invIndex.beginBulkLoad(BTree.DEFAULT_FILL_FACTOR);
         } catch (Exception e) {
             // Cleanup in case of failure.
             invIndexDataflowHelper.deinit();
@@ -96,7 +90,7 @@
         int tupleCount = accessor.getTupleCount();
         for (int i = 0; i < tupleCount; i++) {
             tuple.reset(accessor, i);
-            invIndex.bulkLoadAddTuple(bulkLoadCtx, tuple);
+            invIndex.bulkLoadAddTuple(tuple, bulkLoadCtx);
         }
     }
 
@@ -117,5 +111,6 @@
 
     @Override
     public void fail() throws HyracksDataException {
+        writer.fail();
     }
 }
\ No newline at end of file
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexDataflowHelper.java b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexDataflowHelper.java
index a7dc7d5..1bba574 100644
--- a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexDataflowHelper.java
+++ b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexDataflowHelper.java
@@ -24,6 +24,8 @@
 import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexDataflowHelper;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexDataflowHelper;
 import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedIndexOperatorDescriptor;
+import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedListBuilder;
+import edu.uci.ics.hyracks.storage.am.invertedindex.impls.FixedSizeElementInvertedListBuilder;
 import edu.uci.ics.hyracks.storage.am.invertedindex.impls.InvertedIndex;
 
 public final class InvertedIndexDataflowHelper extends IndexDataflowHelper {
@@ -46,7 +48,10 @@
         IInvertedIndexOperatorDescriptor invIndexOpDesc = (IInvertedIndexOperatorDescriptor) opDesc;
         // Assumes btreeDataflowHelper.init() has already been called.
         BTree btree = (BTree) btreeDataflowHelper.getIndex();
+        IInvertedListBuilder invListBuilder = new FixedSizeElementInvertedListBuilder(
+                invIndexOpDesc.getInvListsTypeTraits());
         return new InvertedIndex(opDesc.getStorageManager().getBufferCache(ctx), btree,
-                invIndexOpDesc.getInvListsTypeTraits(), invIndexOpDesc.getInvListsComparatorFactories());
+                invIndexOpDesc.getInvListsTypeTraits(), invIndexOpDesc.getInvListsComparatorFactories(),
+                invListBuilder, invIndexOpDesc.getTokenizerFactory().createTokenizer());
     }
 }
\ No newline at end of file
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexSearchOperatorDescriptor.java b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexSearchOperatorDescriptor.java
index bf9899f..b1c45fa 100644
--- a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexSearchOperatorDescriptor.java
+++ b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexSearchOperatorDescriptor.java
@@ -29,7 +29,6 @@
 import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
 import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedIndexSearchModifier;
 import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedIndexSearchModifierFactory;
-import edu.uci.ics.hyracks.storage.am.invertedindex.tokenizers.IBinaryTokenizer;
 import edu.uci.ics.hyracks.storage.am.invertedindex.tokenizers.IBinaryTokenizerFactory;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 
@@ -37,7 +36,6 @@
     private static final long serialVersionUID = 1L;
 
     private final int queryField;
-    private final IBinaryTokenizerFactory queryTokenizerFactory;
     private final IInvertedIndexSearchModifierFactory searchModifierFactory;
 
     public InvertedIndexSearchOperatorDescriptor(JobSpecification spec,
@@ -49,18 +47,16 @@
             IInvertedIndexSearchModifierFactory searchModifierFactory, RecordDescriptor recDesc) {
         super(spec, 1, 1, recDesc, storageManager, btreeFileSplitProvider, invListsFileSplitProvider,
                 indexRegistryProvider, tokenTypeTraits, tokenComparatorFactories, invListsTypeTraits,
-                invListComparatorFactories, btreeDataflowHelperFactory);
+                invListComparatorFactories, queryTokenizerFactory, btreeDataflowHelperFactory);
         this.queryField = queryField;
-        this.queryTokenizerFactory = queryTokenizerFactory;
         this.searchModifierFactory = searchModifierFactory;
     }
 
     @Override
     public IOperatorNodePushable createPushRuntime(IHyracksTaskContext ctx,
             IRecordDescriptorProvider recordDescProvider, int partition, int nPartitions) throws HyracksDataException {
-        IBinaryTokenizer tokenizer = queryTokenizerFactory.createTokenizer();
         IInvertedIndexSearchModifier searchModifier = searchModifierFactory.createSearchModifier();
-        return new InvertedIndexSearchOperatorNodePushable(this, ctx, partition, queryField, searchModifier, tokenizer,
+        return new InvertedIndexSearchOperatorNodePushable(this, ctx, partition, queryField, searchModifier,
                 recordDescProvider);
     }
 }
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexSearchOperatorNodePushable.java b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexSearchOperatorNodePushable.java
index ceaff1e..534bb65 100644
--- a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexSearchOperatorNodePushable.java
+++ b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/dataflow/InvertedIndexSearchOperatorNodePushable.java
@@ -29,30 +29,27 @@
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.FrameTupleReference;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractUnaryInputUnaryOutputOperatorNodePushable;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.TreeIndexDataflowHelper;
-import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedIndexResultCursor;
 import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedIndexSearchModifier;
 import edu.uci.ics.hyracks.storage.am.invertedindex.impls.InvertedIndex;
+import edu.uci.ics.hyracks.storage.am.invertedindex.impls.InvertedIndexSearchPredicate;
 import edu.uci.ics.hyracks.storage.am.invertedindex.impls.OccurrenceThresholdPanicException;
-import edu.uci.ics.hyracks.storage.am.invertedindex.impls.SearchResultCursor;
-import edu.uci.ics.hyracks.storage.am.invertedindex.impls.TOccurrenceSearcher;
-import edu.uci.ics.hyracks.storage.am.invertedindex.tokenizers.IBinaryTokenizer;
 
 public class InvertedIndexSearchOperatorNodePushable extends AbstractUnaryInputUnaryOutputOperatorNodePushable {
     private final TreeIndexDataflowHelper btreeDataflowHelper;
     private final InvertedIndexDataflowHelper invIndexDataflowHelper;
-    private final IHyracksTaskContext ctx;
     private final int queryField;
     private FrameTupleAccessor accessor;
     private FrameTupleReference tuple;
     private IRecordDescriptorProvider recordDescProvider;
     private InvertedIndex invIndex;
-
-    private final IInvertedIndexSearchModifier searchModifier;
-    private final IBinaryTokenizer queryTokenizer;
-    private TOccurrenceSearcher searcher;
-    private IInvertedIndexResultCursor resultCursor;
-
+    
+    private final InvertedIndexSearchPredicate searchPred;
+    private IIndexAccessor indexAccessor;
+    private IIndexCursor resultCursor;        
+    
     private ByteBuffer writeBuffer;
     private FrameTupleAppender appender;
     private ArrayTupleBuilder tb;
@@ -62,15 +59,13 @@
 
     public InvertedIndexSearchOperatorNodePushable(AbstractInvertedIndexOperatorDescriptor opDesc,
             IHyracksTaskContext ctx, int partition, int queryField, IInvertedIndexSearchModifier searchModifier,
-            IBinaryTokenizer queryTokenizer, IRecordDescriptorProvider recordDescProvider) {
+            IRecordDescriptorProvider recordDescProvider) {
         this.opDesc = opDesc;
         btreeDataflowHelper = (TreeIndexDataflowHelper) opDesc.getIndexDataflowHelperFactory()
                 .createIndexDataflowHelper(opDesc, ctx, partition, false);
         invIndexDataflowHelper = new InvertedIndexDataflowHelper(btreeDataflowHelper, opDesc, ctx, partition, false);
-        this.ctx = ctx;
         this.queryField = queryField;
-        this.searchModifier = searchModifier;
-        this.queryTokenizer = queryTokenizer;
+        this.searchPred = new InvertedIndexSearchPredicate(searchModifier);
         this.recordDescProvider = recordDescProvider;
     }
 
@@ -111,10 +106,8 @@
         appender = new FrameTupleAppender(btreeDataflowHelper.getHyracksTaskContext().getFrameSize());
         appender.reset(writeBuffer, true);
 
-        searcher = new TOccurrenceSearcher(ctx, invIndex, queryTokenizer);
-        resultCursor = new SearchResultCursor(searcher.createResultFrameTupleAccessor(),
-                searcher.createResultTupleReference());
-
+        indexAccessor = invIndex.createAccessor();
+        resultCursor = indexAccessor.createSearchCursor();
         writer.open();
     }
 
@@ -146,10 +139,11 @@
         try {
             for (int i = 0; i < tupleCount; i++) {
                 tuple.reset(accessor, i);
-                searcher.reset();
+                searchPred.setQueryTuple(tuple);
+                searchPred.setQueryFieldIndex(queryField);
                 try {
-                    searcher.reset();
-                    searcher.search(resultCursor, tuple, queryField, searchModifier);
+                    resultCursor.reset();
+                    indexAccessor.search(resultCursor, searchPred);
                     writeSearchResults();
                 } catch (OccurrenceThresholdPanicException e) {
                     // Ignore panic cases for now.
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 6d9fb0e..b79a795 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
@@ -17,56 +17,68 @@
 
 import java.nio.ByteBuffer;
 
+import edu.uci.ics.hyracks.api.context.IHyracksCommonContext;
 import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
-import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
 import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
-import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.api.io.IIOManager;
 import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleReference;
 import edu.uci.ics.hyracks.dataflow.common.comm.io.ByteArrayAccessibleOutputStream;
-import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAccessor;
-import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAppender;
-import edu.uci.ics.hyracks.dataflow.common.data.accessors.FrameTupleReference;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
 import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
 import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexBulkLoadContext;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
+import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexType;
 import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndex;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
+import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedIndexSearcher;
 import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedListBuilder;
 import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedListCursor;
+import edu.uci.ics.hyracks.storage.am.invertedindex.tokenizers.IBinaryTokenizer;
 import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
 import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
 import edu.uci.ics.hyracks.storage.common.file.BufferedFileHandle;
 
 /**
  * An inverted index consists of two files: 1. a file storing (paginated)
- * inverted lists 2. a BTree-file mapping from tokens to inverted lists
+ * inverted lists 2. a BTree-file mapping from tokens to inverted lists.
  * 
  * Implemented features: bulk loading and searching (based on T-Occurrence) Not
  * implemented features: updates (insert/update/delete) Limitations: a query
- * cannot exceed the size of a Hyracks frame
+ * cannot exceed the size of a Hyracks frame.
  */
 public class InvertedIndex implements IIndex {
-
+    private final IHyracksCommonContext ctx = new DefaultHyracksCommonContext();
+    
     private BTree btree;
     private int rootPageId = 0;
     private IBufferCache bufferCache;
     private int fileId;
     private final ITypeTraits[] invListTypeTraits;
     private final IBinaryComparatorFactory[] invListCmpFactories;
+    private final IInvertedListBuilder invListBuilder;
+    private final IBinaryTokenizer tokenizer;
     private final int numTokenFields;
     private final int numInvListKeys;
 
-    public InvertedIndex(IBufferCache bufferCache, BTree btree, ITypeTraits[] invListTypeTraits, IBinaryComparatorFactory[] invListCmpFactories) {
+    public InvertedIndex(IBufferCache bufferCache, BTree btree, ITypeTraits[] invListTypeTraits,
+            IBinaryComparatorFactory[] invListCmpFactories, IInvertedListBuilder invListBuilder,
+            IBinaryTokenizer tokenizer) {
         this.bufferCache = bufferCache;
         this.btree = btree;
-        this.invListCmpFactories = invListCmpFactories;
         this.invListTypeTraits = invListTypeTraits;
+        this.invListCmpFactories = invListCmpFactories;
+        this.invListBuilder = invListBuilder;
+        this.tokenizer = tokenizer;
         this.numTokenFields = btree.getComparatorFactories().length;
         this.numInvListKeys = invListCmpFactories.length;
     }
@@ -80,144 +92,190 @@
     public void create(int indexFileId) throws HyracksDataException {
     }
     
+    @Override
     public void close() {
         this.fileId = -1;
     }
 
-    public BulkLoadContext beginBulkLoad(IInvertedListBuilder invListBuilder, int hyracksFrameSize,
-            float btreeFillFactor) throws HyracksDataException, TreeIndexException {
-        BulkLoadContext ctx = new BulkLoadContext(invListBuilder, hyracksFrameSize, btreeFillFactor);
+        
+    public boolean openCursor(ITreeIndexCursor btreeCursor, RangePredicate btreePred, ITreeIndexAccessor btreeAccessor,
+            IInvertedListCursor invListCursor) throws HyracksDataException, IndexException {
+        btreeAccessor.search(btreeCursor, btreePred);
+        boolean ret = false;
+        try {
+            if (btreeCursor.hasNext()) {
+                btreeCursor.next();
+                ITupleReference frameTuple = btreeCursor.getTuple();
+                // Hardcoded mapping of btree fields
+                int startPageId = IntegerSerializerDeserializer.getInt(frameTuple.getFieldData(1),
+                        frameTuple.getFieldStart(1));
+                int endPageId = IntegerSerializerDeserializer.getInt(frameTuple.getFieldData(2),
+                        frameTuple.getFieldStart(2));
+                int startOff = IntegerSerializerDeserializer.getInt(frameTuple.getFieldData(3),
+                        frameTuple.getFieldStart(3));
+                int numElements = IntegerSerializerDeserializer.getInt(frameTuple.getFieldData(4),
+                        frameTuple.getFieldStart(4));
+                invListCursor.reset(startPageId, endPageId, startOff, numElements);
+                ret = true;
+            } else {
+                invListCursor.reset(0, 0, 0, 0);
+            }
+        } finally {
+            btreeCursor.close();
+            btreeCursor.reset();
+        }
+        return ret;
+    }
+    
+    @Override
+    public IIndexBulkLoadContext beginBulkLoad(float fillFactor) throws TreeIndexException, HyracksDataException {
+        InvertedIndexBulkLoadContext ctx = new InvertedIndexBulkLoadContext(fillFactor);
         ctx.init(rootPageId, fileId);
         return ctx;
     }
 
-    // ASSUMPTIONS:
-    // the first btree.getMultiComparator().getKeyFieldCount() fields in tuple
-    // are btree keys (e.g., a string token)
-    // the next invListCmp.getKeyFieldCount() fields in tuple are keys of the
-    // inverted list (e.g., primary key)
-    // key fields of inverted list are fixed size
-    public void bulkLoadAddTuple(BulkLoadContext ctx, ITupleReference tuple) throws HyracksDataException {
-
-        // first inverted list, copy token to baaos and start new list
+    /**
+     * Assumptions:
+     * The first btree.getMultiComparator().getKeyFieldCount() fields in tuple
+     * are btree keys (e.g., a string token).
+     * The next invListCmp.getKeyFieldCount() fields in tuple are keys of the
+     * inverted list (e.g., primary key).
+     * Key fields of inverted list are fixed size.
+     * 
+     */
+    @Override
+    public void bulkLoadAddTuple(ITupleReference tuple, IIndexBulkLoadContext ictx) throws HyracksDataException {
+        InvertedIndexBulkLoadContext ctx = (InvertedIndexBulkLoadContext) ictx;
+        
+        // First inverted list, copy token to baaos and start new list.
         if (ctx.currentInvListTokenBaaos.size() == 0) {
             ctx.currentInvListStartPageId = ctx.currentPageId;
-            ctx.currentInvListStartOffset = ctx.invListBuilder.getPos();
+            ctx.currentInvListStartOffset = invListBuilder.getPos();
 
-            // remember current token
+            // Remember current token.
             ctx.currentInvListTokenBaaos.reset();
             for (int i = 0; i < numTokenFields; i++) {
                 ctx.currentInvListTokenBaaos.write(tuple.getFieldData(i), tuple.getFieldStart(i),
                         tuple.getFieldLength(i));
             }
 
-            if (!ctx.invListBuilder.startNewList(tuple, numTokenFields)) {
+            if (!invListBuilder.startNewList(tuple, numTokenFields)) {
                 ctx.pinNextPage();
-                ctx.invListBuilder.setTargetBuffer(ctx.currentPage.getBuffer().array(), 0);
-                if (!ctx.invListBuilder.startNewList(tuple, numTokenFields)) {
+                invListBuilder.setTargetBuffer(ctx.currentPage.getBuffer().array(), 0);
+                if (!invListBuilder.startNewList(tuple, numTokenFields)) {
                     throw new IllegalStateException("Failed to create first inverted list.");
                 }
             }
         }
 
-        // create new inverted list?
+        // Create new inverted list?
         ctx.currentInvListToken.reset(ctx.currentInvListTokenBaaos.getByteArray(), 0);
         if (ctx.tokenCmp.compare(tuple, ctx.currentInvListToken) != 0) {
 
-            // create entry in btree for last inverted list
+            // Create entry in btree for last inverted list.
             createAndInsertBTreeTuple(ctx);
 
-            // remember new token
+            // Remember new token.
             ctx.currentInvListTokenBaaos.reset();
             for (int i = 0; i < numTokenFields; i++) {
                 ctx.currentInvListTokenBaaos.write(tuple.getFieldData(i), tuple.getFieldStart(i),
                         tuple.getFieldLength(i));
             }
 
-            // start new list
-            if (!ctx.invListBuilder.startNewList(tuple, numTokenFields)) {
+            // Start new list.
+            if (!invListBuilder.startNewList(tuple, numTokenFields)) {
                 ctx.pinNextPage();
-                ctx.invListBuilder.setTargetBuffer(ctx.currentPage.getBuffer().array(), 0);
-                if (!ctx.invListBuilder.startNewList(tuple, numTokenFields)) {
+                invListBuilder.setTargetBuffer(ctx.currentPage.getBuffer().array(), 0);
+                if (!invListBuilder.startNewList(tuple, numTokenFields)) {
                     throw new IllegalStateException("Failed to start new inverted list after switching to a new page.");
                 }
             }
 
             ctx.currentInvListStartPageId = ctx.currentPageId;
-            ctx.currentInvListStartOffset = ctx.invListBuilder.getPos();
+            ctx.currentInvListStartOffset = invListBuilder.getPos();
         }
 
-        // append to current inverted list
-        if (!ctx.invListBuilder.appendElement(tuple, numTokenFields, numInvListKeys)) {
+        // Append to current inverted list.
+        if (!invListBuilder.appendElement(tuple, numTokenFields, numInvListKeys)) {
             ctx.pinNextPage();
-            ctx.invListBuilder.setTargetBuffer(ctx.currentPage.getBuffer().array(), 0);
-            if (!ctx.invListBuilder.appendElement(tuple, numTokenFields, numInvListKeys)) {
+            invListBuilder.setTargetBuffer(ctx.currentPage.getBuffer().array(), 0);
+            if (!invListBuilder.appendElement(tuple, numTokenFields, numInvListKeys)) {
                 throw new IllegalStateException(
                         "Failed to append element to inverted list after switching to a new page.");
             }
         }
     }
 
-    public boolean openCursor(ITreeIndexCursor btreeCursor, RangePredicate btreePred, ITreeIndexAccessor btreeAccessor,
-            IInvertedListCursor invListCursor) throws Exception {
-    	btreeAccessor.search(btreeCursor, btreePred);
-
-        boolean ret = false;
-        if (btreeCursor.hasNext()) {
-
-            btreeCursor.next();
-            ITupleReference frameTuple = btreeCursor.getTuple();
-
-            // hardcoded mapping of btree fields
-            int startPageId = IntegerSerializerDeserializer.getInt(frameTuple.getFieldData(1),
-                    frameTuple.getFieldStart(1));
-            int endPageId = IntegerSerializerDeserializer.getInt(frameTuple.getFieldData(2),
-                    frameTuple.getFieldStart(2));
-            int startOff = IntegerSerializerDeserializer
-                    .getInt(frameTuple.getFieldData(3), frameTuple.getFieldStart(3));
-            int numElements = IntegerSerializerDeserializer.getInt(frameTuple.getFieldData(4),
-                    frameTuple.getFieldStart(4));
-
-            invListCursor.reset(startPageId, endPageId, startOff, numElements);
-            ret = true;
-        } else {
-            invListCursor.reset(0, 0, 0, 0);
-        }
-
-        btreeCursor.close();
-        btreeCursor.reset();
-
-        return ret;
-    }
-
-    public void createAndInsertBTreeTuple(BulkLoadContext ctx) throws HyracksDataException {
-        // build tuple
+    private void createAndInsertBTreeTuple(InvertedIndexBulkLoadContext ctx) throws HyracksDataException {        
+        // Build tuple.        
         ctx.btreeTupleBuilder.reset();
         ctx.btreeTupleBuilder.addField(ctx.currentInvListTokenBaaos.getByteArray(), 0,
                 ctx.currentInvListTokenBaaos.size());
         ctx.btreeTupleBuilder.addField(IntegerSerializerDeserializer.INSTANCE, ctx.currentInvListStartPageId);
         ctx.btreeTupleBuilder.addField(IntegerSerializerDeserializer.INSTANCE, ctx.currentPageId);
         ctx.btreeTupleBuilder.addField(IntegerSerializerDeserializer.INSTANCE, ctx.currentInvListStartOffset);
-        ctx.btreeTupleBuilder.addField(IntegerSerializerDeserializer.INSTANCE, ctx.invListBuilder.getListSize());
-
-        // append to buffer
-        ctx.btreeTupleAppender.reset(ctx.btreeTupleBuffer, true);
-        ctx.btreeTupleAppender.append(ctx.btreeTupleBuilder.getFieldEndOffsets(), ctx.btreeTupleBuilder.getByteArray(),
-                0, ctx.btreeTupleBuilder.getSize());
-
-        // reset tuple reference
-        ctx.btreeFrameTupleReference.reset(ctx.btreeFrameTupleAccessor, 0);
-
-        btree.bulkLoadAddTuple(ctx.btreeFrameTupleReference, ctx.btreeBulkLoadCtx);
+        ctx.btreeTupleBuilder.addField(IntegerSerializerDeserializer.INSTANCE, invListBuilder.getListSize());
+        // Reset tuple reference and add it.
+        ctx.btreeTupleReference.reset(ctx.btreeTupleBuilder.getFieldEndOffsets(), ctx.btreeTupleBuilder.getByteArray());
+        btree.bulkLoadAddTuple(ctx.btreeTupleReference, ctx.btreeBulkLoadCtx);
     }
 
-    public void endBulkLoad(BulkLoadContext ctx) throws HyracksDataException {
-        // create entry in btree for last inverted list
+    @Override
+    public void endBulkLoad(IIndexBulkLoadContext ictx) throws HyracksDataException {
+        // Create entry in btree for last inverted list.
+        InvertedIndexBulkLoadContext ctx = (InvertedIndexBulkLoadContext) ictx;
         createAndInsertBTreeTuple(ctx);
         btree.endBulkLoad(ctx.btreeBulkLoadCtx);
         ctx.deinit();
     }
+    
+    public final class InvertedIndexBulkLoadContext implements IIndexBulkLoadContext {
+        private final ArrayTupleBuilder btreeTupleBuilder;
+        private final ArrayTupleReference btreeTupleReference;
+        private final float btreeFillFactor;
+        private IIndexBulkLoadContext btreeBulkLoadCtx;
 
+        private int currentInvListStartPageId;
+        private int currentInvListStartOffset;
+        private final ByteArrayAccessibleOutputStream currentInvListTokenBaaos = new ByteArrayAccessibleOutputStream();
+        private final FixedSizeTupleReference currentInvListToken = new FixedSizeTupleReference(invListTypeTraits);
+
+        private int currentPageId;
+        private ICachedPage currentPage;
+        private final MultiComparator tokenCmp;
+
+        public InvertedIndexBulkLoadContext(float btreeFillFactor) {
+            this.tokenCmp = MultiComparator.create(btree.getComparatorFactories());
+            this.btreeTupleBuilder = new ArrayTupleBuilder(btree.getFieldCount());
+            this.btreeTupleReference = new ArrayTupleReference();
+            this.btreeFillFactor = btreeFillFactor;
+        }
+
+        public void init(int startPageId, int fileId) throws HyracksDataException, TreeIndexException {
+            btreeBulkLoadCtx = btree.beginBulkLoad(btreeFillFactor);
+            currentPageId = startPageId;
+            currentPage = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, currentPageId), true);
+            currentPage.acquireWriteLatch();
+            invListBuilder.setTargetBuffer(currentPage.getBuffer().array(), 0);
+        }
+
+        public void deinit() throws HyracksDataException {
+            if (currentPage != null) {
+                currentPage.releaseWriteLatch();
+                bufferCache.unpin(currentPage);
+            }
+        }
+
+        public void pinNextPage() throws HyracksDataException {
+            currentPage.releaseWriteLatch();
+            bufferCache.unpin(currentPage);
+            currentPageId++;
+            currentPage = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, currentPageId), true);
+            currentPage.acquireWriteLatch();
+        }
+    }
+
+    @Override
     public IBufferCache getBufferCache() {
         return bufferCache;
     }
@@ -237,65 +295,75 @@
     public BTree getBTree() {
         return btree;
     }
-
-    public final class BulkLoadContext {
-        private final ByteBuffer btreeTupleBuffer;
-        private final ArrayTupleBuilder btreeTupleBuilder;
-        private final FrameTupleAppender btreeTupleAppender;
-        private final FrameTupleAccessor btreeFrameTupleAccessor;
-        private final FrameTupleReference btreeFrameTupleReference = new FrameTupleReference();
-        private final float btreeFillFactor;
-        private IIndexBulkLoadContext btreeBulkLoadCtx;
-
-        private int currentInvListStartPageId;
-        private int currentInvListStartOffset;
-        private final ByteArrayAccessibleOutputStream currentInvListTokenBaaos = new ByteArrayAccessibleOutputStream();
-        private final FixedSizeTupleReference currentInvListToken = new FixedSizeTupleReference(invListTypeTraits);
-
-        private int currentPageId;
-        private ICachedPage currentPage;
-        private final IInvertedListBuilder invListBuilder;
-        private final MultiComparator tokenCmp;
-
-        public BulkLoadContext(IInvertedListBuilder invListBuilder, int hyracksFrameSize, float btreeFillFactor) {
-            this.invListBuilder = invListBuilder;
-            this.tokenCmp = MultiComparator.create(btree.getComparatorFactories());
-            this.btreeTupleBuffer = ByteBuffer.allocate(hyracksFrameSize);
-            this.btreeTupleBuilder = new ArrayTupleBuilder(btree.getFieldCount());
-            this.btreeTupleAppender = new FrameTupleAppender(hyracksFrameSize);
-            // TODO: serde never used, only need correct number of fields
-            // tuple contains (token, start page, end page, start offset, num
-            // elements)
-            RecordDescriptor recDesc = new RecordDescriptor(new ISerializerDeserializer[] {
-                    IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE,
-                    IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE,
-                    IntegerSerializerDeserializer.INSTANCE });
-            this.btreeFrameTupleAccessor = new FrameTupleAccessor(hyracksFrameSize, recDesc);
-            this.btreeFillFactor = btreeFillFactor;
+    
+    public class InvertedIndexAccessor implements IIndexAccessor {        
+        private final IInvertedIndexSearcher searcher;
+        
+        public InvertedIndexAccessor(InvertedIndex index) {
+            this.searcher = new TOccurrenceSearcher(ctx, index, tokenizer);
+        }
+        
+        @Override
+        public void insert(ITupleReference tuple) throws HyracksDataException, IndexException {
+            // TODO Auto-generated method stub
         }
 
-        public void init(int startPageId, int fileId) throws HyracksDataException, TreeIndexException {
-            btreeBulkLoadCtx = btree.beginBulkLoad(btreeFillFactor);
-            currentPageId = startPageId;
-            currentPage = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, currentPageId), true);
-            currentPage.acquireWriteLatch();
-            invListBuilder.setTargetBuffer(currentPage.getBuffer().array(), 0);
-            btreeFrameTupleAccessor.reset(btreeTupleBuffer);
+        @Override
+        public void update(ITupleReference tuple) throws HyracksDataException, IndexException {
+            // TODO Auto-generated method stub
         }
 
-        public void deinit() throws HyracksDataException {
-            if (currentPage != null) {
-                currentPage.releaseWriteLatch();
-                bufferCache.unpin(currentPage);
-            }
+        @Override
+        public void delete(ITupleReference tuple) throws HyracksDataException, IndexException {
+            // TODO Auto-generated method stub
         }
 
-        public void pinNextPage() throws HyracksDataException {
-            currentPage.releaseWriteLatch();
-            bufferCache.unpin(currentPage);
-            currentPageId++;
-            currentPage = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, currentPageId), true);
-            currentPage.acquireWriteLatch();
+        @Override
+        public IIndexCursor createSearchCursor() {
+            return new InvertedIndexSearchCursor(searcher);
+        }
+
+        @Override
+        public void search(IIndexCursor cursor, ISearchPredicate searchPred) throws HyracksDataException,
+                IndexException {
+            searcher.search((InvertedIndexSearchCursor) cursor, (InvertedIndexSearchPredicate) searchPred);
+        }
+        
+        public IInvertedIndexSearcher getSearcher() {
+            return searcher;
+        }
+    }
+    
+    @Override
+    public IIndexAccessor createAccessor() {
+        return new InvertedIndexAccessor(this);
+    }
+
+    @Override
+    public IndexType getIndexType() {
+        return IndexType.INVERTED;
+    }
+
+    // This is just a dummy hyracks context for allocating frames for temporary
+    // results during inverted index searches.
+    // TODO: In the future we should use the real HyracksTaskContext to track
+    // frame usage.
+    private class DefaultHyracksCommonContext implements IHyracksCommonContext {
+        private final int FRAME_SIZE = 32768;
+
+        @Override
+        public ByteBuffer allocateFrame() {
+            return ByteBuffer.allocate(FRAME_SIZE);
+        }
+
+        @Override
+        public int getFrameSize() {
+            return FRAME_SIZE;
+        }
+
+        @Override
+        public IIOManager getIOManager() {
+            return null;
         }
     }
 }
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/InvertedIndexException.java b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/InvertedIndexException.java
index 494ac0c..9762a74 100644
--- a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/InvertedIndexException.java
+++ b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/InvertedIndexException.java
@@ -15,7 +15,9 @@
 
 package edu.uci.ics.hyracks.storage.am.invertedindex.impls;
 
-public class InvertedIndexException extends Exception {
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
+
+public class InvertedIndexException extends IndexException {
     private static final long serialVersionUID = 1L;
 
     public InvertedIndexException(String msg) {
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/InvertedIndexSearchCursor.java b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/InvertedIndexSearchCursor.java
new file mode 100644
index 0000000..1eeb576
--- /dev/null
+++ b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/InvertedIndexSearchCursor.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.invertedindex.impls;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import edu.uci.ics.hyracks.api.comm.IFrameTupleAccessor;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.ICursorInitialState;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
+import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
+import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedIndexSearcher;
+
+public class InvertedIndexSearchCursor implements IIndexCursor {
+
+    private List<ByteBuffer> resultBuffers;
+    private int numResultBuffers;
+    private int currentBufferIndex = 0;
+    private int tupleIndex = 0;
+    private final IInvertedIndexSearcher invIndexSearcher;
+    private final IFrameTupleAccessor fta;
+    private final FixedSizeTupleReference resultTuple;
+    
+    public InvertedIndexSearchCursor(IInvertedIndexSearcher invIndexSearcher) {
+        this.invIndexSearcher = invIndexSearcher;
+        this.fta = invIndexSearcher.createResultFrameTupleAccessor();
+        this.resultTuple = (FixedSizeTupleReference) invIndexSearcher.createResultTupleReference();
+    }
+
+    @Override
+    public void open(ICursorInitialState initialState, ISearchPredicate searchPred) throws HyracksDataException {
+        currentBufferIndex = 0;
+        tupleIndex = 0;
+        resultBuffers = invIndexSearcher.getResultBuffers();
+        numResultBuffers = invIndexSearcher.getNumValidResultBuffers();
+        if (numResultBuffers > 0) {
+            fta.reset(resultBuffers.get(0));
+        }
+    }
+    
+    @Override
+    public boolean hasNext() {
+        if (currentBufferIndex < numResultBuffers && tupleIndex < fta.getTupleCount()) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public void next() {
+        resultTuple.reset(fta.getBuffer().array(), fta.getTupleStartOffset(tupleIndex));
+        tupleIndex++;
+        if (tupleIndex >= fta.getTupleCount()) {
+            if (currentBufferIndex + 1 < numResultBuffers) {
+                currentBufferIndex++;
+                fta.reset(resultBuffers.get(currentBufferIndex));
+                tupleIndex = 0;
+            }
+        }
+    }
+
+    @Override
+    public ITupleReference getTuple() {
+        return resultTuple;
+    }
+
+    @Override
+    public void reset() {
+        currentBufferIndex = 0;
+        tupleIndex = 0;
+        invIndexSearcher.reset();
+        resultBuffers = invIndexSearcher.getResultBuffers();
+        numResultBuffers = invIndexSearcher.getNumValidResultBuffers();
+    }
+
+    @Override
+    public void close() throws HyracksDataException {
+        currentBufferIndex = 0;
+        tupleIndex = 0;
+        resultBuffers = null;
+        numResultBuffers = 0;
+    }
+}
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/InvertedIndexSearchPredicate.java b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/InvertedIndexSearchPredicate.java
new file mode 100644
index 0000000..989878d
--- /dev/null
+++ b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/InvertedIndexSearchPredicate.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.invertedindex.impls;
+
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
+import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedIndexSearchModifier;
+
+public class InvertedIndexSearchPredicate implements ISearchPredicate {
+    private static final long serialVersionUID = 1L;
+
+    private ITupleReference queryTuple;
+    private int queryFieldIndex;
+    private final IInvertedIndexSearchModifier searchModifier;
+    
+    public InvertedIndexSearchPredicate(IInvertedIndexSearchModifier searchModifier) {
+        this.searchModifier = searchModifier;
+    }
+    
+    public void setQueryTuple(ITupleReference queryTuple) {
+        this.queryTuple = queryTuple;
+    }
+    
+    public ITupleReference getQueryTuple() {
+        return queryTuple;
+    }
+    
+    public void setQueryFieldIndex(int queryFieldIndex) {
+        this.queryFieldIndex = queryFieldIndex;
+    }
+    
+    public int getQueryFieldIndex() {
+        return queryFieldIndex;
+    }
+    
+    public IInvertedIndexSearchModifier getSearchModifier() {
+        return searchModifier;
+    }
+    
+    @Override
+    public MultiComparator getLowKeyComparator() {
+        // TODO: This doesn't make sense for an inverted index. Change ISearchPredicate interface.
+        return null;
+    }
+
+    @Override
+    public MultiComparator getHighKeyComparator() {
+        // TODO: This doesn't make sense for an inverted index. Change ISearchPredicate interface.
+        return null;
+    }
+}
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/SearchResultCursor.java b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/SearchResultCursor.java
deleted file mode 100644
index 5a7230c..0000000
--- a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/SearchResultCursor.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2009-2010 by The Regents of the University of California
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * you may obtain a copy of the License from
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.uci.ics.hyracks.storage.am.invertedindex.impls;
-
-import java.nio.ByteBuffer;
-import java.util.List;
-
-import edu.uci.ics.hyracks.api.comm.IFrameTupleAccessor;
-import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
-import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedIndexResultCursor;
-import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedIndexSearcher;
-
-public class SearchResultCursor implements IInvertedIndexResultCursor {
-
-    private List<ByteBuffer> resultBuffers;
-    private IFrameTupleAccessor fta;
-    private FixedSizeTupleReference resultTuple;
-    private int numResultBuffers;
-    private int currentBufferIndex = 0;
-    private int tupleIndex = 0;
-
-    public SearchResultCursor(IFrameTupleAccessor fta, ITupleReference resultTuple) {
-        this.fta = fta;
-        this.resultTuple = (FixedSizeTupleReference) resultTuple;
-    }
-
-    @Override
-    public boolean hasNext() {
-        if (currentBufferIndex < numResultBuffers && tupleIndex < fta.getTupleCount())
-            return true;
-        else
-            return false;
-    }
-
-    @Override
-    public void next() {
-        resultTuple.reset(fta.getBuffer().array(), fta.getTupleStartOffset(tupleIndex));
-        tupleIndex++;
-        if (tupleIndex >= fta.getTupleCount()) {
-            if (currentBufferIndex + 1 < numResultBuffers) {
-                currentBufferIndex++;
-                fta.reset(resultBuffers.get(currentBufferIndex));
-                tupleIndex = 0;
-            }
-        }
-    }
-
-    @Override
-    public ITupleReference getTuple() {
-        return resultTuple;
-    }
-
-    @Override
-    public void reset(IInvertedIndexSearcher invIndexSearcher) {
-        currentBufferIndex = 0;
-        tupleIndex = 0;
-        resultBuffers = invIndexSearcher.getResultBuffers();
-        numResultBuffers = invIndexSearcher.getNumValidResultBuffers();
-        if (numResultBuffers > 0) {
-            fta.reset(resultBuffers.get(0));
-        }
-    }
-}
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/TOccurrenceSearcher.java b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/TOccurrenceSearcher.java
index 220f35b..3270216 100644
--- a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/TOccurrenceSearcher.java
+++ b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/TOccurrenceSearcher.java
@@ -22,7 +22,7 @@
 import java.util.List;
 
 import edu.uci.ics.hyracks.api.comm.IFrameTupleAccessor;
-import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
+import edu.uci.ics.hyracks.api.context.IHyracksCommonContext;
 import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
 import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
 import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
@@ -41,8 +41,8 @@
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrame;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
-import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedIndexResultCursor;
 import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedIndexSearchModifier;
 import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedIndexSearcher;
 import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedListCursor;
@@ -51,7 +51,7 @@
 
 public class TOccurrenceSearcher implements IInvertedIndexSearcher {
 
-    protected final IHyracksTaskContext ctx;
+    protected final IHyracksCommonContext ctx;
     protected final FixedSizeFrameTupleAppender resultFrameTupleApp;
     protected final FixedSizeFrameTupleAccessor resultFrameTupleAcc;
     protected final FixedSizeTupleReference resultTuple;
@@ -87,7 +87,7 @@
     protected List<IInvertedListCursor> invListCursorCache = new ArrayList<IInvertedListCursor>(cursorCacheSize);
     protected List<IInvertedListCursor> invListCursors = new ArrayList<IInvertedListCursor>(cursorCacheSize);
 
-    public TOccurrenceSearcher(IHyracksTaskContext ctx, InvertedIndex invIndex, IBinaryTokenizer queryTokenizer) {
+    public TOccurrenceSearcher(IHyracksCommonContext ctx, InvertedIndex invIndex, IBinaryTokenizer queryTokenizer) {
         this.ctx = ctx;
         this.invIndex = invIndex;
         this.invListCmp = MultiComparator.create(invIndex.getInvListElementCmpFactories());
@@ -143,12 +143,14 @@
         currentNumResults = 0;
     }
 
-    public void search(IInvertedIndexResultCursor resultCursor, ITupleReference queryTuple, int queryField,
-            IInvertedIndexSearchModifier searchModifier) throws Exception {
-
-        queryTokenAppender.reset(queryTokenFrame, true);
-        queryTokenizer.reset(queryTuple.getFieldData(queryField), queryTuple.getFieldStart(queryField),
-                queryTuple.getFieldLength(queryField));
+    public void search(InvertedIndexSearchCursor resultCursor, InvertedIndexSearchPredicate searchPred) throws HyracksDataException, IndexException {
+        ITupleReference queryTuple = searchPred.getQueryTuple();
+        int queryFieldIndex = searchPred.getQueryFieldIndex();
+        IInvertedIndexSearchModifier searchModifier = searchPred.getSearchModifier();
+        
+        queryTokenAppender.reset(queryTokenFrame, true);                
+        queryTokenizer.reset(queryTuple.getFieldData(queryFieldIndex), queryTuple.getFieldStart(queryFieldIndex),
+                queryTuple.getFieldLength(queryFieldIndex));
 
         while (queryTokenizer.hasNext()) {
             queryTokenizer.next();
@@ -196,10 +198,10 @@
         maxResultBufIdx = mergePrefixLists(numPrefixLists, numQueryTokens);
         maxResultBufIdx = mergeSuffixLists(numPrefixLists, numQueryTokens, maxResultBufIdx);
 
-        resultCursor.reset(this);
+        resultCursor.open(null, searchPred);
     }
 
-    protected int mergePrefixLists(int numPrefixTokens, int numQueryTokens) throws IOException {
+    protected int mergePrefixLists(int numPrefixTokens, int numQueryTokens) throws HyracksDataException {
         int maxPrevBufIdx = 0;
         for (int i = 0; i < numPrefixTokens; i++) {
             swap = prevResultBuffers;
@@ -214,7 +216,7 @@
         return maxPrevBufIdx;
     }
 
-    protected int mergeSuffixLists(int numPrefixTokens, int numQueryTokens, int maxPrevBufIdx) throws IOException {
+    protected int mergeSuffixLists(int numPrefixTokens, int numQueryTokens, int maxPrevBufIdx) throws HyracksDataException {
         for (int i = numPrefixTokens; i < numQueryTokens; i++) {
             swap = prevResultBuffers;
             prevResultBuffers = newResultBuffers;
@@ -236,7 +238,7 @@
     }
 
     protected int mergeSuffixListProbe(IInvertedListCursor invListCursor, List<ByteBuffer> prevResultBuffers,
-            int maxPrevBufIdx, List<ByteBuffer> newResultBuffers, int invListIx, int numQueryTokens) throws IOException {
+            int maxPrevBufIdx, List<ByteBuffer> newResultBuffers, int invListIx, int numQueryTokens) {
 
         int newBufIdx = 0;
         ByteBuffer newCurrentBuffer = newResultBuffers.get(0);
@@ -281,7 +283,7 @@
     }
 
     protected int mergeSuffixListScan(IInvertedListCursor invListCursor, List<ByteBuffer> prevResultBuffers,
-            int maxPrevBufIdx, List<ByteBuffer> newResultBuffers, int invListIx, int numQueryTokens) throws IOException {
+            int maxPrevBufIdx, List<ByteBuffer> newResultBuffers, int invListIx, int numQueryTokens) {
         int newBufIdx = 0;
         ByteBuffer newCurrentBuffer = newResultBuffers.get(0);
 
@@ -373,7 +375,7 @@
     }
 
     protected int mergePrefixList(IInvertedListCursor invListCursor, List<ByteBuffer> prevResultBuffers,
-            int maxPrevBufIdx, List<ByteBuffer> newResultBuffers) throws IOException {
+            int maxPrevBufIdx, List<ByteBuffer> newResultBuffers) {
         int newBufIdx = 0;
         ByteBuffer newCurrentBuffer = newResultBuffers.get(0);
 
@@ -469,7 +471,7 @@
         return newBufIdx;
     }
 
-    protected int appendTupleToNewResults(ITupleReference tuple, int newCount, int newBufIdx) throws IOException {
+    protected int appendTupleToNewResults(ITupleReference tuple, int newCount, int newBufIdx) {
         ByteBuffer newCurrentBuffer = newResultBuffers.get(newBufIdx);
 
         if (!resultFrameTupleApp.hasSpace()) {
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/TOccurrenceSearcherSuffixProbeOnly.java b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/TOccurrenceSearcherSuffixProbeOnly.java
index 87c718b..b40b9cf 100644
--- a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/TOccurrenceSearcherSuffixProbeOnly.java
+++ b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/TOccurrenceSearcherSuffixProbeOnly.java
@@ -15,11 +15,11 @@
 
 package edu.uci.ics.hyracks.storage.am.invertedindex.impls;
 
-import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.List;
 
 import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
 import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedListCursor;
@@ -35,7 +35,7 @@
         this.invListCmp = MultiComparator.create(invIndex.getInvListElementCmpFactories());
     }
 
-    protected int mergeSuffixLists(int numPrefixTokens, int numQueryTokens, int maxPrevBufIdx) throws IOException {
+    protected int mergeSuffixLists(int numPrefixTokens, int numQueryTokens, int maxPrevBufIdx) throws HyracksDataException {
         for (int i = numPrefixTokens; i < numQueryTokens; i++) {
             swap = prevResultBuffers;
             prevResultBuffers = newResultBuffers;
@@ -51,7 +51,7 @@
     }
 
     protected int mergeSuffixListProbe(IInvertedListCursor invListCursor, List<ByteBuffer> prevResultBuffers,
-            int maxPrevBufIdx, List<ByteBuffer> newResultBuffers, int invListIx, int numQueryTokens) throws IOException {
+            int maxPrevBufIdx, List<ByteBuffer> newResultBuffers, int invListIx, int numQueryTokens) {
 
         int newBufIdx = 0;
         ByteBuffer newCurrentBuffer = newResultBuffers.get(0);
diff --git a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/TOccurrenceSearcherSuffixScanOnly.java b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/TOccurrenceSearcherSuffixScanOnly.java
index 04f2d9f..ab48ac7 100644
--- a/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/TOccurrenceSearcherSuffixScanOnly.java
+++ b/hyracks-storage-am-invertedindex/src/main/java/edu/uci/ics/hyracks/storage/am/invertedindex/impls/TOccurrenceSearcherSuffixScanOnly.java
@@ -15,11 +15,11 @@
 
 package edu.uci.ics.hyracks.storage.am.invertedindex.impls;
 
-import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.List;
 
 import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
@@ -36,7 +36,7 @@
         this.invListCmp = MultiComparator.create(invIndex.getInvListElementCmpFactories());
     }
 
-    protected int mergeSuffixLists(int numPrefixTokens, int numQueryTokens, int maxPrevBufIdx) throws IOException {
+    protected int mergeSuffixLists(int numPrefixTokens, int numQueryTokens, int maxPrevBufIdx) throws HyracksDataException {
         for (int i = numPrefixTokens; i < numQueryTokens; i++) {
             swap = prevResultBuffers;
             prevResultBuffers = newResultBuffers;
@@ -52,7 +52,7 @@
     }
 
     protected int mergeSuffixListScan(IInvertedListCursor invListCursor, List<ByteBuffer> prevResultBuffers,
-            int maxPrevBufIdx, List<ByteBuffer> newResultBuffers, int invListIx, int numQueryTokens) throws IOException {
+            int maxPrevBufIdx, List<ByteBuffer> newResultBuffers, int invListIx, int numQueryTokens) {
 
         int newBufIdx = 0;
         ByteBuffer newCurrentBuffer = newResultBuffers.get(0);
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/impls/LSMBTree.java b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/impls/LSMBTree.java
index 725f680..ef380f4 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/impls/LSMBTree.java
+++ b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/impls/LSMBTree.java
@@ -32,20 +32,23 @@
 import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
 import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
 import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexBulkLoadContext;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexOpContext;
 import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
 import edu.uci.ics.hyracks.storage.am.common.api.IndexType;
 import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
 import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMComponentFinalizer;
 import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMFileManager;
-import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMTree;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMIndex;
 import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryFreePageManager;
 import edu.uci.ics.hyracks.storage.am.lsm.common.impls.BTreeFactory;
 import edu.uci.ics.hyracks.storage.am.lsm.common.impls.LSMHarness;
@@ -54,7 +57,7 @@
 import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
 import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
 
-public class LSMBTree implements ILSMTree {
+public class LSMBTree implements ILSMIndex, ITreeIndex {
     protected final Logger LOGGER = Logger.getLogger(LSMBTree.class.getName());
     
     private final LSMHarness lsmHarness;
@@ -260,11 +263,11 @@
     }
 
     @Override
-    public ITreeIndex flush() throws HyracksDataException, TreeIndexException {
+    public ITreeIndex flush() throws HyracksDataException, IndexException {
         // Bulk load a new on-disk BTree from the in-memory BTree.        
         RangePredicate nullPred = new RangePredicate(null, null, true, true, null, null);
         ITreeIndexAccessor memBTreeAccessor = memBTree.createAccessor();
-        ITreeIndexCursor scanCursor = memBTreeAccessor.createSearchCursor();
+        IIndexCursor scanCursor = memBTreeAccessor.createSearchCursor();
         memBTreeAccessor.search(scanCursor, nullPred);
         BTree diskBTree = createFlushTarget();
         // Bulk load the tuples from the in-memory BTree into the new disk BTree.
@@ -330,7 +333,7 @@
         return diskBTree;
     }
     
-    public void search(ITreeIndexCursor cursor, List<Object> diskComponents, ISearchPredicate pred, IIndexOpContext ictx, boolean includeMemComponent, AtomicInteger searcherRefCount) throws HyracksDataException, TreeIndexException {
+    public void search(IIndexCursor cursor, List<Object> diskComponents, ISearchPredicate pred, IIndexOpContext ictx, boolean includeMemComponent, AtomicInteger searcherRefCount) throws HyracksDataException, IndexException {
         LSMBTreeOpContext ctx = (LSMBTreeOpContext) ictx;
         LSMBTreeRangeSearchCursor lsmTreeCursor = (LSMBTreeRangeSearchCursor) cursor;
         int numDiskBTrees = diskComponents.size();
@@ -363,7 +366,7 @@
         lsmTreeCursor.initPriorityQueue();
     }
     
-    public ITreeIndex merge(List<Object> mergedComponents) throws HyracksDataException, TreeIndexException  {
+    public ITreeIndex merge(List<Object> mergedComponents) throws HyracksDataException, IndexException  {
         LSMBTreeOpContext ctx = createOpContext();
         ITreeIndexCursor cursor = new LSMBTreeRangeSearchCursor();
         RangePredicate rangePred = new RangePredicate(null, null, true, true, null, null);
@@ -509,7 +512,7 @@
     }
 
     @Override
-    public ITreeIndexAccessor createAccessor() {
+    public IIndexAccessor createAccessor() {
         return new LSMBTreeIndexAccessor(lsmHarness, createOpContext());
     }
     
@@ -519,7 +522,7 @@
         }
 
         @Override
-        public ITreeIndexCursor createSearchCursor() {
+        public IIndexCursor createSearchCursor() {
             return new LSMBTreeRangeSearchCursor();
         }
         
diff --git a/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMTree.java b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMIndex.java
similarity index 79%
rename from hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMTree.java
rename to hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMIndex.java
index dd1e3f9..362fa7c 100644
--- a/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMTree.java
+++ b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMIndex.java
@@ -20,11 +20,11 @@
 
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexOpContext;
 import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
-import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndex;
 import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryFreePageManager;
 
 /**
@@ -36,20 +36,20 @@
  * concurrent searches/updates/merges may be ongoing.
  * 
  */
-public interface ILSMTree extends ITreeIndex {
+public interface ILSMIndex extends IIndex {
     public boolean insertUpdateOrDelete(ITupleReference tuple, IIndexOpContext ictx) throws HyracksDataException,
-            TreeIndexException;
+            IndexException;
 
-    public void search(ITreeIndexCursor cursor, List<Object> diskComponents, ISearchPredicate pred,
-            IIndexOpContext ictx, boolean includeMemComponent, AtomicInteger searcherRefCount) throws HyracksDataException, TreeIndexException;
+    public void search(IIndexCursor cursor, List<Object> diskComponents, ISearchPredicate pred,
+            IIndexOpContext ictx, boolean includeMemComponent, AtomicInteger searcherRefCount) throws HyracksDataException, IndexException;
 
-    public Object merge(List<Object> mergedComponents) throws HyracksDataException, TreeIndexException;
+    public Object merge(List<Object> mergedComponents) throws HyracksDataException, IndexException;
 
     public void addMergedComponent(Object newComponent, List<Object> mergedComponents);
 
     public void cleanUpAfterMerge(List<Object> mergedComponents) throws HyracksDataException;
 
-    public Object flush() throws HyracksDataException, TreeIndexException;
+    public Object flush() throws HyracksDataException, IndexException;
 
     public void addFlushedComponent(Object index);
 
diff --git a/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMTreeIndexAccessor.java b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMIndexAccessor.java
similarity index 81%
rename from hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMTreeIndexAccessor.java
rename to hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMIndexAccessor.java
index 032b112..e762bb5 100644
--- a/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMTreeIndexAccessor.java
+++ b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMIndexAccessor.java
@@ -16,7 +16,8 @@
 package edu.uci.ics.hyracks.storage.am.lsm.common.api;
 
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
 import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
 
 /**
@@ -26,14 +27,14 @@
  * can concurrently operate on the same ILSMTree (i.e., the ILSMTree must allow
  * concurrent operations).
  */
-public interface ILSMTreeIndexAccessor extends ITreeIndexAccessor {
+public interface ILSMIndexAccessor extends IIndexAccessor {
 	/**
 	 * Force a flush of the in-memory component.
 	 * 
 	 * @throws HyracksDataException
 	 * @throws TreeIndexException
 	 */
-	public void flush() throws HyracksDataException, TreeIndexException;
+	public void flush() throws HyracksDataException, IndexException;
 
     /**
      * Merge all on-disk components.
@@ -41,5 +42,5 @@
      * @throws HyracksDataException
      * @throws TreeIndexException
      */
-    public void merge() throws HyracksDataException, TreeIndexException;
+    public void merge() throws HyracksDataException, IndexException;
 }
diff --git a/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/LSMHarness.java b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/LSMHarness.java
index 222d627..846bacf 100644
--- a/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/LSMHarness.java
+++ b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/LSMHarness.java
@@ -24,11 +24,11 @@
 
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexOpContext;
 import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
-import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
-import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMTree;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMIndex;
 
 /**
  * Common code for synchronizing LSM operations like
@@ -49,8 +49,8 @@
 	protected final Logger LOGGER = Logger.getLogger(LSMHarness.class.getName());
 	protected static final long AFTER_MERGE_CLEANUP_SLEEP = 100;
 	
-	private ILSMTree lsmTree;    
-    
+	private ILSMIndex lsmIndex;
+	
 	// All accesses to the LSM-Tree's on-disk components are synchronized on diskComponentsSync.
 	private Object diskComponentsSync = new Object();
 	
@@ -68,8 +68,8 @@
     // We alternate between searcherRefCountA and searcherRefCountB.
     private AtomicInteger searcherRefCount = searcherRefCountA;
     
-    public LSMHarness(ILSMTree lsmTree) {
-    	this.lsmTree = lsmTree;
+    public LSMHarness(ILSMIndex lsmIndex) {
+    	this.lsmIndex = lsmIndex;
         this.threadRefCount = 0;
         this.flushFlag = false;
     }
@@ -78,11 +78,11 @@
         threadRefCount++;
     }
     
-    public void threadExit() throws HyracksDataException, TreeIndexException {
+    public void threadExit() throws HyracksDataException, IndexException {
         synchronized (this) {
             threadRefCount--;
             // Check if we've reached or exceeded the maximum number of pages.
-            if (!flushFlag && lsmTree.getInMemoryFreePageManager().isFull()) {
+            if (!flushFlag && lsmIndex.getInMemoryFreePageManager().isFull()) {
                 flushFlag = true;
             }
             // Flush will only be handled by last exiting thread.
@@ -93,7 +93,7 @@
         }
     }
     
-	public void insertUpdateOrDelete(ITupleReference tuple, IIndexOpContext ctx) throws HyracksDataException, TreeIndexException {
+	public void insertUpdateOrDelete(ITupleReference tuple, IIndexOpContext ctx) throws HyracksDataException, IndexException {
 		boolean waitForFlush = true;
 		do {
 		    // Wait for ongoing flush to complete.
@@ -111,32 +111,32 @@
 		boolean operationComplete = true;
 		try {
 			do {
-			    operationComplete = lsmTree.insertUpdateOrDelete(tuple, ctx);
+			    operationComplete = lsmIndex.insertUpdateOrDelete(tuple, ctx);
 			} while (!operationComplete);
 		} finally {
 			threadExit();
 		}
 	}
 
-    public void flush() throws HyracksDataException, TreeIndexException {
+    public void flush() throws HyracksDataException, IndexException {
         if (LOGGER.isLoggable(Level.INFO)) {
             LOGGER.info("Flushing LSM-Tree.");
         }
-        Object newComponent = lsmTree.flush();
+        Object newComponent = lsmIndex.flush();
         
         // The implementation of this call must take any necessary steps to make
         // the new component permanent, and mark it as valid (usually this means
         // forcing all pages of the tree to disk, possibly with some extra
         // information to mark the tree as valid).
-        lsmTree.getComponentFinalizer().finalize(newComponent);
+        lsmIndex.getComponentFinalizer().finalize(newComponent);
         
-        lsmTree.resetInMemoryComponent();
+        lsmIndex.resetInMemoryComponent();
         synchronized (diskComponentsSync) {
-            lsmTree.addFlushedComponent(newComponent);
+            lsmIndex.addFlushedComponent(newComponent);
         }
     }
     
-    public List<Object> search(ITreeIndexCursor cursor, ISearchPredicate pred, IIndexOpContext ctx, boolean includeMemComponent) throws HyracksDataException, TreeIndexException {                
+    public List<Object> search(IIndexCursor cursor, ISearchPredicate pred, IIndexOpContext ctx, boolean includeMemComponent) throws HyracksDataException, IndexException {                
         // If the search doesn't include the in-memory component, then we don't have
         // to synchronize with a flush.
         if (includeMemComponent) {
@@ -163,16 +163,16 @@
         List<Object> diskComponentSnapshot = new ArrayList<Object>();
         AtomicInteger localSearcherRefCount = null;
         synchronized (diskComponentsSync) {
-            diskComponentSnapshot.addAll(lsmTree.getDiskComponents());
+            diskComponentSnapshot.addAll(lsmIndex.getDiskComponents());
             localSearcherRefCount = searcherRefCount;
             localSearcherRefCount.incrementAndGet();         
         }
         
-        lsmTree.search(cursor, diskComponentSnapshot, pred, ctx, includeMemComponent, localSearcherRefCount);
+        lsmIndex.search(cursor, diskComponentSnapshot, pred, ctx, includeMemComponent, localSearcherRefCount);
         return diskComponentSnapshot;
     }
 
-    public void merge() throws HyracksDataException, TreeIndexException  {
+    public void merge() throws HyracksDataException, IndexException  {
         if (!isMerging.compareAndSet(false, true)) {
             throw new LSMMergeInProgressException("Merge already in progress in LSMTree. Only one concurrent merge allowed.");
         }
@@ -186,7 +186,7 @@
         AtomicInteger localSearcherRefCount = searcherRefCount;
         
         List<Object> mergedComponents = new ArrayList<Object>();
-        Object newComponent = lsmTree.merge(mergedComponents);
+        Object newComponent = lsmIndex.merge(mergedComponents);
         // No merge happened.
         if (newComponent == null) {
             isMerging.set(false);
@@ -196,7 +196,7 @@
         // Remove the old Trees from the list, and add the new merged Tree(s).
         // Also, swap the searchRefCount.
         synchronized (diskComponentsSync) {
-        	lsmTree.addMergedComponent(newComponent, mergedComponents);
+        	lsmIndex.addMergedComponent(newComponent, mergedComponents);
             // Swap the searcher ref count reference, and reset it to zero.    
         	if (searcherRefCount == searcherRefCountA) {
                 searcherRefCount = searcherRefCountB;
@@ -222,11 +222,11 @@
         // the new component permanent, and mark it as valid (usually this means
         // forcing all pages of the tree to disk, possibly with some extra
         // information to mark the tree as valid).
-        lsmTree.getComponentFinalizer().finalize(newComponent);
+        lsmIndex.getComponentFinalizer().finalize(newComponent);
         
         // Cleanup. At this point we have guaranteed that no searchers are
         // touching the old on-disk Trees (localSearcherRefCount == 0).
-        lsmTree.cleanUpAfterMerge(mergedComponents);
+        lsmIndex.cleanUpAfterMerge(mergedComponents);
         isMerging.set(false);
     }
     
@@ -236,7 +236,7 @@
         if (includeMemComponent) {
             try {
                 threadExit();
-            } catch (TreeIndexException e) {
+            } catch (IndexException e) {
                 throw new HyracksDataException(e);
             }
         }
@@ -249,9 +249,9 @@
         // the new component permanent, and mark it as valid (usually this means
         // forcing all pages of the tree to disk, possibly with some extra
         // information to mark the tree as valid).
-        lsmTree.getComponentFinalizer().finalize(index);
+        lsmIndex.getComponentFinalizer().finalize(index);
         synchronized (diskComponentsSync) {
-    		lsmTree.addFlushedComponent(index);
+    		lsmIndex.addFlushedComponent(index);
     	}
     }
 }
diff --git a/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/LSMTreeIndexAccessor.java b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/LSMTreeIndexAccessor.java
index 98cfce7..5df3c21 100644
--- a/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/LSMTreeIndexAccessor.java
+++ b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/LSMTreeIndexAccessor.java
@@ -2,14 +2,14 @@
 
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexOpContext;
 import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
-import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
-import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMTreeIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMIndexAccessor;
 
-public abstract class LSMTreeIndexAccessor implements ILSMTreeIndexAccessor {
+public abstract class LSMTreeIndexAccessor implements ILSMIndexAccessor {
 	protected LSMHarness lsmHarness;
 	protected IIndexOpContext ctx;
 
@@ -20,14 +20,14 @@
 
 	@Override
 	public void insert(ITupleReference tuple) throws HyracksDataException,
-			TreeIndexException {
+			IndexException {
 		ctx.reset(IndexOp.INSERT);
 		lsmHarness.insertUpdateOrDelete(tuple, ctx);
 	}
 
 	@Override
 	public void update(ITupleReference tuple) throws HyracksDataException,
-			TreeIndexException {
+			IndexException {
 		// Update is the same as insert.
 		ctx.reset(IndexOp.INSERT);
 		lsmHarness.insertUpdateOrDelete(tuple, ctx);
@@ -35,42 +35,25 @@
 
 	@Override
 	public void delete(ITupleReference tuple) throws HyracksDataException,
-			TreeIndexException {
+			IndexException {
 		ctx.reset(IndexOp.DELETE);
 		lsmHarness.insertUpdateOrDelete(tuple, ctx);
 	}
 	
 	@Override
-	public void search(ITreeIndexCursor cursor, ISearchPredicate searchPred)
-			throws HyracksDataException, TreeIndexException {
+	public void search(IIndexCursor cursor, ISearchPredicate searchPred)
+			throws HyracksDataException, IndexException {
 		ctx.reset(IndexOp.SEARCH);
 		lsmHarness.search(cursor, searchPred, ctx, true);
 	}
 
 	@Override
-	public ITreeIndexCursor createDiskOrderScanCursor() {
-		// Disk-order scan doesn't make sense for the LSMBTree because it cannot
-		// correctly resolve deleted tuples.
-		throw new UnsupportedOperationException(
-				"DiskOrderScan not supported by LSMTree.");
-	}
-
-	@Override
-	public void diskOrderScan(ITreeIndexCursor cursor)
-			throws HyracksDataException {
-		// Disk-order scan doesn't make sense for the LSMBTree because it cannot
-		// correctly resolve deleted tuples.
-		throw new UnsupportedOperationException(
-				"DiskOrderScan not supported by LSMTree.");
-	}
-	
-	@Override
-	public void flush() throws HyracksDataException, TreeIndexException {
+	public void flush() throws HyracksDataException, IndexException {
 		lsmHarness.flush();
 	}
 
 	@Override
-	public void merge() throws HyracksDataException, TreeIndexException {
+	public void merge() throws HyracksDataException, IndexException {
 		lsmHarness.merge();
 	}
 }
\ No newline at end of file
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java
index 38b2710..41da083 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java
@@ -30,20 +30,23 @@
 import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
 import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
 import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexBulkLoadContext;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexOpContext;
 import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
 import edu.uci.ics.hyracks.storage.am.common.api.IndexType;
 import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
 import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMComponentFinalizer;
 import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMFileManager;
-import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMTree;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMIndex;
 import edu.uci.ics.hyracks.storage.am.lsm.common.freepage.InMemoryFreePageManager;
 import edu.uci.ics.hyracks.storage.am.lsm.common.impls.BTreeFactory;
 import edu.uci.ics.hyracks.storage.am.lsm.common.impls.LSMHarness;
@@ -57,7 +60,7 @@
 import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
 import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
 
-public class LSMRTree implements ILSMTree {
+public class LSMRTree implements ILSMIndex, ITreeIndex {
 
     public class LSMRTreeComponent {
         private final RTree rtree;
@@ -337,9 +340,9 @@
         return true;
     }
 
-    public void search(ITreeIndexCursor cursor, List<Object> diskComponents, ISearchPredicate pred,
+    public void search(IIndexCursor cursor, List<Object> diskComponents, ISearchPredicate pred,
             IIndexOpContext ictx, boolean includeMemComponent, AtomicInteger searcherRefCount)
-            throws HyracksDataException, TreeIndexException {
+            throws HyracksDataException, IndexException {
         LSMRTreeOpContext ctx = (LSMRTreeOpContext) ictx;
         int numDiskTrees = diskComponents.size();
         int numTrees = (includeMemComponent) ? numDiskTrees + 1 : numDiskTrees;
@@ -371,14 +374,14 @@
     }
 
     @Override
-    public Object flush() throws HyracksDataException, TreeIndexException {
+    public Object flush() throws HyracksDataException, IndexException {
         // Renaming order is critical because we use assume ordering when we
         // read the file names when we open the tree.
         // The RTree should be renamed before the BTree.
 
         // scan the memory RTree
         ITreeIndexAccessor memRTreeAccessor = memComponent.getRTree().createAccessor();
-        ITreeIndexCursor rtreeScanCursor = memRTreeAccessor.createSearchCursor();
+        IIndexCursor rtreeScanCursor = memRTreeAccessor.createSearchCursor();
         SearchPredicate rtreeNullPredicate = new SearchPredicate(null, null);
         memRTreeAccessor.search(rtreeScanCursor, rtreeNullPredicate);
         LSMRTreeFileNameComponent fileNames = (LSMRTreeFileNameComponent) fileManager.getRelFlushFileName();
@@ -401,7 +404,7 @@
 
         // scan the memory BTree
         ITreeIndexAccessor memBTreeAccessor = memComponent.getBTree().createAccessor();
-        ITreeIndexCursor btreeScanCursor = memBTreeAccessor.createSearchCursor();
+        IIndexCursor btreeScanCursor = memBTreeAccessor.createSearchCursor();
         RangePredicate btreeNullPredicate = new RangePredicate(null, null, true, true, null, null);
         memBTreeAccessor.search(btreeScanCursor, btreeNullPredicate);
         FileReference btreeFile = fileManager.createFlushFile(fileNames.getBTreeFileName());
@@ -423,7 +426,7 @@
     }
 
     @Override
-    public Object merge(List<Object> mergedComponents) throws HyracksDataException, TreeIndexException {
+    public Object merge(List<Object> mergedComponents) throws HyracksDataException, IndexException {
         // Renaming order is critical because we use assume ordering when we
         // read the file names when we open the tree.
         // The RTree should be renamed before the BTree.
@@ -524,7 +527,7 @@
     }
 
     @Override
-    public ITreeIndexAccessor createAccessor() {
+    public IIndexAccessor createAccessor() {
         return new LSMRTreeAccessor(lsmHarness, createOpContext());
     }
 
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeSearchCursor.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeSearchCursor.java
index 3249f3d..7690909 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeSearchCursor.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeSearchCursor.java
@@ -26,7 +26,7 @@
 import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
-import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
 import edu.uci.ics.hyracks.storage.am.lsm.common.impls.LSMHarness;
 import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeInteriorFrame;
@@ -72,7 +72,7 @@
             rtreeCursors[currentCursror].reset();
             try {
                 diskRTreeAccessors[currentCursror].search(rtreeCursors[currentCursror], rtreeSearchPredicate);
-            } catch (TreeIndexException e) {
+            } catch (IndexException e) {
                 throw new HyracksDataException(e);
             }
         }
@@ -95,7 +95,7 @@
                         btreeRangePredicate.setHighKey(currentTuple, true);
                         btreeRangePredicate.setLowKey(currentTuple, true);
                         diskBTreeAccessors[i].search(btreeCursors[i], btreeRangePredicate);
-                    } catch (TreeIndexException e) {
+                    } catch (IndexException e) {
                         throw new HyracksDataException(e);
                     }
                     try {
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java
index dab5eef..cf404c8 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java
@@ -26,6 +26,7 @@
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
 import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexBulkLoadContext;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexOpContext;
 import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
@@ -34,6 +35,7 @@
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrame;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrame;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
 import edu.uci.ics.hyracks.storage.am.common.api.IndexType;
 import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
 import edu.uci.ics.hyracks.storage.am.common.frames.FrameOpSpaceStatus;
@@ -964,10 +966,10 @@
         }
 
         @Override
-        public void search(ITreeIndexCursor cursor, ISearchPredicate searchPred) throws HyracksDataException,
-                TreeIndexException {
+        public void search(IIndexCursor cursor, ISearchPredicate searchPred) throws HyracksDataException,
+                IndexException {
             ctx.reset(IndexOp.SEARCH);
-            rtree.search(cursor, searchPred, ctx);
+            rtree.search((ITreeIndexCursor) cursor, searchPred, ctx);
         }
 
         @Override
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexExamplesTest.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexExamplesTest.java
index da9d548..6230a22 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexExamplesTest.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexExamplesTest.java
@@ -91,7 +91,7 @@
         }
         ArrayTupleBuilder tb = new ArrayTupleBuilder(fieldCount);
         ArrayTupleReference tuple = new ArrayTupleReference();
-        ITreeIndexAccessor indexAccessor = treeIndex.createAccessor();
+        ITreeIndexAccessor indexAccessor = (ITreeIndexAccessor) treeIndex.createAccessor();
         int numInserts = 10000;
         for (int i = 0; i < numInserts; i++) {
             int f0 = rnd.nextInt() % numInserts;
@@ -170,7 +170,7 @@
         }
         ArrayTupleBuilder tb = new ArrayTupleBuilder(fieldCount);
         ArrayTupleReference tuple = new ArrayTupleReference();
-        ITreeIndexAccessor indexAccessor = treeIndex.createAccessor();
+        ITreeIndexAccessor indexAccessor = (ITreeIndexAccessor) treeIndex.createAccessor();
         int numInserts = 10000;
         for (int i = 0; i < 10000; i++) {
             int f0 = rnd.nextInt() % 2000;
@@ -247,7 +247,7 @@
         }
         ArrayTupleBuilder tb = new ArrayTupleBuilder(fieldCount);
         ArrayTupleReference tuple = new ArrayTupleReference();
-        ITreeIndexAccessor indexAccessor = treeIndex.createAccessor();
+        ITreeIndexAccessor indexAccessor = (ITreeIndexAccessor) treeIndex.createAccessor();
         // Max string length to be generated.
         int maxLength = 10;
         int numInserts = 10000;
@@ -322,7 +322,7 @@
 
         ArrayTupleBuilder tb = new ArrayTupleBuilder(fieldCount);
         ArrayTupleReference tuple = new ArrayTupleReference();
-        ITreeIndexAccessor indexAccessor = treeIndex.createAccessor();
+        ITreeIndexAccessor indexAccessor = (ITreeIndexAccessor) treeIndex.createAccessor();
         // Max string length to be generated.
         int runs = 3;
         for (int run = 0; run < runs; run++) {
@@ -424,7 +424,7 @@
         if (LOGGER.isLoggable(Level.INFO)) {
             LOGGER.info("Inserting into tree...");
         }
-        ITreeIndexAccessor indexAccessor = treeIndex.createAccessor();
+        ITreeIndexAccessor indexAccessor = (ITreeIndexAccessor) treeIndex.createAccessor();
         ArrayTupleBuilder tb = new ArrayTupleBuilder(fieldCount);
         ArrayTupleReference tuple = new ArrayTupleReference();
         int maxLength = 10;
@@ -527,7 +527,7 @@
             LOGGER.info(ins + " tuples loaded in " + (end - start) + "ms");
         }
 
-        ITreeIndexAccessor indexAccessor = treeIndex.createAccessor();
+        ITreeIndexAccessor indexAccessor = (ITreeIndexAccessor) treeIndex.createAccessor();
 
         // Build low key.
         ArrayTupleBuilder lowKeyTb = new ArrayTupleBuilder(1);
@@ -550,7 +550,7 @@
         if (LOGGER.isLoggable(Level.INFO)) {
             LOGGER.info("Ordered Scan:");
         }
-        ITreeIndexCursor scanCursor = indexAccessor.createSearchCursor();        
+        ITreeIndexCursor scanCursor = (ITreeIndexCursor) indexAccessor.createSearchCursor();        
         RangePredicate nullPred = new RangePredicate(null, null, true, true, null, null);
         indexAccessor.search(scanCursor, nullPred);
         try {
@@ -604,7 +604,7 @@
             String highKeyString = TupleUtils.printTuple(highKey, fieldSerdes);
             LOGGER.info("Range-Search in: [ " + lowKeyString + ", " + highKeyString + "]");
         }
-        ITreeIndexCursor rangeCursor = indexAccessor.createSearchCursor();
+        ITreeIndexCursor rangeCursor = (ITreeIndexCursor) indexAccessor.createSearchCursor();
         MultiComparator lowKeySearchCmp = BTreeUtils.getSearchMultiComparator(cmpFactories, lowKey);
         MultiComparator highKeySearchCmp = BTreeUtils.getSearchMultiComparator(cmpFactories, highKey);
         RangePredicate rangePred = new RangePredicate(lowKey, highKey, true, true, lowKeySearchCmp,
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexTestUtils.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexTestUtils.java
index 8519c02..06d14b8 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexTestUtils.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/btree/OrderedIndexTestUtils.java
@@ -27,6 +27,7 @@
 import edu.uci.ics.hyracks.storage.am.common.CheckTuple;
 import edu.uci.ics.hyracks.storage.am.common.ITreeIndexTestContext;
 import edu.uci.ics.hyracks.storage.am.common.TreeIndexTestUtils;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
@@ -89,7 +90,7 @@
         }
         MultiComparator lowKeyCmp = BTreeUtils.getSearchMultiComparator(ctx.getComparatorFactories(), lowKey);
         MultiComparator highKeyCmp = BTreeUtils.getSearchMultiComparator(ctx.getComparatorFactories(), highKey);
-        ITreeIndexCursor searchCursor = ctx.getIndexAccessor().createSearchCursor();
+        IIndexCursor searchCursor = ctx.getIndexAccessor().createSearchCursor();
         RangePredicate rangePred = new RangePredicate(lowKey, highKey, lowKeyInclusive, highKeyInclusive, lowKeyCmp,
                 highKeyCmp);
         ctx.getIndexAccessor().search(searchCursor, rangePred);
@@ -136,7 +137,7 @@
             LOGGER.info("Testing Point Searches On All Expected Keys.");
         }
         OrderedIndexTestContext ctx = (OrderedIndexTestContext) ictx;
-        ITreeIndexCursor searchCursor = ctx.getIndexAccessor().createSearchCursor();
+        IIndexCursor searchCursor = ctx.getIndexAccessor().createSearchCursor();
 
         ArrayTupleBuilder lowKeyBuilder = new ArrayTupleBuilder(ctx.getKeyFieldCount());
         ArrayTupleReference lowKey = new ArrayTupleReference();
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/AbstractTreeIndexTestWorker.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/AbstractTreeIndexTestWorker.java
index e7fee30..eca9b35 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/AbstractTreeIndexTestWorker.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/AbstractTreeIndexTestWorker.java
@@ -17,10 +17,12 @@
 
 import java.util.Random;
 
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
 import edu.uci.ics.hyracks.storage.am.common.TestOperationSelector.TestOperation;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.common.datagen.DataGenThread;
 import edu.uci.ics.hyracks.storage.am.common.datagen.TupleBatch;
 
@@ -30,7 +32,7 @@
     private final TestOperationSelector opSelector;
     private final int numBatches;
     
-    protected final ITreeIndexAccessor indexAccessor;
+    protected final IIndexAccessor indexAccessor;
     
     public AbstractTreeIndexTestWorker(DataGenThread dataGen, TestOperationSelector opSelector, ITreeIndex index, int numBatches) {
         this.dataGen = dataGen;
@@ -55,4 +57,14 @@
             e.printStackTrace();
         }
     }
+    
+    protected void consumeCursorTuples(IIndexCursor cursor) throws HyracksDataException {
+        try {
+            while (cursor.hasNext()) {
+                cursor.next();
+            }
+        } finally {
+            cursor.close();
+        }
+    }
 }
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/ITreeIndexTestWorker.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/ITreeIndexTestWorker.java
index 62d30bb..5e2733f 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/ITreeIndexTestWorker.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/ITreeIndexTestWorker.java
@@ -18,8 +18,8 @@
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
 import edu.uci.ics.hyracks.storage.am.common.TestOperationSelector.TestOperation;
-import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
 
 public interface ITreeIndexTestWorker {
-    void performOp(ITupleReference tuple, TestOperation op) throws HyracksDataException, TreeIndexException;
+    void performOp(ITupleReference tuple, TestOperation op) throws HyracksDataException, IndexException;
 }
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/TreeIndexTestContext.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/TreeIndexTestContext.java
index 934d907..0fd61c3 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/TreeIndexTestContext.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/TreeIndexTestContext.java
@@ -34,7 +34,7 @@
     public TreeIndexTestContext(ISerializerDeserializer[] fieldSerdes, ITreeIndex treeIndex) {
         this.fieldSerdes = fieldSerdes;
         this.treeIndex = treeIndex;
-        this.indexAccessor = treeIndex.createAccessor();
+        this.indexAccessor = (ITreeIndexAccessor) treeIndex.createAccessor();
         this.tupleBuilder = new ArrayTupleBuilder(fieldSerdes.length);
     }
 
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/TreeIndexTestUtils.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/TreeIndexTestUtils.java
index e02d641..447ce0d 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/TreeIndexTestUtils.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/common/TreeIndexTestUtils.java
@@ -21,6 +21,7 @@
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexBulkLoadContext;
 import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
 import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
 
 @SuppressWarnings("rawtypes")
@@ -81,7 +82,7 @@
         if (LOGGER.isLoggable(Level.INFO)) {
             LOGGER.info("Testing Scan.");
         }
-        ITreeIndexCursor scanCursor = ctx.getIndexAccessor().createSearchCursor();
+        ITreeIndexCursor scanCursor = (ITreeIndexCursor) ctx.getIndexAccessor().createSearchCursor();
         ISearchPredicate nullPred = createNullSearchPredicate();
         ctx.getIndexAccessor().search(scanCursor, nullPred);
         Iterator<CheckTuple> checkIter = ctx.getCheckTuples().iterator();
@@ -183,7 +184,7 @@
     }
 
     public static void bulkLoadCheckTuples(ITreeIndexTestContext ctx, Collection<CheckTuple> checkTuples)
-            throws HyracksDataException, TreeIndexException {
+            throws HyracksDataException, IndexException {
         int fieldCount = ctx.getFieldCount();
         int numTuples = checkTuples.size();
         ArrayTupleBuilder tupleBuilder = new ArrayTupleBuilder(fieldCount);
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeExamplesTest.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeExamplesTest.java
index 7cb946a..020194e 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeExamplesTest.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/AbstractRTreeExamplesTest.java
@@ -116,7 +116,7 @@
         }
         ArrayTupleBuilder tb = new ArrayTupleBuilder(fieldCount);
         ArrayTupleReference tuple = new ArrayTupleReference();
-        ITreeIndexAccessor indexAccessor = treeIndex.createAccessor();
+        ITreeIndexAccessor indexAccessor = (ITreeIndexAccessor) treeIndex.createAccessor();
         int numInserts = 10000;
         for (int i = 0; i < numInserts; i++) {
             int p1x = rnd.nextInt();
@@ -223,7 +223,7 @@
         }
         ArrayTupleBuilder tb = new ArrayTupleBuilder(fieldCount);
         ArrayTupleReference tuple = new ArrayTupleReference();
-        ITreeIndexAccessor indexAccessor = treeIndex.createAccessor();
+        ITreeIndexAccessor indexAccessor = (ITreeIndexAccessor) treeIndex.createAccessor();
         int numInserts = 10000;
         for (int i = 0; i < numInserts; i++) {
             double p1x = rnd.nextDouble();
@@ -318,7 +318,7 @@
 
         ArrayTupleBuilder tb = new ArrayTupleBuilder(fieldCount);
         ArrayTupleReference tuple = new ArrayTupleReference();
-        ITreeIndexAccessor indexAccessor = treeIndex.createAccessor();
+        ITreeIndexAccessor indexAccessor = (ITreeIndexAccessor) treeIndex.createAccessor();
 
         int runs = 3;
         for (int run = 0; run < runs; run++) {
@@ -477,7 +477,7 @@
             LOGGER.info(numInserts + " tuples loaded in " + (end - start) + "ms");
         }
 
-        ITreeIndexAccessor indexAccessor = treeIndex.createAccessor();
+        ITreeIndexAccessor indexAccessor = (ITreeIndexAccessor) treeIndex.createAccessor();
 
         // Build key.
         ArrayTupleBuilder keyTb = new ArrayTupleBuilder(rtreeKeyFieldCount);
@@ -493,7 +493,7 @@
         if (LOGGER.isLoggable(Level.INFO)) {
             LOGGER.info("Scan:");
         }
-        ITreeIndexCursor scanCursor = indexAccessor.createSearchCursor();
+        ITreeIndexCursor scanCursor = (ITreeIndexCursor) indexAccessor.createSearchCursor();
         SearchPredicate nullPred = new SearchPredicate(null, null);
         indexAccessor.search(scanCursor, nullPred);
         try {
@@ -546,7 +546,7 @@
             String kString = TupleUtils.printTuple(key, fieldSerdes);
             LOGGER.info("Range-Search using key: " + kString);
         }
-        ITreeIndexCursor rangeCursor = indexAccessor.createSearchCursor();
+        ITreeIndexCursor rangeCursor = (ITreeIndexCursor) indexAccessor.createSearchCursor();
         MultiComparator cmp = RTreeUtils.getSearchMultiComparator(cmpFactories, key);
         SearchPredicate rangePred = new SearchPredicate(key, cmp);
         indexAccessor.search(rangeCursor, rangePred);
diff --git a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeTestUtils.java b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeTestUtils.java
index 889318c..a23f375 100644
--- a/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeTestUtils.java
+++ b/hyracks-test-support/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeTestUtils.java
@@ -52,7 +52,7 @@
         AbstractRTreeTestContext ctx = (AbstractRTreeTestContext) ictx;
         MultiComparator cmp = RTreeUtils.getSearchMultiComparator(ctx.getComparatorFactories(), key);
 
-        ITreeIndexCursor searchCursor = ctx.getIndexAccessor().createSearchCursor();
+        ITreeIndexCursor searchCursor = (ITreeIndexCursor) ctx.getIndexAccessor().createSearchCursor();
         SearchPredicate searchPred = new SearchPredicate(key, cmp);
         ctx.getIndexAccessor().search(searchCursor, searchPred);
 
diff --git a/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/AbstractInvIndexSearchTest.java b/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/AbstractInvIndexSearchTest.java
index 4dba14a..091fb05 100644
--- a/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/AbstractInvIndexSearchTest.java
+++ b/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/AbstractInvIndexSearchTest.java
@@ -15,16 +15,13 @@
 
 package edu.uci.ics.hyracks.storage.am.invertedindex;
 
-import java.io.DataOutput;
 import java.io.File;
-import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Random;
 
 import org.junit.After;
 import org.junit.Before;
 
-import edu.uci.ics.hyracks.api.comm.IFrameTupleAccessor;
 import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
 import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
 import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
@@ -36,15 +33,14 @@
 import edu.uci.ics.hyracks.data.std.primitive.IntegerPointable;
 import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
 import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
-import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAccessor;
-import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAppender;
-import edu.uci.ics.hyracks.dataflow.common.data.accessors.FrameTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleReference;
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
 import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMLeafFrameFactory;
 import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
 import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrame;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrame;
@@ -52,9 +48,9 @@
 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.tuples.TypeAwareTupleWriterFactory;
-import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedIndexResultCursor;
+import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedListBuilder;
+import edu.uci.ics.hyracks.storage.am.invertedindex.impls.FixedSizeElementInvertedListBuilder;
 import edu.uci.ics.hyracks.storage.am.invertedindex.impls.InvertedIndex;
-import edu.uci.ics.hyracks.storage.am.invertedindex.impls.TOccurrenceSearcher;
 import edu.uci.ics.hyracks.storage.am.invertedindex.tokenizers.IBinaryTokenizer;
 import edu.uci.ics.hyracks.storage.am.invertedindex.tokenizers.ITokenFactory;
 import edu.uci.ics.hyracks.storage.am.invertedindex.util.InvertedIndexUtils;
@@ -116,41 +112,32 @@
 
     protected Random rnd = new Random();
 
-    protected ByteBuffer frame = taskCtx.allocateFrame();
-    protected FrameTupleAppender appender = new FrameTupleAppender(taskCtx.getFrameSize());
     protected ArrayTupleBuilder tb = new ArrayTupleBuilder(2);
-    protected DataOutput dos = tb.getDataOutput();
+    protected ArrayTupleReference tuple = new ArrayTupleReference();
 
     protected ISerializerDeserializer[] insertSerde = { UTF8StringSerializerDeserializer.INSTANCE,
             IntegerSerializerDeserializer.INSTANCE };
     protected RecordDescriptor insertRecDesc = new RecordDescriptor(insertSerde);
-    protected IFrameTupleAccessor accessor = new FrameTupleAccessor(taskCtx.getFrameSize(), insertRecDesc);
-
-    protected FrameTupleReference tuple = new FrameTupleReference();
 
     protected ArrayList<ArrayList<Integer>> checkInvLists = new ArrayList<ArrayList<Integer>>();
 
     protected int maxId = 1000000;
-    // protected int maxId = 1000;
     protected int[] scanCountArray = new int[maxId];
     protected ArrayList<Integer> expectedResults = new ArrayList<Integer>();
 
     protected ISerializerDeserializer[] querySerde = { UTF8StringSerializerDeserializer.INSTANCE };
     protected RecordDescriptor queryRecDesc = new RecordDescriptor(querySerde);
 
-    protected FrameTupleAppender queryAppender = new FrameTupleAppender(taskCtx.getFrameSize());
     protected ArrayTupleBuilder queryTb = new ArrayTupleBuilder(querySerde.length);
-    protected DataOutput queryDos = queryTb.getDataOutput();
-
-    protected IFrameTupleAccessor queryAccessor = new FrameTupleAccessor(taskCtx.getFrameSize(), queryRecDesc);
-    protected FrameTupleReference queryTuple = new FrameTupleReference();
+    protected ArrayTupleReference queryTuple = new ArrayTupleReference();
 
     protected ITokenFactory tokenFactory;
     protected IBinaryTokenizer tokenizer;
 
-    protected TOccurrenceSearcher searcher;
-    protected IInvertedIndexResultCursor resultCursor;
+    protected IIndexCursor resultCursor;
 
+    protected abstract void setTokenizer();
+    
     /**
      * Initialize members, generate data, and bulk load the inverted index.
      */
@@ -177,6 +164,8 @@
 
         // --- INVERTED INDEX ---
 
+        setTokenizer();
+        
         bufferCache.createFile(invListsFile);
         invListsFileId = fmp.lookupFileId(invListsFile);
         bufferCache.openFile(invListsFileId);
@@ -184,13 +173,11 @@
         invListTypeTraits[0] = IntegerPointable.TYPE_TRAITS;
         invListCmpFactories[0] = PointableBinaryComparatorFactory.of(IntegerPointable.FACTORY);
 
-        invIndex = new InvertedIndex(bufferCache, btree, invListTypeTraits, invListCmpFactories);
+        IInvertedListBuilder invListBuilder = new FixedSizeElementInvertedListBuilder(invListTypeTraits);
+        invIndex = new InvertedIndex(bufferCache, btree, invListTypeTraits, invListCmpFactories, invListBuilder, tokenizer);
         invIndex.open(invListsFileId);
 
         rnd.setSeed(50);
-
-        accessor.reset(frame);
-        queryAccessor.reset(frame);
     }
 
     @After
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 8a40a29..f0694c0 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
@@ -51,6 +51,7 @@
 import edu.uci.ics.hyracks.storage.am.btree.impls.BTreeRangeSearchCursor;
 import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
 import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexBulkLoadContext;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrame;
@@ -134,7 +135,8 @@
         IBinaryComparatorFactory[] invListCmpFactories = new IBinaryComparatorFactory[invListKeys];
         invListCmpFactories[0] = PointableBinaryComparatorFactory.of(IntegerPointable.FACTORY);
 
-        InvertedIndex invIndex = new InvertedIndex(bufferCache, btree, invListTypeTraits, invListCmpFactories);
+        IInvertedListBuilder invListBuilder = new FixedSizeElementInvertedListBuilder(invListTypeTraits);
+        InvertedIndex invIndex = new InvertedIndex(bufferCache, btree, invListTypeTraits, invListCmpFactories, invListBuilder, null);
         invIndex.open(invListsFileId);
 
         Random rnd = new Random();
@@ -172,19 +174,14 @@
         int addProb = 0;
         int addProbStep = 10;
 
-        IInvertedListBuilder invListBuilder = new FixedSizeElementInvertedListBuilder(invListTypeTraits);
-        InvertedIndex.BulkLoadContext ctx = invIndex.beginBulkLoad(invListBuilder, HYRACKS_FRAME_SIZE,
-                BTree.DEFAULT_FILL_FACTOR);
+        IIndexBulkLoadContext ctx = invIndex.beginBulkLoad(BTree.DEFAULT_FILL_FACTOR);
 
-        int totalElements = 0;
         for (int i = 0; i < tokens.size(); i++) {
 
             addProb += addProbStep * (i + 1);
             for (int j = 0; j < maxId; j++) {
                 if ((Math.abs(rnd.nextInt()) % addProb) == 0) {
 
-                    totalElements++;
-
                     tb.reset();
                     UTF8StringSerializerDeserializer.INSTANCE.serialize(tokens.get(i), dos);
                     tb.addFieldEndOffset();
@@ -199,7 +196,7 @@
                     tuple.reset(accessor, 0);
 
                     try {
-                        invIndex.bulkLoadAddTuple(ctx, tuple);
+                        invIndex.bulkLoadAddTuple(tuple, ctx);
                     } catch (Exception e) {
                         e.printStackTrace();
                     }
diff --git a/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/SearchPerfTest.java b/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/SearchPerfTest.java
index 38b8bfa..ef0a6fb 100644
--- a/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/SearchPerfTest.java
+++ b/hyracks-tests/hyracks-storage-am-invertedindex-test/src/test/java/edu/uci/ics/hyracks/storage/am/invertedindex/SearchPerfTest.java
@@ -28,13 +28,12 @@
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
 import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexBulkLoadContext;
 import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
 import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedIndexSearchModifier;
-import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedListBuilder;
-import edu.uci.ics.hyracks.storage.am.invertedindex.impls.FixedSizeElementInvertedListBuilder;
-import edu.uci.ics.hyracks.storage.am.invertedindex.impls.InvertedIndex;
+import edu.uci.ics.hyracks.storage.am.invertedindex.impls.InvertedIndex.InvertedIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.invertedindex.impls.InvertedIndexSearchPredicate;
 import edu.uci.ics.hyracks.storage.am.invertedindex.impls.OccurrenceThresholdPanicException;
-import edu.uci.ics.hyracks.storage.am.invertedindex.impls.SearchResultCursor;
 import edu.uci.ics.hyracks.storage.am.invertedindex.impls.TOccurrenceSearcher;
 import edu.uci.ics.hyracks.storage.am.invertedindex.searchmodifiers.ConjunctiveSearchModifier;
 import edu.uci.ics.hyracks.storage.am.invertedindex.searchmodifiers.JaccardSearchModifier;
@@ -54,16 +53,16 @@
 
 	protected List<String> tokens = new ArrayList<String>();
 
-	@Before
-	public void start() throws Exception {
-		super.start();
+	@Override
+	protected void setTokenizer() {
 		tokenFactory = new UTF8WordTokenFactory();
 		tokenizer = new DelimitedUTF8StringBinaryTokenizer(true, false,
 				tokenFactory);
-		searcher = new TOccurrenceSearcher(taskCtx, invIndex, tokenizer);
-		resultCursor = new SearchResultCursor(
-				searcher.createResultFrameTupleAccessor(),
-				searcher.createResultTupleReference());
+	}
+	
+	@Before
+	public void start() throws Exception {
+		super.start();
 		loadData();
 	}
 
@@ -86,37 +85,23 @@
 		int addProb = 0;
 		int addProbStep = 10;
 
-		IInvertedListBuilder invListBuilder = new FixedSizeElementInvertedListBuilder(
-				invListTypeTraits);
-		InvertedIndex.BulkLoadContext ctx = invIndex.beginBulkLoad(
-				invListBuilder, HYRACKS_FRAME_SIZE, BTree.DEFAULT_FILL_FACTOR);
+		IIndexBulkLoadContext ctx = invIndex.beginBulkLoad(BTree.DEFAULT_FILL_FACTOR);
 
-		int totalElements = 0;
 		for (int i = 0; i < tokens.size(); i++) {
 
 			addProb += addProbStep * (i + 1);
 			for (int j = 0; j < maxId; j++) {
 				if ((Math.abs(rnd.nextInt()) % addProb) == 0) {
-
-					totalElements++;
-
 					tb.reset();
 					UTF8StringSerializerDeserializer.INSTANCE.serialize(
-							tokens.get(i), dos);
+							tokens.get(i), tb.getDataOutput());
 					tb.addFieldEndOffset();
-					IntegerSerializerDeserializer.INSTANCE.serialize(j, dos);
+					IntegerSerializerDeserializer.INSTANCE.serialize(j, tb.getDataOutput());
 					tb.addFieldEndOffset();
-
+					tuple.reset(tb.getFieldEndOffsets(), tb.getByteArray());
 					checkInvLists.get(i).add(j);
-
-					appender.reset(frame, true);
-					appender.append(tb.getFieldEndOffsets(), tb.getByteArray(),
-							0, tb.getSize());
-
-					tuple.reset(accessor, 0);
-
 					try {
-						invIndex.bulkLoadAddTuple(ctx, tuple);
+						invIndex.bulkLoadAddTuple(tuple, ctx);
 					} catch (Exception e) {
 						e.printStackTrace();
 					}
@@ -169,6 +154,9 @@
 
 		rnd.setSeed(50);
 
+		InvertedIndexAccessor accessor = (InvertedIndexAccessor) invIndex.createAccessor();
+		InvertedIndexSearchPredicate searchPred = new InvertedIndexSearchPredicate(searchModifier);
+		
 		// generate random queries
 		int[] queryTokenIndexes = new int[tokens.size()];
 		for (int i = 0; i < numQueries; i++) {
@@ -181,31 +169,34 @@
 			StringBuilder strBuilder = new StringBuilder();
 			for (int j = 0; j < numQueryTokens; j++) {
 				strBuilder.append(tokens.get(queryTokenIndexes[j]));
-				if (j + 1 != numQueryTokens)
+				if (j + 1 != numQueryTokens) {
 					strBuilder.append(" ");
+				}
 			}
 
 			String queryString = strBuilder.toString();
 
+			// Serialize query.
 			queryTb.reset();
 			UTF8StringSerializerDeserializer.INSTANCE.serialize(queryString,
-					queryDos);
+					queryTb.getDataOutput());
 			queryTb.addFieldEndOffset();
+			queryTuple.reset(queryTb.getFieldEndOffsets(), queryTb.getByteArray());
 
-			queryAppender.reset(frame, true);
-			queryAppender.append(queryTb.getFieldEndOffsets(),
-					queryTb.getByteArray(), 0, queryTb.getSize());
-			queryTuple.reset(queryAccessor, 0);
-
+			// Set query tuple in search predicate.
+			searchPred.setQueryTuple(queryTuple);
+			searchPred.setQueryFieldIndex(0);
+			
 			boolean panic = false;
 
+			resultCursor = accessor.createSearchCursor();
 			int repeats = 1;
 			double totalTime = 0;
 			for (int j = 0; j < repeats; j++) {
 				long timeStart = System.currentTimeMillis();
 				try {
-					searcher.reset();
-					searcher.search(resultCursor, queryTuple, 0, searchModifier);
+					resultCursor.reset();
+					accessor.search(resultCursor, searchPred);
 				} catch (OccurrenceThresholdPanicException e) {
 					panic = true;
 				}
@@ -219,10 +210,9 @@
 			}
 
 			if (!panic) {
-
+				TOccurrenceSearcher searcher = (TOccurrenceSearcher) accessor.getSearcher();
 				fillExpectedResults(queryTokenIndexes, numQueryTokens,
 						searcher.getOccurrenceThreshold());
-
 				// verify results
 				int checkIndex = 0;
 				while (resultCursor.hasNext()) {
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 d99329f..49295d2 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
@@ -31,14 +31,12 @@
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
 import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexBulkLoadContext;
 import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
 import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedIndexSearchModifier;
-import edu.uci.ics.hyracks.storage.am.invertedindex.api.IInvertedListBuilder;
-import edu.uci.ics.hyracks.storage.am.invertedindex.impls.FixedSizeElementInvertedListBuilder;
-import edu.uci.ics.hyracks.storage.am.invertedindex.impls.InvertedIndex;
+import edu.uci.ics.hyracks.storage.am.invertedindex.impls.InvertedIndex.InvertedIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.invertedindex.impls.InvertedIndexSearchPredicate;
 import edu.uci.ics.hyracks.storage.am.invertedindex.impls.OccurrenceThresholdPanicException;
-import edu.uci.ics.hyracks.storage.am.invertedindex.impls.SearchResultCursor;
-import edu.uci.ics.hyracks.storage.am.invertedindex.impls.TOccurrenceSearcher;
 import edu.uci.ics.hyracks.storage.am.invertedindex.searchmodifiers.ConjunctiveSearchModifier;
 import edu.uci.ics.hyracks.storage.am.invertedindex.searchmodifiers.EditDistanceSearchModifier;
 import edu.uci.ics.hyracks.storage.am.invertedindex.searchmodifiers.JaccardSearchModifier;
@@ -54,6 +52,13 @@
 
 	protected IBinaryComparator[] btreeBinCmps;
 	
+	@Override
+	protected void setTokenizer() {
+		tokenFactory = new UTF8NGramTokenFactory();
+		tokenizer = new NGramUTF8StringBinaryTokenizer(3, false, true, false,
+				tokenFactory);
+	}
+	
 	@Before
 	public void start() throws Exception {
 		super.start();
@@ -61,13 +66,6 @@
 		for (int i = 0; i < btreeCmpFactories.length; i++) {
 			btreeBinCmps[i] = btreeCmpFactories[i].createBinaryComparator();
 		}
-		tokenFactory = new UTF8NGramTokenFactory();
-		tokenizer = new NGramUTF8StringBinaryTokenizer(3, false, true, false,
-				tokenFactory);
-		searcher = new TOccurrenceSearcher(taskCtx, invIndex, tokenizer);
-		resultCursor = new SearchResultCursor(
-				searcher.createResultFrameTupleAccessor(),
-				searcher.createResultTupleReference());
 		generateDataStrings();
 		loadData();
 	}
@@ -145,38 +143,28 @@
 			DataOutputStream dos = new DataOutputStream(baaos);
 			UTF8StringSerializerDeserializer.INSTANCE.serialize(s, dos);
 			tokenizer.reset(baaos.getByteArray(), 0, baaos.size());
-			int tokenCount = 0;
 			while (tokenizer.hasNext()) {
 				tokenizer.next();
 				IToken token = tokenizer.getToken();
 				pairs.add(new TokenIdPair(token, id));
-				++tokenCount;
 			}
 			++id;
 		}
 		Collections.sort(pairs);
 
 		// bulk load index
-		IInvertedListBuilder invListBuilder = new FixedSizeElementInvertedListBuilder(
-				invListTypeTraits);
-		InvertedIndex.BulkLoadContext ctx = invIndex.beginBulkLoad(
-				invListBuilder, HYRACKS_FRAME_SIZE, BTree.DEFAULT_FILL_FACTOR);
+		IIndexBulkLoadContext ctx = invIndex.beginBulkLoad(BTree.DEFAULT_FILL_FACTOR);
 
 		for (TokenIdPair t : pairs) {
 			tb.reset();
 			tb.addField(t.baaos.getByteArray(), 0,
 					t.baaos.getByteArray().length);
-			IntegerSerializerDeserializer.INSTANCE.serialize(t.id, dos);
+			IntegerSerializerDeserializer.INSTANCE.serialize(t.id, tb.getDataOutput());
 			tb.addFieldEndOffset();
-
-			appender.reset(frame, true);
-			appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0,
-					tb.getSize());
-
-			tuple.reset(accessor, 0);
+			tuple.reset(tb.getFieldEndOffsets(), tb.getByteArray());
 
 			try {
-				invIndex.bulkLoadAddTuple(ctx, tuple);
+				invIndex.bulkLoadAddTuple(tuple, ctx);
 			} catch (Exception e) {
 				e.printStackTrace();
 			}
@@ -194,28 +182,34 @@
 
 		rnd.setSeed(50);
 
+		InvertedIndexAccessor accessor = (InvertedIndexAccessor) invIndex.createAccessor();
+		InvertedIndexSearchPredicate searchPred = new InvertedIndexSearchPredicate(searchModifier);
+		
 		for (int i = 0; i < numQueries; i++) {
 
 			int queryIndex = Math.abs(rnd.nextInt() % dataStrings.size());
 			String queryString = dataStrings.get(queryIndex);
 
+			// Serialize query.
 			queryTb.reset();
 			UTF8StringSerializerDeserializer.INSTANCE.serialize(queryString,
-					queryDos);
+					queryTb.getDataOutput());
 			queryTb.addFieldEndOffset();
+			queryTuple.reset(queryTb.getFieldEndOffsets(), queryTb.getByteArray());
 
-			queryAppender.reset(frame, true);
-			queryAppender.append(queryTb.getFieldEndOffsets(),
-					queryTb.getByteArray(), 0, queryTb.getSize());
-			queryTuple.reset(queryAccessor, 0);
-
+			// Set query tuple in search predicate.
+			searchPred.setQueryTuple(queryTuple);
+			searchPred.setQueryFieldIndex(0);
+			
+			resultCursor = accessor.createSearchCursor();
+			
 			int repeats = 1;
 			double totalTime = 0;
 			for (int j = 0; j < repeats; j++) {
 				long timeStart = System.currentTimeMillis();
 				try {
-					searcher.reset();
-					searcher.search(resultCursor, queryTuple, 0, searchModifier);
+					resultCursor.reset();
+					accessor.search(resultCursor, searchPred);
 				} catch (OccurrenceThresholdPanicException e) {
 					// ignore panic queries
 				}
diff --git a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeMergeTestDriver.java b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeMergeTestDriver.java
index c4edaf8..5268de6 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeMergeTestDriver.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeMergeTestDriver.java
@@ -23,7 +23,7 @@
 import edu.uci.ics.hyracks.storage.am.btree.OrderedIndexTestDriver;
 import edu.uci.ics.hyracks.storage.am.btree.OrderedIndexTestUtils;
 import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeLeafFrameType;
-import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMTreeIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMIndexAccessor;
 
 @SuppressWarnings("rawtypes")
 public abstract class LSMBTreeMergeTestDriver extends OrderedIndexTestDriver {
@@ -60,7 +60,7 @@
                 }
             }
 
-            ILSMTreeIndexAccessor accessor = (ILSMTreeIndexAccessor) ctx.getIndexAccessor();
+            ILSMIndexAccessor accessor = (ILSMIndexAccessor) ctx.getIndexAccessor();
             accessor.merge();
 
             orderedIndexTestUtils.checkPointSearches(ctx);
diff --git a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/multithread/LSMBTreeTestWorker.java b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/multithread/LSMBTreeTestWorker.java
index 93f5d47..0cbfb64 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/multithread/LSMBTreeTestWorker.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/multithread/LSMBTreeTestWorker.java
@@ -26,9 +26,9 @@
 import edu.uci.ics.hyracks.storage.am.common.AbstractTreeIndexTestWorker;
 import edu.uci.ics.hyracks.storage.am.common.TestOperationSelector;
 import edu.uci.ics.hyracks.storage.am.common.TestOperationSelector.TestOperation;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
-import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
 import edu.uci.ics.hyracks.storage.am.common.datagen.DataGenThread;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
 import edu.uci.ics.hyracks.storage.am.lsm.btree.impls.LSMBTree;
@@ -50,9 +50,9 @@
     }
     
     @Override
-    public void performOp(ITupleReference tuple, TestOperation op) throws HyracksDataException, TreeIndexException {        
+    public void performOp(ITupleReference tuple, TestOperation op) throws HyracksDataException, IndexException {        
         LSMBTreeIndexAccessor accessor = (LSMBTreeIndexAccessor) indexAccessor;
-        ITreeIndexCursor searchCursor = accessor.createSearchCursor();
+        IIndexCursor searchCursor = accessor.createSearchCursor();
         MultiComparator cmp = accessor.getMultiComparator();
         RangePredicate rangePred = new RangePredicate(tuple, tuple, true, true, cmp, cmp);
         
@@ -122,14 +122,4 @@
                 throw new HyracksDataException("Op " + op.toString() + " not supported.");
         }
     }
-    
-    private void consumeCursorTuples(ITreeIndexCursor cursor) throws HyracksDataException {
-        try {
-            while(cursor.hasNext()) {
-                cursor.next();
-            }
-        } finally {
-            cursor.close();
-        }
-    }
 }
diff --git a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/perf/LSMTreeRunner.java b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/perf/LSMTreeRunner.java
index 275621f..a034788 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/perf/LSMTreeRunner.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/perf/LSMTreeRunner.java
@@ -24,7 +24,7 @@
 import edu.uci.ics.hyracks.api.exceptions.HyracksException;
 import edu.uci.ics.hyracks.control.nc.io.IOManager;
 import edu.uci.ics.hyracks.storage.am.btree.exceptions.BTreeException;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
 import edu.uci.ics.hyracks.storage.am.common.datagen.DataGenThread;
 import edu.uci.ics.hyracks.storage.am.common.datagen.TupleBatch;
@@ -124,7 +124,7 @@
         private final DataGenThread dataGen;
         private final LSMBTree lsmTree;
         private final int numBatches;
-        private final ITreeIndexAccessor lsmTreeAccessor;
+        private final IIndexAccessor lsmTreeAccessor;
         public LSMTreeThread(DataGenThread dataGen, LSMBTree lsmTree, int numBatches) {
             this.dataGen = dataGen;
             this.lsmTree = lsmTree;
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeMergeTestDriver.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeMergeTestDriver.java
index 3ae3c46..86204fb 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeMergeTestDriver.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeMergeTestDriver.java
@@ -20,7 +20,7 @@
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
 import edu.uci.ics.hyracks.storage.am.common.api.IPrimitiveValueProviderFactory;
-import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMTreeIndexAccessor;
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestContext;
 import edu.uci.ics.hyracks.storage.am.rtree.AbstractRTreeTestDriver;
 import edu.uci.ics.hyracks.storage.am.rtree.RTreeTestUtils;
@@ -59,7 +59,7 @@
                 }
             }
 
-            ILSMTreeIndexAccessor accessor = (ILSMTreeIndexAccessor) ctx.getIndexAccessor();
+            ILSMIndexAccessor accessor = (ILSMIndexAccessor) ctx.getIndexAccessor();
             accessor.merge();
 
             rTreeTestUtils.checkScan(ctx);
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/LSMRTreeTestWorker.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/LSMRTreeTestWorker.java
index 3565679..bcbcf71 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/LSMRTreeTestWorker.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/multithread/LSMRTreeTestWorker.java
@@ -24,7 +24,7 @@
 import edu.uci.ics.hyracks.storage.am.common.TestOperationSelector.TestOperation;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
-import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
 import edu.uci.ics.hyracks.storage.am.common.datagen.DataGenThread;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
 import edu.uci.ics.hyracks.storage.am.lsm.common.impls.LSMMergeInProgressException;
@@ -47,7 +47,7 @@
     }
 
     @Override
-    public void performOp(ITupleReference tuple, TestOperation op) throws HyracksDataException, TreeIndexException {
+    public void performOp(ITupleReference tuple, TestOperation op) throws HyracksDataException, IndexException {
         LSMRTreeAccessor accessor = (LSMRTreeAccessor) indexAccessor;
         ITreeIndexCursor searchCursor = accessor.createSearchCursor();
         MultiComparator cmp = accessor.getMultiComparator();
diff --git a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/multithread/RTreeTestWorker.java b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/multithread/RTreeTestWorker.java
index 490f03e..f5867e6 100644
--- a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/multithread/RTreeTestWorker.java
+++ b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/multithread/RTreeTestWorker.java
@@ -22,9 +22,10 @@
 import edu.uci.ics.hyracks.storage.am.common.AbstractTreeIndexTestWorker;
 import edu.uci.ics.hyracks.storage.am.common.TestOperationSelector;
 import edu.uci.ics.hyracks.storage.am.common.TestOperationSelector.TestOperation;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
-import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
 import edu.uci.ics.hyracks.storage.am.common.datagen.DataGenThread;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
 import edu.uci.ics.hyracks.storage.am.rtree.impls.RTree;
@@ -45,9 +46,9 @@
     }
 
     @Override
-    public void performOp(ITupleReference tuple, TestOperation op) throws HyracksDataException, TreeIndexException {
+    public void performOp(ITupleReference tuple, TestOperation op) throws HyracksDataException, IndexException {
         RTree.RTreeAccessor accessor = (RTree.RTreeAccessor) indexAccessor;
-        ITreeIndexCursor searchCursor = accessor.createSearchCursor();
+        IIndexCursor searchCursor = accessor.createSearchCursor();
         ITreeIndexCursor diskOrderScanCursor = accessor.createDiskOrderScanCursor();
         MultiComparator cmp = accessor.getOpContext().cmp;
         SearchPredicate rangePred = new SearchPredicate(tuple, cmp);
@@ -111,14 +112,4 @@
         }
         rearrangedTuple.reset(rearrangedTb.getFieldEndOffsets(), rearrangedTb.getByteArray());
     }
-
-    private void consumeCursorTuples(ITreeIndexCursor cursor) throws HyracksDataException {
-        try {
-            while (cursor.hasNext()) {
-                cursor.next();
-            }
-        } finally {
-            cursor.close();
-        }
-    }
 }