first pass of cleanup: removed static classes and cleaned up some bootstrapping code

git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_spring_cleaning@217 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/api/aqlj/server/APIClientThread.java b/asterix-app/src/main/java/edu/uci/ics/asterix/api/aqlj/server/APIClientThread.java
index 87e899e..bf82eb4 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/api/aqlj/server/APIClientThread.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/api/aqlj/server/APIClientThread.java
@@ -38,7 +38,7 @@
 import edu.uci.ics.asterix.aql.parser.AQLParser;
 import edu.uci.ics.asterix.aql.parser.ParseException;
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
-import edu.uci.ics.asterix.hyracks.bootstrap.AsterixNodeState;
+import edu.uci.ics.asterix.hyracks.bootstrap.APINodeState;
 import edu.uci.ics.asterix.metadata.MetadataManager;
 import edu.uci.ics.asterix.metadata.api.IAsterixStateProxy;
 import edu.uci.ics.asterix.metadata.bootstrap.AsterixProperties;
@@ -93,7 +93,7 @@
 
         // get the port of the node data server that is running on the first nc
         IAsterixStateProxy proxy = (IAsterixStateProxy) appCtx.getDistributedState();
-        nodeDataServerPort = ((AsterixNodeState) proxy.getAsterixNodeState(outputNodeName)).getAPINodeDataServerPort();
+        nodeDataServerPort = ((APINodeState) proxy.getAsterixNodeState(outputNodeName)).getAPINodeDataServerPort();
         nodeDataServerStream = null;
 
         // write the data into the output stores directory of the nc
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/AsterixNodeState.java b/asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/APINodeState.java
similarity index 94%
rename from asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/AsterixNodeState.java
rename to asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/APINodeState.java
index dbf1625..0d8981e 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/AsterixNodeState.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/APINodeState.java
@@ -16,7 +16,7 @@
 
 import java.io.Serializable;
 
-public class AsterixNodeState implements Serializable {
+public class APINodeState implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/CCBootstrapImpl.java b/asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/CCBootstrapImpl.java
index c6d38d3..273b6f2 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/CCBootstrapImpl.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/CCBootstrapImpl.java
@@ -80,7 +80,7 @@
             Set<String> nodeNames = entry.getValue();
             Iterator<String> it = nodeNames.iterator();
             while (it.hasNext()) {
-                AsterixNodeState ns = new AsterixNodeState();
+                APINodeState ns = new APINodeState();
                 ns.setAPINodeDataServerPort(startPort);
                 proxy.setAsterixNodeState(it.next(), ns);
                 startPort++;
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/NCBootstrapImpl.java b/asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/NCBootstrapImpl.java
index 7cdca49..d469dd0 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/NCBootstrapImpl.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/NCBootstrapImpl.java
@@ -15,20 +15,20 @@
 package edu.uci.ics.asterix.hyracks.bootstrap;
 
 import java.rmi.server.UnicastRemoteObject;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import edu.uci.ics.asterix.api.aqlj.server.NodeDataClientThreadFactory;
 import edu.uci.ics.asterix.api.aqlj.server.ThreadedServer;
-import edu.uci.ics.asterix.common.api.AsterixAppContextInfoImpl;
-import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.common.api.INodeApplicationState;
 import edu.uci.ics.asterix.common.context.AsterixAppRuntimeContext;
+import edu.uci.ics.asterix.common.context.NodeApplicationState;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
 import edu.uci.ics.asterix.metadata.MetadataManager;
 import edu.uci.ics.asterix.metadata.MetadataNode;
 import edu.uci.ics.asterix.metadata.api.IAsterixStateProxy;
 import edu.uci.ics.asterix.metadata.api.IMetadataNode;
-import edu.uci.ics.asterix.metadata.bootstrap.AsterixProperties;
 import edu.uci.ics.asterix.metadata.bootstrap.MetadataBootstrap;
-import edu.uci.ics.asterix.transaction.management.exception.ACIDException;
 import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionProvider;
 import edu.uci.ics.hyracks.api.application.INCApplicationContext;
 import edu.uci.ics.hyracks.api.application.INCBootstrap;
@@ -36,81 +36,90 @@
 public class NCBootstrapImpl implements INCBootstrap {
     private static final Logger LOGGER = Logger.getLogger(NCBootstrapImpl.class.getName());
 
-    public static final int DEFAULT_AQLJ_NODE_DATA_SERVER_PORT = 6061;
-
-    private INCApplicationContext ncAppContext = null;
-
-    private static IMetadataNode metadataNode;
+    private final INodeApplicationState applicationState = new NodeApplicationState();
+    
+    private INCApplicationContext ncApplicationContext = null;
     private String nodeId;
-
+    private boolean isMetadataNode = false;
     private ThreadedServer apiNodeDataServer;
 
     @Override
     public void start() throws Exception {
+        ncApplicationContext.setApplicationObject(applicationState);
+        nodeId = ncApplicationContext.getNodeId();
 
-        LOGGER.info("Starting Asterix NC " + nodeId + " Bootstrap");
-        IAsterixStateProxy p = (IAsterixStateProxy) ncAppContext.getDistributedState();
-        LOGGER.info("\nMetadata node " + p.getAsterixProperties().getMetadataNodeName());
-        initializeTransactionSupport(ncAppContext, nodeId);
-        if (nodeId.equals(p.getAsterixProperties().getMetadataNodeName())) {
-            AsterixAppRuntimeContext.initialize(ncAppContext);
-            LOGGER.info("Initialized AsterixRuntimeContext: " + AsterixAppRuntimeContext.getInstance());
-            metadataNode = registerRemoteObject(ncAppContext, p.getAsterixProperties());
-            p.setMetadataNode(metadataNode);
-            MetadataManager.INSTANCE = new MetadataManager(p);
-            LOGGER.info("Bootstrapping Metadata");
-            MetadataManager.INSTANCE.init();
-            MetadataBootstrap.startUniverse(p.getAsterixProperties(), AsterixAppContextInfoImpl.INSTANCE);
-        } else {
-            Thread.sleep(5000);
-            AsterixAppRuntimeContext.initialize(ncAppContext);
-            LOGGER.info("Initialized AsterixRuntimeContext: " + AsterixAppRuntimeContext.getInstance());
+        if (LOGGER.isLoggable(Level.INFO)) {
+            LOGGER.info("Starting Asterix node controller: " + nodeId);
         }
 
-        IAsterixStateProxy proxy = (IAsterixStateProxy) ncAppContext.getDistributedState();
-        AsterixNodeState ns = (AsterixNodeState) proxy.getAsterixNodeState(ncAppContext.getNodeId());
+        // Check if this node is the metadata node
+        IAsterixStateProxy proxy = (IAsterixStateProxy) ncApplicationContext.getDistributedState();
+        isMetadataNode = nodeId.equals(proxy.getAsterixProperties().getMetadataNodeName());
+
+        // Initialize the runtime context
+        AsterixAppRuntimeContext runtimeContext = new AsterixAppRuntimeContext(ncApplicationContext);
+        applicationState.setApplicationRuntimeContext(runtimeContext);
+        runtimeContext.initialize();
+
+        // Initialize the transaction sub-system
+        TransactionProvider provider = new TransactionProvider(nodeId);
+        applicationState.setTransactionProvider(provider);
+
+        // Initialize metadata if this node is the metadata node
+        if (isMetadataNode) {
+            registerRemoteMetadataNode(proxy);
+
+            if (LOGGER.isLoggable(Level.INFO)) {
+                LOGGER.info("Bootstrapping metadata");
+            }
+
+            MetadataManager.INSTANCE = new MetadataManager(proxy);
+            MetadataManager.INSTANCE.init();
+            MetadataBootstrap.startUniverse(proxy.getAsterixProperties(), ncApplicationContext);
+
+        }
+
+        // Start a sub-component for the API server. This server is only connected to by the 
+        // API server that lives on the CC and never by a client wishing to execute AQL.
+        // TODO: The API sub-system will change dramatically in the future and this code will go away, 
+        // but leave it for now.
+        APINodeState ns = (APINodeState) proxy.getAsterixNodeState(nodeId);
         apiNodeDataServer = new ThreadedServer(ns.getAPINodeDataServerPort(), new NodeDataClientThreadFactory());
         apiNodeDataServer.start();
     }
 
-    public static IMetadataNode registerRemoteObject(INCApplicationContext ncAppContext,
-            AsterixProperties asterixProperties) throws AsterixException {
+    public void registerRemoteMetadataNode(IAsterixStateProxy proxy) throws Exception {
+        IMetadataNode stub = null;
         try {
-            TransactionProvider factory = (TransactionProvider) ncAppContext.getApplicationObject();
-            MetadataNode.INSTANCE = new MetadataNode(asterixProperties, AsterixAppContextInfoImpl.INSTANCE, factory);
-            IMetadataNode stub = (IMetadataNode) UnicastRemoteObject.exportObject(MetadataNode.INSTANCE, 0);
-            LOGGER.info("MetadataNode bound.");
-            return stub;
+            MetadataNode.INSTANCE = new MetadataNode(applicationState);
+            stub = (IMetadataNode) UnicastRemoteObject.exportObject(MetadataNode.INSTANCE, 0);
         } catch (Exception e) {
-            LOGGER.info("MetadataNode exception.");
             throw new AsterixException(e);
         }
+        proxy.setMetadataNode(stub);
+
+        if (LOGGER.isLoggable(Level.INFO)) {
+            LOGGER.info("Metadata node bound");
+        }
     }
 
     @Override
     public void stop() throws Exception {
-        LOGGER.info("Stopping Asterix NC Bootstrap");
-        IAsterixStateProxy p = (IAsterixStateProxy) ncAppContext.getDistributedState();
-        if (nodeId.equals(p.getAsterixProperties().getMetadataNodeName())) {
+        if (LOGGER.isLoggable(Level.INFO)) {
+            LOGGER.info("Stopping Asterix node controller: " + nodeId);
+        }
+
+        // Quiesce metadata
+        if (isMetadataNode) {
             MetadataBootstrap.stopUniverse();
         }
-        AsterixAppRuntimeContext.deinitialize();
+
         apiNodeDataServer.shutdown();
+        applicationState.getApplicationRuntimeContext().deinitialize();
     }
 
     @Override
     public void setApplicationContext(INCApplicationContext appCtx) {
-        this.ncAppContext = appCtx;
-        this.nodeId = ncAppContext.getNodeId();
-    }
-
-    private void initializeTransactionSupport(INCApplicationContext ncAppContext, String nodeId) {
-        try {
-            TransactionProvider factory = new TransactionProvider(nodeId);
-            ncAppContext.setApplicationObject(factory);
-        } catch (ACIDException e) {
-            e.printStackTrace();
-            LOGGER.severe(" Could not initialize transaction support ");
-        }
+        this.ncApplicationContext = appCtx;
     }
 }
\ No newline at end of file
diff --git a/asterix-common/pom.xml b/asterix-common/pom.xml
index 34a73c9..facca1c 100644
--- a/asterix-common/pom.xml
+++ b/asterix-common/pom.xml
@@ -33,6 +33,13 @@
 			<artifactId>hyracks-dataflow-std</artifactId>
 			<version>0.2.1-SNAPSHOT</version>
 		</dependency>
+		<dependency>
+			<groupId>edu.uci.ics.asterix</groupId>
+			<artifactId>asterix-transactions</artifactId>
+			<version>0.0.4-SNAPSHOT</version>
+			<type>jar</type>
+			<scope>compile</scope>
+		</dependency>
 	</dependencies>
 
 </project>
diff --git a/asterix-common/src/main/java/edu/uci/ics/asterix/common/api/INodeApplicationState.java b/asterix-common/src/main/java/edu/uci/ics/asterix/common/api/INodeApplicationState.java
new file mode 100644
index 0000000..d1d1a43
--- /dev/null
+++ b/asterix-common/src/main/java/edu/uci/ics/asterix/common/api/INodeApplicationState.java
@@ -0,0 +1,14 @@
+package edu.uci.ics.asterix.common.api;
+
+import edu.uci.ics.asterix.common.context.AsterixAppRuntimeContext;
+import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionProvider;
+
+public interface INodeApplicationState {
+    public AsterixAppRuntimeContext getApplicationRuntimeContext();
+    
+    public void setApplicationRuntimeContext(AsterixAppRuntimeContext context);
+    
+    public TransactionProvider getTransactionProvider();
+    
+    public void setTransactionProvider(TransactionProvider provider);
+}
diff --git a/asterix-common/src/main/java/edu/uci/ics/asterix/common/context/AsterixAppRuntimeContext.java b/asterix-common/src/main/java/edu/uci/ics/asterix/common/context/AsterixAppRuntimeContext.java
index 949855f..3f07e5b 100644
--- a/asterix-common/src/main/java/edu/uci/ics/asterix/common/context/AsterixAppRuntimeContext.java
+++ b/asterix-common/src/main/java/edu/uci/ics/asterix/common/context/AsterixAppRuntimeContext.java
@@ -1,12 +1,9 @@
 package edu.uci.ics.asterix.common.context;
 
 import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.logging.Logger;
+import java.util.logging.Level;
 
 import edu.uci.ics.asterix.common.config.GlobalConfig;
-import edu.uci.ics.asterix.common.exceptions.AsterixRuntimeException;
 import edu.uci.ics.hyracks.api.application.INCApplicationContext;
 import edu.uci.ics.hyracks.api.io.IIOManager;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndex;
@@ -21,90 +18,78 @@
 import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
 
 public class AsterixAppRuntimeContext {
-    private static AsterixAppRuntimeContext INSTANCE;
-
-    private IndexRegistry<IIndex> treeRegistry;
-    private IBufferCache bufferCache;
+    private INCApplicationContext ncApplicationContext;
+    private IndexRegistry<IIndex> indexRegistry;
     private IFileMapManager fileMapManager;
-    private INCApplicationContext ncAppContext;
+    private IBufferCache bufferCache;
 
-    private static Logger LOGGER = Logger.getLogger(AsterixAppRuntimeContext.class.getName());
-
-    private AsterixAppRuntimeContext() {
+    public AsterixAppRuntimeContext(INCApplicationContext ncAppContext) {
+        this.ncApplicationContext = ncAppContext;
     }
 
-    public static void initialize(INCApplicationContext ncAppContext) throws IOException {
-        if (INSTANCE != null) {
-            LOGGER.info("Asterix instance already initialized");
-            return;
-        }
+    public void initialize() throws IOException {
+        int pageSize = getBufferCachePageSize();
+        int cacheSize = getBufferCacheSize();
 
-        INSTANCE = new AsterixAppRuntimeContext();
-        INSTANCE.ncAppContext = ncAppContext;
-        INSTANCE.start();
-    }
-
-    public static void deinitialize() {
-        if (INSTANCE != null) {
-            INSTANCE.stop();
-            INSTANCE = null;
-        }
-    }
-
-    private void stop() {
-        bufferCache.close();
-    }
-
-    private void start() throws IOException {
+        // Initialize file map manager
         fileMapManager = new AsterixFileMapManager();
+
+        // Initialize the buffer cache
         ICacheMemoryAllocator allocator = new HeapBufferAllocator();
         IPageReplacementStrategy prs = new ClockPageReplacementStrategy();
-        if (ncAppContext == null) {
-            throw new AsterixRuntimeException("NC Application Context has not been set.");
-        }
-        IIOManager ioMgr = ncAppContext.getRootContext().getIOManager();
-        String pgsizeStr = System.getProperty(GlobalConfig.BUFFER_CACHE_PAGE_SIZE_PROPERTY);
-        int pgSize = -1;
-        if (pgsizeStr != null) {
-            try {
-                pgSize = Integer.parseInt(pgsizeStr);
-            } catch (NumberFormatException nfe) {
-                StringWriter sw = new StringWriter();
-                nfe.printStackTrace(new PrintWriter(sw, true));
-                sw.close();
-                GlobalConfig.ASTERIX_LOGGER.warning("Wrong buffer cache page size argument. Picking frame size ("
-                        + ncAppContext.getRootContext().getFrameSize() + ") instead. \n" + sw.toString() + "\n");
-            }
-        }
-        if (pgSize < 0) {
-            // by default, pick the frame size
-            pgSize = ncAppContext.getRootContext().getFrameSize();
-        }
+        IIOManager ioMgr = ncApplicationContext.getRootContext().getIOManager();
+        bufferCache = new BufferCache(ioMgr, allocator, prs, fileMapManager, pageSize, cacheSize, Integer.MAX_VALUE);
 
-        int cacheSize = GlobalConfig.DEFAULT_BUFFER_CACHE_SIZE;
-        String cacheSizeStr = System.getProperty(GlobalConfig.BUFFER_CACHE_SIZE_PROPERTY);
-        if (cacheSizeStr != null) {
-            int cs = -1;
-            try {
-                cs = Integer.parseInt(cacheSizeStr);
-            } catch (NumberFormatException nfe) {
-                StringWriter sw = new StringWriter();
-                nfe.printStackTrace(new PrintWriter(sw, true));
-                sw.close();
-                GlobalConfig.ASTERIX_LOGGER.warning("Wrong buffer cache size argument. Picking default value ("
-                        + GlobalConfig.DEFAULT_BUFFER_CACHE_SIZE + ") instead.\n");
-            }
-            if (cs >= 0) {
-                cacheSize = cs;
-            }
-        }
-        System.out.println("BC :" + pgSize + " cache " + cacheSize);
-        bufferCache = new BufferCache(ioMgr, allocator, prs, fileMapManager, pgSize, cacheSize, Integer.MAX_VALUE);
-        treeRegistry = new IndexRegistry<IIndex>();
+        // Initialize the index registry
+        indexRegistry = new IndexRegistry<IIndex>();
     }
 
-    public static AsterixAppRuntimeContext getInstance() {
-        return INSTANCE;
+    private int getBufferCachePageSize() {
+        int pageSize = ncApplicationContext.getRootContext().getFrameSize();
+        String pageSizeStr = System.getProperty(GlobalConfig.BUFFER_CACHE_PAGE_SIZE_PROPERTY, null);
+        if (pageSizeStr != null) {
+            try {
+                pageSize = Integer.parseInt(pageSizeStr);
+            } catch (NumberFormatException nfe) {
+                if (GlobalConfig.ASTERIX_LOGGER.isLoggable(Level.WARNING)) {
+                    GlobalConfig.ASTERIX_LOGGER.warning("Wrong buffer cache page size argument. "
+                            + "Using default value: " + pageSize);
+                }
+                return pageSize;
+            }
+        }
+
+        if (GlobalConfig.ASTERIX_LOGGER.isLoggable(Level.INFO)) {
+            GlobalConfig.ASTERIX_LOGGER.info("Buffer cache page size: " + pageSize);
+        }
+
+        return pageSize;
+    }
+
+    private int getBufferCacheSize() {
+        int cacheSize = GlobalConfig.DEFAULT_BUFFER_CACHE_SIZE;
+        String cacheSizeStr = System.getProperty(GlobalConfig.BUFFER_CACHE_SIZE_PROPERTY, null);
+        if (cacheSizeStr != null) {
+            try {
+                cacheSize = Integer.parseInt(cacheSizeStr);
+            } catch (NumberFormatException nfe) {
+                if (GlobalConfig.ASTERIX_LOGGER.isLoggable(Level.WARNING)) {
+                    GlobalConfig.ASTERIX_LOGGER.warning("Wrong buffer cache size argument. " + "Using default value: "
+                            + cacheSize);
+                }
+                return cacheSize;
+            }
+        }
+
+        if (GlobalConfig.ASTERIX_LOGGER.isLoggable(Level.INFO)) {
+            GlobalConfig.ASTERIX_LOGGER.info("Buffer cache size: " + cacheSize);
+        }
+
+        return cacheSize;
+    }
+
+    public void deinitialize() {
+        bufferCache.close();
     }
 
     public IBufferCache getBufferCache() {
@@ -115,8 +100,8 @@
         return fileMapManager;
     }
 
-    public IndexRegistry<IIndex> getTreeRegistry() {
-        return treeRegistry;
+    public IndexRegistry<IIndex> getIndexRegistry() {
+        return indexRegistry;
     }
 
 }
\ No newline at end of file
diff --git a/asterix-common/src/main/java/edu/uci/ics/asterix/common/context/AsterixStorageManagerInterface.java b/asterix-common/src/main/java/edu/uci/ics/asterix/common/context/AsterixStorageManagerInterface.java
index 67b785e..befcfe8 100644
--- a/asterix-common/src/main/java/edu/uci/ics/asterix/common/context/AsterixStorageManagerInterface.java
+++ b/asterix-common/src/main/java/edu/uci/ics/asterix/common/context/AsterixStorageManagerInterface.java
@@ -1,5 +1,6 @@
 package edu.uci.ics.asterix.common.context;
 
+import edu.uci.ics.asterix.common.api.INodeApplicationState;
 import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
@@ -12,11 +13,15 @@
 
     @Override
     public IBufferCache getBufferCache(IHyracksTaskContext ctx) {
-        return AsterixAppRuntimeContext.getInstance().getBufferCache();
+        INodeApplicationState applicationState = (INodeApplicationState) ctx.getJobletContext().getApplicationContext()
+                .getApplicationObject();
+        return applicationState.getApplicationRuntimeContext().getBufferCache();
     }
 
     @Override
     public IFileMapProvider getFileMapProvider(IHyracksTaskContext ctx) {
-        return AsterixAppRuntimeContext.getInstance().getFileMapManager();
+        INodeApplicationState applicationState = (INodeApplicationState) ctx.getJobletContext().getApplicationContext()
+                .getApplicationObject();
+        return applicationState.getApplicationRuntimeContext().getFileMapManager();
     }
 }
diff --git a/asterix-common/src/main/java/edu/uci/ics/asterix/common/context/AsterixTreeRegistryProvider.java b/asterix-common/src/main/java/edu/uci/ics/asterix/common/context/AsterixTreeRegistryProvider.java
index 3f542ec..9055c4a 100644
--- a/asterix-common/src/main/java/edu/uci/ics/asterix/common/context/AsterixTreeRegistryProvider.java
+++ b/asterix-common/src/main/java/edu/uci/ics/asterix/common/context/AsterixTreeRegistryProvider.java
@@ -1,5 +1,6 @@
 package edu.uci.ics.asterix.common.context;
 
+import edu.uci.ics.asterix.common.api.INodeApplicationState;
 import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndex;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexRegistryProvider;
@@ -16,7 +17,9 @@
 
     @Override
     public IndexRegistry<IIndex> getRegistry(IHyracksTaskContext ctx) {
-        return AsterixAppRuntimeContext.getInstance().getTreeRegistry();
+        INodeApplicationState applicationState = (INodeApplicationState) ctx.getJobletContext().getApplicationContext()
+                .getApplicationObject();
+        return applicationState.getApplicationRuntimeContext().getIndexRegistry();
     }
 
 }
diff --git a/asterix-common/src/main/java/edu/uci/ics/asterix/common/context/NodeApplicationState.java b/asterix-common/src/main/java/edu/uci/ics/asterix/common/context/NodeApplicationState.java
new file mode 100644
index 0000000..c5cf752
--- /dev/null
+++ b/asterix-common/src/main/java/edu/uci/ics/asterix/common/context/NodeApplicationState.java
@@ -0,0 +1,31 @@
+package edu.uci.ics.asterix.common.context;
+
+import edu.uci.ics.asterix.common.api.INodeApplicationState;
+import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionProvider;
+
+public class NodeApplicationState implements INodeApplicationState {
+
+    private AsterixAppRuntimeContext appRuntimeContext;
+    private TransactionProvider provider;
+    
+    @Override
+    public AsterixAppRuntimeContext getApplicationRuntimeContext() {
+        return appRuntimeContext;
+    }
+
+    @Override
+    public void setApplicationRuntimeContext(AsterixAppRuntimeContext context) {
+        this.appRuntimeContext = context;
+    }
+
+    @Override
+    public TransactionProvider getTransactionProvider() {
+        return provider;
+    }
+
+    @Override
+    public void setTransactionProvider(TransactionProvider provider) {
+        this.provider = provider;
+    }
+
+}
diff --git a/asterix-hyracks-glue/pom.xml b/asterix-hyracks-glue/pom.xml
index 012d8f6..416ae58 100644
--- a/asterix-hyracks-glue/pom.xml
+++ b/asterix-hyracks-glue/pom.xml
@@ -42,6 +42,13 @@
        <artifactId>hyracks-storage-am-btree</artifactId>
        <version>0.2.1-SNAPSHOT</version>
     </dependency>
+    <dependency>
+    	<groupId>edu.uci.ics.asterix</groupId>
+    	<artifactId>asterix-common</artifactId>
+    	<version>0.0.4-SNAPSHOT</version>
+    	<type>jar</type>
+    	<scope>compile</scope>
+    </dependency>
   </dependencies>
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
diff --git a/asterix-hyracks-glue/src/main/java/edu/uci/ics/asterix/runtime/transaction/TreeIndexInsertUpdateDeleteOperatorDescriptor.java b/asterix-hyracks-glue/src/main/java/edu/uci/ics/asterix/runtime/transaction/TreeIndexInsertUpdateDeleteOperatorDescriptor.java
index 1b6daec..ffc9a9a 100644
--- a/asterix-hyracks-glue/src/main/java/edu/uci/ics/asterix/runtime/transaction/TreeIndexInsertUpdateDeleteOperatorDescriptor.java
+++ b/asterix-hyracks-glue/src/main/java/edu/uci/ics/asterix/runtime/transaction/TreeIndexInsertUpdateDeleteOperatorDescriptor.java
@@ -15,6 +15,7 @@
 
 package edu.uci.ics.asterix.runtime.transaction;
 
+import edu.uci.ics.asterix.common.api.INodeApplicationState;
 import edu.uci.ics.asterix.transaction.management.exception.ACIDException;
 import edu.uci.ics.asterix.transaction.management.service.transaction.ITransactionManager;
 import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionContext;
@@ -35,23 +36,22 @@
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
 import edu.uci.ics.hyracks.storage.common.IStorageManagerInterface;
 
-public class TreeIndexInsertUpdateDeleteOperatorDescriptor extends
-		AbstractTreeIndexOperatorDescriptor {
+public class TreeIndexInsertUpdateDeleteOperatorDescriptor extends AbstractTreeIndexOperatorDescriptor {
 
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
-	private final int[] fieldPermutation;
+    private final int[] fieldPermutation;
 
-	private final IndexOp op;
+    private final IndexOp op;
 
-	private final long transactionId;
-
+    private final long transactionId;
 
     public TreeIndexInsertUpdateDeleteOperatorDescriptor(JobSpecification spec, RecordDescriptor recDesc,
             IStorageManagerInterface storageManager, IIndexRegistryProvider<IIndex> indexRegistryProvider,
             IFileSplitProvider fileSplitProvider, ITypeTraits[] typeTraits,
             IBinaryComparatorFactory[] comparatorFactories, int[] fieldPermutation, IndexOp op,
-            IIndexDataflowHelperFactory dataflowHelperFactory, IOperationCallbackProvider opCallbackProvider, long transactionId) {
+            IIndexDataflowHelperFactory dataflowHelperFactory, IOperationCallbackProvider opCallbackProvider,
+            long transactionId) {
         super(spec, 1, 1, recDesc, storageManager, indexRegistryProvider, fileSplitProvider, typeTraits,
                 comparatorFactories, dataflowHelperFactory, opCallbackProvider);
         this.fieldPermutation = fieldPermutation;
@@ -59,24 +59,19 @@
         this.transactionId = transactionId;
     }
 
-	@Override
-	public IOperatorNodePushable createPushRuntime(IHyracksTaskContext ctx,
-			IRecordDescriptorProvider recordDescProvider, int partition,
-			int nPartitions) {
-		TransactionContext txnContext;
-		try {
-			ITransactionManager transactionManager = ((TransactionProvider) (ctx
-					.getJobletContext().getApplicationContext()
-					.getApplicationObject())).getTransactionManager();
-			txnContext = transactionManager
-					.getTransactionContext(transactionId);
-		} catch (ACIDException ae) {
-			throw new RuntimeException(
-					" could not obtain context for invalid transaction id "
-							+ transactionId);
-		}
-		return new TreeIndexInsertUpdateDeleteOperatorNodePushable(txnContext, this, ctx, opCallbackProvider, partition,
-                fieldPermutation, recordDescProvider, op);
-	}
-
+    @Override
+    public IOperatorNodePushable createPushRuntime(IHyracksTaskContext ctx,
+            IRecordDescriptorProvider recordDescProvider, int partition, int nPartitions) {
+        TransactionContext txnContext;
+        try {
+            INodeApplicationState applicationState = (INodeApplicationState) ctx.getJobletContext()
+                    .getApplicationContext().getApplicationObject();
+            ITransactionManager transactionManager = applicationState.getTransactionProvider().getTransactionManager();
+            txnContext = transactionManager.getTransactionContext(transactionId);
+        } catch (ACIDException ae) {
+            throw new RuntimeException(" could not obtain context for invalid transaction id " + transactionId);
+        }
+        return new TreeIndexInsertUpdateDeleteOperatorNodePushable(txnContext, this, ctx, opCallbackProvider,
+                partition, fieldPermutation, recordDescProvider, op);
+    }
 }
diff --git a/asterix-hyracks-glue/src/main/java/edu/uci/ics/asterix/runtime/transaction/TreeIndexInsertUpdateDeleteOperatorNodePushable.java b/asterix-hyracks-glue/src/main/java/edu/uci/ics/asterix/runtime/transaction/TreeIndexInsertUpdateDeleteOperatorNodePushable.java
index 3af5e91..2d03101 100644
--- a/asterix-hyracks-glue/src/main/java/edu/uci/ics/asterix/runtime/transaction/TreeIndexInsertUpdateDeleteOperatorNodePushable.java
+++ b/asterix-hyracks-glue/src/main/java/edu/uci/ics/asterix/runtime/transaction/TreeIndexInsertUpdateDeleteOperatorNodePushable.java
@@ -16,11 +16,15 @@
 
 import java.nio.ByteBuffer;
 
+import edu.uci.ics.asterix.common.api.INodeApplicationState;
 import edu.uci.ics.asterix.transaction.management.exception.ACIDException;
 import edu.uci.ics.asterix.transaction.management.resource.ICloseable;
 import edu.uci.ics.asterix.transaction.management.resource.TransactionalResourceRepository;
 import edu.uci.ics.asterix.transaction.management.service.locking.ILockManager;
 import edu.uci.ics.asterix.transaction.management.service.logging.DataUtil;
+import edu.uci.ics.asterix.transaction.management.service.logging.TreeLogger;
+import edu.uci.ics.asterix.transaction.management.service.logging.TreeResourceManager;
+import edu.uci.ics.asterix.transaction.management.service.transaction.IResourceManager;
 import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionContext;
 import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionManagementConstants;
 import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionProvider;
@@ -53,9 +57,10 @@
     private TreeLogger bTreeLogger;
     private final TransactionProvider transactionProvider;
 
-    public TreeIndexInsertUpdateDeleteOperatorNodePushable(TransactionContext txnContext, AbstractTreeIndexOperatorDescriptor opDesc,
-            IHyracksTaskContext ctx, IOperationCallbackProvider opCallbackProvider, int partition,
-            int[] fieldPermutation, IRecordDescriptorProvider recordDescProvider, IndexOp op) {
+    public TreeIndexInsertUpdateDeleteOperatorNodePushable(TransactionContext txnContext,
+            AbstractTreeIndexOperatorDescriptor opDesc, IHyracksTaskContext ctx,
+            IOperationCallbackProvider opCallbackProvider, int partition, int[] fieldPermutation,
+            IRecordDescriptorProvider recordDescProvider, IndexOp op) {
         boolean createIfNotExists = (op == IndexOp.INSERT);
         treeIndexHelper = (TreeIndexDataflowHelper) opDesc.getIndexDataflowHelperFactory().createIndexDataflowHelper(
                 opDesc, ctx, opCallbackProvider, partition, createIfNotExists);
@@ -63,21 +68,26 @@
         this.op = op;
         tuple.setFieldPermutation(fieldPermutation);
         this.txnContext = txnContext;
-        transactionProvider = (TransactionProvider) ctx.getJobletContext().getApplicationContext()
+        INodeApplicationState applicationState = (INodeApplicationState) ctx.getJobletContext().getApplicationContext()
                 .getApplicationObject();
-    }
-    
-    public void initializeTransactionSupport() {
-        TransactionalResourceRepository.registerTransactionalResourceManager(TreeResourceManager.ID,
-                TreeResourceManager.getInstance());
-        int fileId = treeIndexHelper.getIndexFileId();
-        byte[] resourceId = DataUtil.intToByteArray(fileId);
-        TransactionalResourceRepository.registerTransactionalResource(resourceId, treeIndexHelper.getIndex());
-        lockManager = transactionProvider.getLockManager();
-        bTreeLogger = TreeLoggerRepository.getTreeLogger(resourceId);
+        transactionProvider = applicationState.getTransactionProvider();
     }
 
-    
+    public void initializeTransactionSupport() {
+        TransactionalResourceRepository resourceRepository = transactionProvider.getTransactionalResourceRepository();
+        IResourceManager resourceMgr = resourceRepository.getTransactionalResourceMgr(TreeResourceManager.ID);
+        if (resourceMgr == null) {
+            resourceRepository.registerTransactionalResourceManager(TreeResourceManager.ID, new TreeResourceManager(
+                    transactionProvider));
+        }
+        int fileId = treeIndexHelper.getIndexFileId();
+        byte[] resourceId = DataUtil.intToByteArray(fileId);
+        transactionProvider.getTransactionalResourceRepository().registerTransactionalResource(resourceId,
+                treeIndexHelper.getIndex());
+        lockManager = transactionProvider.getLockManager();
+        bTreeLogger = transactionProvider.getTreeLoggerRepository().getTreeLogger(resourceId);
+    }
+
     @Override
     public void open() throws HyracksDataException {
         AbstractTreeIndexOperatorDescriptor opDesc = (AbstractTreeIndexOperatorDescriptor) treeIndexHelper
@@ -97,7 +107,7 @@
             throw new HyracksDataException(e);
         }
     }
-    
+
     @Override
     public void nextFrame(ByteBuffer buffer) throws HyracksDataException {
         final IIndex treeIndex = treeIndexHelper.getIndex();
@@ -123,7 +133,7 @@
                         indexAccessor.delete(tuple);
                         bTreeLogger.generateLogRecord(transactionProvider, txnContext, op, tuple);
                         break;
-                    }                        
+                    }
 
                     default: {
                         throw new HyracksDataException("Unsupported operation " + op
diff --git a/asterix-hyracks-glue/src/main/java/edu/uci/ics/asterix/runtime/transaction/TreeLoggerRepository.java b/asterix-hyracks-glue/src/main/java/edu/uci/ics/asterix/runtime/transaction/TreeLoggerRepository.java
deleted file mode 100644
index fbd3cb1..0000000
--- a/asterix-hyracks-glue/src/main/java/edu/uci/ics/asterix/runtime/transaction/TreeLoggerRepository.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2009-2011 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.asterix.runtime.transaction;
-
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.Map;
-
-public class TreeLoggerRepository {
-
-    private static final Map<ByteBuffer, TreeLogger> loggers = new HashMap<ByteBuffer, TreeLogger>();
-
-    public static synchronized TreeLogger getTreeLogger(byte[] resourceIdBytes) {
-        ByteBuffer resourceId = ByteBuffer.wrap(resourceIdBytes);
-        TreeLogger logger = loggers.get(resourceId);
-        if (logger == null) {
-            logger = new TreeLogger(resourceIdBytes);
-            loggers.put(resourceId, logger);
-        }
-        return logger;
-    }
-}
\ No newline at end of file
diff --git a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataNode.java b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataNode.java
index 243fc61..3bc7b75 100644
--- a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataNode.java
+++ b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataNode.java
@@ -19,15 +19,14 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import edu.uci.ics.asterix.common.api.INodeApplicationState;
 import edu.uci.ics.asterix.common.config.DatasetConfig.DatasetType;
 import edu.uci.ics.asterix.common.config.DatasetConfig.IndexType;
-import edu.uci.ics.asterix.common.dataflow.IAsterixApplicationContextInfo;
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.metadata.api.IMetadataIndex;
 import edu.uci.ics.asterix.metadata.api.IMetadataNode;
 import edu.uci.ics.asterix.metadata.api.IValueExtractor;
-import edu.uci.ics.asterix.metadata.bootstrap.AsterixProperties;
 import edu.uci.ics.asterix.metadata.bootstrap.MetadataPrimaryIndexes;
 import edu.uci.ics.asterix.metadata.bootstrap.MetadataSecondaryIndexes;
 import edu.uci.ics.asterix.metadata.entities.Dataset;
@@ -74,29 +73,25 @@
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrame;
 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.dataflow.IIndexRegistryProvider;
+import edu.uci.ics.hyracks.storage.am.common.dataflow.IndexRegistry;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
 
 public class MetadataNode implements IMetadataNode {
-
     private static final long serialVersionUID = 1L;
-    private static IIndexRegistryProvider<IIndex> btreeRegistryProvider;
-    public static MetadataNode INSTANCE;
+
     // TODO: Temporary transactional resource id for metadata.
-    private static byte[] metadataResourceId = MetadataNode.class.toString().getBytes();
+    private static final byte[] metadataResourceId = MetadataNode.class.toString().getBytes();
 
-    @SuppressWarnings("unchecked")
-    private ISerializerDeserializer<AString> stringSerde = AqlSerializerDeserializerProvider.INSTANCE
-            .getSerializerDeserializer(BuiltinType.ASTRING);
+    private final IndexRegistry<IIndex> indexRegistry;
+    private final TransactionProvider transactionProvider;
 
-    private TransactionProvider transactionProvider;
+    public static MetadataNode INSTANCE;
 
-    public MetadataNode(AsterixProperties asterixProperity, IAsterixApplicationContextInfo appContext,
-            TransactionProvider transactionProvider) {
+    public MetadataNode(INodeApplicationState applicationState) {
         super();
-        this.transactionProvider = transactionProvider;
-        btreeRegistryProvider = appContext.getTreeRegisterProvider();
+        this.transactionProvider = applicationState.getTransactionProvider();
+        this.indexRegistry = applicationState.getApplicationRuntimeContext().getIndexRegistry();
     }
 
     @Override
@@ -230,28 +225,22 @@
     }
 
     @Override
-	public void addFunction(long txnId, Function function)
-			throws MetadataException, RemoteException {
-		try {
-			// Insert into the 'function' dataset.
-			FunctionTupleTranslator tupleReaderWriter = new FunctionTupleTranslator(
-					true);
-			ITupleReference functionTuple = tupleReaderWriter
-					.getTupleFromMetadataEntity(function);
-			insertTupleIntoIndex(txnId,
-					MetadataPrimaryIndexes.FUNCTION_DATASET, functionTuple);
+    public void addFunction(long txnId, Function function) throws MetadataException, RemoteException {
+        try {
+            // Insert into the 'function' dataset.
+            FunctionTupleTranslator tupleReaderWriter = new FunctionTupleTranslator(true);
+            ITupleReference functionTuple = tupleReaderWriter.getTupleFromMetadataEntity(function);
+            insertTupleIntoIndex(txnId, MetadataPrimaryIndexes.FUNCTION_DATASET, functionTuple);
 
-		} catch (BTreeDuplicateKeyException e) {
-			throw new MetadataException("A dataset with this name "
-					+ function.getFunctionName() + " and arity "
-					+ function.getFunctionArity()
-					+ " already exists in dataverse '"
-					+ function.getDataverseName() + "'.", e);
-		} catch (Exception e) {
-			throw new MetadataException(e);
-		}
-	}
-    
+        } catch (BTreeDuplicateKeyException e) {
+            throw new MetadataException("A dataset with this name " + function.getFunctionName() + " and arity "
+                    + function.getFunctionArity() + " already exists in dataverse '" + function.getDataverseName()
+                    + "'.", e);
+        } catch (Exception e) {
+            throw new MetadataException(e);
+        }
+    }
+
     public void insertIntoDatatypeSecondaryIndex(long txnId, String dataverseName, String nestedTypeName,
             String topTypeName) throws Exception {
         ITupleReference tuple = createTuple(dataverseName, nestedTypeName, topTypeName);
@@ -260,7 +249,7 @@
 
     private void insertTupleIntoIndex(long txnId, IMetadataIndex index, ITupleReference tuple) throws Exception {
         int fileId = index.getFileId();
-        BTree btree = (BTree) btreeRegistryProvider.getRegistry(null).get(fileId);
+        BTree btree = (BTree) indexRegistry.get(fileId);
         btree.open(fileId);
         ITreeIndexAccessor indexAccessor = btree.createAccessor();
         TransactionContext txnCtx = transactionProvider.getTransactionManager().getTransactionContext(txnId);
@@ -505,7 +494,7 @@
 
     private void deleteTupleFromIndex(long txnId, IMetadataIndex index, ITupleReference tuple) throws Exception {
         int fileId = index.getFileId();
-        BTree btree = (BTree) btreeRegistryProvider.getRegistry(null).get(fileId);
+        BTree btree = (BTree) indexRegistry.get(fileId);
         btree.open(fileId);
 
         ITreeIndexAccessor indexAccessor = btree.createAccessor();
@@ -707,65 +696,57 @@
             throw new MetadataException(e);
         }
     }
-    
-    @Override
-	public Function getFunction(long txnId, String dataverseName,
-			String functionName, int arity) throws MetadataException,
-			RemoteException {
-		try {
-			ITupleReference searchKey = createTuple(dataverseName,
-					functionName, "" + arity);
-			FunctionTupleTranslator tupleReaderWriter = new FunctionTupleTranslator(
-					false);
-			List<Function> results = new ArrayList<Function>();
-			IValueExtractor<Function> valueExtractor = new MetadataEntityValueExtractor<Function>(
-					tupleReaderWriter);
-			searchIndex(txnId, MetadataPrimaryIndexes.FUNCTION_DATASET,
-					searchKey, valueExtractor, results);
-			if (results.isEmpty()) {
-				return null;
-			}
-			return results.get(0);
-		} catch (Exception e) {
-			throw new MetadataException(e);
-		}
-	}
 
     @Override
-	public void dropFunction(long txnId, String dataverseName,
-			String functionName, int arity) throws MetadataException,
-			RemoteException {
-		Function function;
-		try {
-			function = getFunction(txnId, dataverseName, functionName, arity);
-		} catch (Exception e) {
-			throw new MetadataException(e);
-		}
-		if (function == null) {
-			throw new MetadataException("Cannot drop function '" + functionName
-					+ " and arity " + arity + "' because it doesn't exist.");
-		}
-		try {
-			// Delete entry from the 'function' dataset.
-			ITupleReference searchKey = createTuple(dataverseName,
-					functionName, "" + arity);
-			// Searches the index for the tuple to be deleted. Acquires an S
-			// lock on the 'function' dataset.
-			ITupleReference datasetTuple = getTupleToBeDeleted(txnId,
-					MetadataPrimaryIndexes.FUNCTION_DATASET, searchKey);
-			deleteTupleFromIndex(txnId, MetadataPrimaryIndexes.FUNCTION_DATASET,
-					datasetTuple);
+    public Function getFunction(long txnId, String dataverseName, String functionName, int arity)
+            throws MetadataException, RemoteException {
+        try {
+            ITupleReference searchKey = createTuple(dataverseName, functionName, "" + arity);
+            FunctionTupleTranslator tupleReaderWriter = new FunctionTupleTranslator(false);
+            List<Function> results = new ArrayList<Function>();
+            IValueExtractor<Function> valueExtractor = new MetadataEntityValueExtractor<Function>(tupleReaderWriter);
+            searchIndex(txnId, MetadataPrimaryIndexes.FUNCTION_DATASET, searchKey, valueExtractor, results);
+            if (results.isEmpty()) {
+                return null;
+            }
+            return results.get(0);
+        } catch (Exception e) {
+            throw new MetadataException(e);
+        }
+    }
 
-			// TODO: Change this to be a BTree specific exception, e.g.,
-			// BTreeKeyDoesNotExistException.
-		} catch (TreeIndexException e) {
-			throw new MetadataException("Cannot drop function '" + functionName
-					+ " and arity " + arity + "' because it doesn't exist.", e);
-		} catch (Exception e) {
-			throw new MetadataException(e);
-		}
-	}
-    
+    @Override
+    public void dropFunction(long txnId, String dataverseName, String functionName, int arity)
+            throws MetadataException, RemoteException {
+        Function function;
+        try {
+            function = getFunction(txnId, dataverseName, functionName, arity);
+        } catch (Exception e) {
+            throw new MetadataException(e);
+        }
+        if (function == null) {
+            throw new MetadataException("Cannot drop function '" + functionName + " and arity " + arity
+                    + "' because it doesn't exist.");
+        }
+        try {
+            // Delete entry from the 'function' dataset.
+            ITupleReference searchKey = createTuple(dataverseName, functionName, "" + arity);
+            // Searches the index for the tuple to be deleted. Acquires an S
+            // lock on the 'function' dataset.
+            ITupleReference datasetTuple = getTupleToBeDeleted(txnId, MetadataPrimaryIndexes.FUNCTION_DATASET,
+                    searchKey);
+            deleteTupleFromIndex(txnId, MetadataPrimaryIndexes.FUNCTION_DATASET, datasetTuple);
+
+            // TODO: Change this to be a BTree specific exception, e.g.,
+            // BTreeKeyDoesNotExistException.
+        } catch (TreeIndexException e) {
+            throw new MetadataException("Cannot drop function '" + functionName + " and arity " + arity
+                    + "' because it doesn't exist.", e);
+        } catch (Exception e) {
+            throw new MetadataException(e);
+        }
+    }
+
     private ITupleReference getTupleToBeDeleted(long txnId, IMetadataIndex metadataIndex, ITupleReference searchKey)
             throws Exception {
         IValueExtractor<ITupleReference> valueExtractor = new TupleCopyValueExtractor(metadataIndex.getTypeTraits());
@@ -786,7 +767,7 @@
         transactionProvider.getLockManager().lock(txnCtx, index.getResourceId(), LockMode.SHARED);
         IBinaryComparatorFactory[] comparatorFactories = index.getKeyBinaryComparatorFactory();
         int fileId = index.getFileId();
-        BTree btree = (BTree) btreeRegistryProvider.getRegistry(null).get(fileId);
+        BTree btree = (BTree) indexRegistry.get(fileId);
         btree.open(fileId);
         ITreeIndexFrame leafFrame = btree.getLeafFrameFactory().createFrame();
         ITreeIndexAccessor indexAccessor = btree.createAccessor();
@@ -815,6 +796,8 @@
     // TODO: Can use Hyrack's TupleUtils for this, once we switch to a newer
     // Hyracks version.
     public ITupleReference createTuple(String... fields) throws HyracksDataException {
+        ISerializerDeserializer<AString> stringSerde = AqlSerializerDeserializerProvider.INSTANCE
+                .getSerializerDeserializer(BuiltinType.ASTRING);
         AMutableString aString = new AMutableString("");
         ArrayTupleBuilder tupleBuilder = new ArrayTupleBuilder(fields.length);
         for (String s : fields) {
diff --git a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/api/IMetadataIndex.java b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/api/IMetadataIndex.java
index c752f18..f9e5540 100644
--- a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/api/IMetadataIndex.java
+++ b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/api/IMetadataIndex.java
@@ -18,12 +18,13 @@
 import java.util.List;
 
 import edu.uci.ics.asterix.om.types.ARecordType;
-import edu.uci.ics.asterix.runtime.transaction.TreeLogger;
 import edu.uci.ics.asterix.transaction.management.exception.ACIDException;
+import edu.uci.ics.asterix.transaction.management.service.logging.TreeLogger;
 import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
 import edu.uci.ics.hyracks.api.dataflow.value.IBinaryHashFunctionFactory;
 import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
 import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 
 /**
  * Descriptor interface for a primary or secondary index on metadata datasets.
@@ -59,7 +60,7 @@
 
     public void setFileId(int fileId);
 
-    public void initTreeLogger() throws ACIDException;
+    public void initTreeLogger(ITreeIndex treeIndex) throws ACIDException;
 
     public int getFileId();
 
diff --git a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/bootstrap/MetadataBootstrap.java b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/bootstrap/MetadataBootstrap.java
index b2bfaf5..daa5fd0 100644
--- a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/bootstrap/MetadataBootstrap.java
+++ b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/bootstrap/MetadataBootstrap.java
@@ -23,9 +23,10 @@
 import java.util.List;
 import java.util.logging.Logger;
 
+import edu.uci.ics.asterix.common.api.INodeApplicationState;
 import edu.uci.ics.asterix.common.config.DatasetConfig.DatasetType;
 import edu.uci.ics.asterix.common.config.DatasetConfig.IndexType;
-import edu.uci.ics.asterix.common.dataflow.IAsterixApplicationContextInfo;
+import edu.uci.ics.asterix.common.context.AsterixAppRuntimeContext;
 import edu.uci.ics.asterix.metadata.IDatasetDetails;
 import edu.uci.ics.asterix.metadata.MetadataManager;
 import edu.uci.ics.asterix.metadata.MetadataTransactionContext;
@@ -42,11 +43,12 @@
 import edu.uci.ics.asterix.metadata.entities.NodeGroup;
 import edu.uci.ics.asterix.om.types.BuiltinType;
 import edu.uci.ics.asterix.om.types.IAType;
-import edu.uci.ics.asterix.runtime.transaction.TreeResourceManager;
 import edu.uci.ics.asterix.transaction.management.exception.ACIDException;
 import edu.uci.ics.asterix.transaction.management.resource.TransactionalResourceRepository;
 import edu.uci.ics.asterix.transaction.management.service.logging.DataUtil;
+import edu.uci.ics.asterix.transaction.management.service.logging.TreeResourceManager;
 import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionManagementConstants.LockManagerConstants.LockMode;
+import edu.uci.ics.hyracks.api.application.INCApplicationContext;
 import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
 import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
@@ -77,7 +79,6 @@
  * stopUniverse() should be called upon application undeployment.
  */
 public class MetadataBootstrap {
-
     private static IBufferCache bufferCache;
     private static IFileMapProvider fileMapProvider;
     private static IndexRegistry<IIndex> btreeRegistry;
@@ -102,8 +103,10 @@
                 MetadataSecondaryIndexes.DATATYPENAME_ON_DATATYPE_INDEX };
     }
 
-    public static void startUniverse(AsterixProperties asterixProperities, IAsterixApplicationContextInfo appContext)
+    public static void startUniverse(AsterixProperties asterixProperities, INCApplicationContext ncApplicationContext)
             throws Exception {
+        INodeApplicationState applicationState = (INodeApplicationState) ncApplicationContext.getApplicationObject();
+        AsterixAppRuntimeContext runtimeContext = applicationState.getApplicationRuntimeContext();
 
         // Initialize static metadata objects, such as record types and metadata
         // index descriptors.
@@ -115,8 +118,10 @@
         initLocalIndexArrays();
 
         boolean isNewUniverse = true;
-        TransactionalResourceRepository.registerTransactionalResourceManager(TreeResourceManager.ID,
-                TreeResourceManager.getInstance());
+        TransactionalResourceRepository resourceRepository = applicationState.getTransactionProvider()
+                .getTransactionalResourceRepository();
+        resourceRepository.registerTransactionalResourceManager(TreeResourceManager.ID, new TreeResourceManager(
+                applicationState.getTransactionProvider()));
 
         metadataNodeName = asterixProperities.getMetadataNodeName();
         isNewUniverse = asterixProperities.isNewUniverse();
@@ -129,9 +134,9 @@
             (new File(outputDir)).mkdirs();
         }
 
-        btreeRegistry = appContext.getTreeRegisterProvider().getRegistry(null);
-        bufferCache = appContext.getStorageManagerInterface().getBufferCache(null);
-        fileMapProvider = appContext.getStorageManagerInterface().getFileMapProvider(null);
+        btreeRegistry = runtimeContext.getIndexRegistry();
+        bufferCache = runtimeContext.getBufferCache();
+        fileMapProvider = runtimeContext.getFileMapManager();
 
         // Create fileRefs to all BTree files and open them in BufferCache.
         for (int i = 0; i < primaryIndexes.length; i++) {
@@ -150,11 +155,11 @@
             if (isNewUniverse) {
                 for (int i = 0; i < primaryIndexes.length; i++) {
                     createIndex(primaryIndexes[i]);
-                    registerTransactionalResource(primaryIndexes[i]);
+                    registerTransactionalResource(primaryIndexes[i], resourceRepository);
                 }
                 for (int i = 0; i < secondaryIndexes.length; i++) {
                     createIndex(secondaryIndexes[i]);
-                    registerTransactionalResource(secondaryIndexes[i]);
+                    registerTransactionalResource(secondaryIndexes[i], resourceRepository);
                 }
                 insertInitialDataverses(mdTxnCtx);
                 insertInitialDatasets(mdTxnCtx);
@@ -166,11 +171,11 @@
             } else {
                 for (int i = 0; i < primaryIndexes.length; i++) {
                     enlistMetadataDataset(primaryIndexes[i]);
-                    registerTransactionalResource(primaryIndexes[i]);
+                    registerTransactionalResource(primaryIndexes[i], resourceRepository);
                 }
                 for (int i = 0; i < secondaryIndexes.length; i++) {
                     enlistMetadataDataset(secondaryIndexes[i]);
-                    registerTransactionalResource(secondaryIndexes[i]);
+                    registerTransactionalResource(secondaryIndexes[i], resourceRepository);
                 }
                 LOGGER.info("FINISHED ENLISTMENT OF METADATA B-TREES.");
             }
@@ -215,12 +220,13 @@
         index.setFileId(fileId);
     }
 
-    private static void registerTransactionalResource(IMetadataIndex index) throws ACIDException {
+    private static void registerTransactionalResource(IMetadataIndex index,
+            TransactionalResourceRepository resourceRepository) throws ACIDException {
         int fileId = index.getFileId();
         ITreeIndex treeIndex = (ITreeIndex) btreeRegistry.get(fileId);
         byte[] resourceId = DataUtil.intToByteArray(fileId);
-        TransactionalResourceRepository.registerTransactionalResource(resourceId, treeIndex);
-        index.initTreeLogger();
+        resourceRepository.registerTransactionalResource(resourceId, treeIndex);
+        index.initTreeLogger(treeIndex);
     }
 
     public static void insertInitialDataverses(MetadataTransactionContext mdTxnCtx) throws Exception {
@@ -308,8 +314,8 @@
         ITreeIndexFrameFactory interiorFrameFactory = new BTreeNSMInteriorFrameFactory(tupleWriterFactory);
         ITreeIndexMetaDataFrameFactory metaDataFrameFactory = new LIFOMetaDataFrameFactory();
         IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, 0, metaDataFrameFactory);
-        BTree btree = new BTree(bufferCache, NoOpOperationCallback.INSTANCE, typeTraits.length, comparatorFactories, freePageManager, interiorFrameFactory,
-                leafFrameFactory);
+        BTree btree = new BTree(bufferCache, NoOpOperationCallback.INSTANCE, typeTraits.length, comparatorFactories,
+                freePageManager, interiorFrameFactory, leafFrameFactory);
         btree.create(fileId);
         btreeRegistry.register(fileId, btree);
     }
@@ -323,8 +329,8 @@
         ITreeIndexFrameFactory interiorFrameFactory = new BTreeNSMInteriorFrameFactory(tupleWriterFactory);
         ITreeIndexMetaDataFrameFactory metaDataFrameFactory = new LIFOMetaDataFrameFactory();
         IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, 0, metaDataFrameFactory);
-        BTree btree = new BTree(bufferCache, NoOpOperationCallback.INSTANCE, typeTraits.length, comparatorFactories, freePageManager, interiorFrameFactory,
-                leafFrameFactory);
+        BTree btree = new BTree(bufferCache, NoOpOperationCallback.INSTANCE, typeTraits.length, comparatorFactories,
+                freePageManager, interiorFrameFactory, leafFrameFactory);
         btreeRegistry.register(fileId, btree);
     }
 
diff --git a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/bootstrap/MetadataIndex.java b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/bootstrap/MetadataIndex.java
index e74a022..0773af8 100644
--- a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/bootstrap/MetadataIndex.java
+++ b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/bootstrap/MetadataIndex.java
@@ -27,15 +27,16 @@
 import edu.uci.ics.asterix.metadata.api.IMetadataIndex;
 import edu.uci.ics.asterix.om.types.ARecordType;
 import edu.uci.ics.asterix.om.types.IAType;
-import edu.uci.ics.asterix.runtime.transaction.TreeLogger;
 import edu.uci.ics.asterix.transaction.management.exception.ACIDException;
 import edu.uci.ics.asterix.transaction.management.service.logging.DataUtil;
+import edu.uci.ics.asterix.transaction.management.service.logging.TreeLogger;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder.OrderKind;
 import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
 import edu.uci.ics.hyracks.api.dataflow.value.IBinaryHashFunctionFactory;
 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.storage.am.common.api.ITreeIndex;
 
 /**
  * Descriptor for a primary or secondary index on metadata datasets.
@@ -201,8 +202,8 @@
     }
 
     @Override
-    public void initTreeLogger() throws ACIDException {
-        this.treeLogger = new TreeLogger(indexResourceId);
+    public void initTreeLogger(ITreeIndex treeIndex) throws ACIDException {
+        this.treeLogger = new TreeLogger(indexResourceId, treeIndex);
     }
 
     @Override
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/job/listener/JobEventListenerFactory.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/job/listener/JobEventListenerFactory.java
index 0a1faac..13839cd 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/job/listener/JobEventListenerFactory.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/job/listener/JobEventListenerFactory.java
@@ -1,5 +1,6 @@
 package edu.uci.ics.asterix.runtime.job.listener;
 
+import edu.uci.ics.asterix.common.api.INodeApplicationState;
 import edu.uci.ics.asterix.transaction.management.exception.ACIDException;
 import edu.uci.ics.asterix.transaction.management.service.transaction.ITransactionManager;
 import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionContext;
@@ -28,9 +29,8 @@
             @Override
             public void jobletFinish(JobStatus jobStatus) {
                 try {
-                    TransactionProvider factory = (TransactionProvider) (jobletContext.getApplicationContext()
-                            .getApplicationObject());
-                    ITransactionManager txnManager = factory.getTransactionManager();
+                    INodeApplicationState applicationState = (INodeApplicationState) jobletContext.getApplicationContext().getApplicationObject();
+                    ITransactionManager txnManager = applicationState.getTransactionProvider().getTransactionManager();
                     TransactionContext txnContext = txnManager.getTransactionContext(txnId);
                     txnContext.setTransactionType(transactionalWrite ? TransactionType.READ_WRITE
                             : TransactionType.READ);
diff --git a/asterix-transactions/pom.xml b/asterix-transactions/pom.xml
index f646356..6e38100 100644
--- a/asterix-transactions/pom.xml
+++ b/asterix-transactions/pom.xml
@@ -25,5 +25,11 @@
 	</build>
 
 	<dependencies>
+		<dependency>
+			<groupId>edu.uci.ics.hyracks</groupId>
+			<artifactId>hyracks-storage-am-btree</artifactId>
+			<version>0.2.1-SNAPSHOT</version>
+			<scope>compile</scope>
+		</dependency>
 	</dependencies>
 </project>
diff --git a/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/resource/TransactionalResourceRepository.java b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/resource/TransactionalResourceRepository.java
index 586f6d6..2bbcc92 100644
--- a/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/resource/TransactionalResourceRepository.java
+++ b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/resource/TransactionalResourceRepository.java
@@ -32,7 +32,7 @@
  */
 public class TransactionalResourceRepository {
 
-    private static Map<ByteBuffer, Object> resourceRepository = new HashMap<ByteBuffer, Object>(); // repository
+    private Map<ByteBuffer, Object> resourceRepository = new HashMap<ByteBuffer, Object>(); // repository
     // containing
     // resources
     // that
@@ -40,13 +40,13 @@
     // in
     // transactions
 
-    private static Map<Byte, IResourceManager> resourceMgrRepository = new HashMap<Byte, IResourceManager>(); // repository
+    private Map<Byte, IResourceManager> resourceMgrRepository = new HashMap<Byte, IResourceManager>(); // repository
 
     // containing
     // resource
     // managers
 
-    public static void registerTransactionalResource(byte[] resourceBytes, Object resource) {
+    public void registerTransactionalResource(byte[] resourceBytes, Object resource) {
         ByteBuffer resourceId = ByteBuffer.wrap(resourceBytes); // need to
         // convert to
         // ByteBuffer so
@@ -66,7 +66,7 @@
         }
     }
 
-    public static void registerTransactionalResourceManager(byte id, IResourceManager resourceMgr) {
+    public void registerTransactionalResourceManager(byte id, IResourceManager resourceMgr) {
         synchronized (resourceMgrRepository) {
             if (resourceMgrRepository.get(id) == null) {
                 resourceMgrRepository.put(id, resourceMgr);
@@ -79,7 +79,7 @@
         }
     }
 
-    public static Object getTransactionalResource(byte[] resourceIdBytes) {
+    public Object getTransactionalResource(byte[] resourceIdBytes) {
         ByteBuffer buffer = ByteBuffer.wrap(resourceIdBytes);
         synchronized (resourceRepository) {
             while (resourceRepository.get(buffer) == null) {
@@ -95,17 +95,17 @@
         }
     }
 
-    public static IResourceManager getTransactionalResourceMgr(byte id) {
+    public IResourceManager getTransactionalResourceMgr(byte id) {
         synchronized (resourceMgrRepository) {
-            while (resourceMgrRepository.get(id) == null) {
-                try {
-                    resourceMgrRepository.wait();
-                } catch (InterruptedException ie) {
-                    ie.printStackTrace();
-                    break; // the thread might be interrupted due to other
-                    // failures occurring elsewhere, break from the loop
-                }
-            }
+//            while (resourceMgrRepository.get(id) == null) {
+//                try {
+//                    resourceMgrRepository.wait();
+//                } catch (InterruptedException ie) {
+//                    ie.printStackTrace();
+//                    break; // the thread might be interrupted due to other
+//                    // failures occurring elsewhere, break from the loop
+//                }
+//            }
             return resourceMgrRepository.get(id);
         }
 
diff --git a/asterix-hyracks-glue/src/main/java/edu/uci/ics/asterix/runtime/transaction/TreeLogger.java b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/logging/TreeLogger.java
similarity index 91%
rename from asterix-hyracks-glue/src/main/java/edu/uci/ics/asterix/runtime/transaction/TreeLogger.java
rename to asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/logging/TreeLogger.java
index e2b6509..3b923dd 100644
--- a/asterix-hyracks-glue/src/main/java/edu/uci/ics/asterix/runtime/transaction/TreeLogger.java
+++ b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/logging/TreeLogger.java
@@ -12,7 +12,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package edu.uci.ics.asterix.runtime.transaction;
+package edu.uci.ics.asterix.transaction.management.service.logging;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -20,13 +20,6 @@
 
 import edu.uci.ics.asterix.transaction.management.exception.ACIDException;
 import edu.uci.ics.asterix.transaction.management.resource.ICloseable;
-import edu.uci.ics.asterix.transaction.management.resource.TransactionalResourceRepository;
-import edu.uci.ics.asterix.transaction.management.service.logging.DataUtil;
-import edu.uci.ics.asterix.transaction.management.service.logging.ILogger;
-import edu.uci.ics.asterix.transaction.management.service.logging.LogActionType;
-import edu.uci.ics.asterix.transaction.management.service.logging.LogType;
-import edu.uci.ics.asterix.transaction.management.service.logging.LogUtil;
-import edu.uci.ics.asterix.transaction.management.service.logging.LogicalLogLocator;
 import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionContext;
 import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionProvider;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
@@ -121,9 +114,9 @@
         public static final byte DELETE = 1;
     }
 
-    public TreeLogger(byte[] resourceIdBytes) {
+    public TreeLogger(byte[] resourceIdBytes, ITreeIndex treeIndex) {
         this.resourceIdBytes = resourceIdBytes;
-        treeIndex = (ITreeIndex) TransactionalResourceRepository.getTransactionalResource(resourceIdBytes);
+        this.treeIndex = treeIndex;
         treeIndexTupleWriter = treeIndex.getLeafFrameFactory().getTupleWriterFactory().createTupleWriter();
         this.resourceIdLengthBytes = DataUtil.intToByteArray(resourceIdBytes.length);
     }
diff --git a/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/logging/TreeLoggerRepository.java b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/logging/TreeLoggerRepository.java
new file mode 100644
index 0000000..34e1466
--- /dev/null
+++ b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/logging/TreeLoggerRepository.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2009-2011 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.asterix.transaction.management.service.logging;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionProvider;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+
+public class TreeLoggerRepository {
+
+    private final Map<ByteBuffer, TreeLogger> loggers = new HashMap<ByteBuffer, TreeLogger>();
+    private final TransactionProvider provider;
+
+    public TreeLoggerRepository(TransactionProvider provider) {
+        this.provider = provider;
+    }
+
+    public synchronized TreeLogger getTreeLogger(byte[] resourceIdBytes) {
+        ByteBuffer resourceId = ByteBuffer.wrap(resourceIdBytes);
+        TreeLogger logger = loggers.get(resourceId);
+        if (logger == null) {
+            ITreeIndex treeIndex = (ITreeIndex) provider.getTransactionalResourceRepository().getTransactionalResource(
+                    resourceIdBytes);
+            logger = new TreeLogger(resourceIdBytes, treeIndex);
+            loggers.put(resourceId, logger);
+        }
+        return logger;
+    }
+}
\ No newline at end of file
diff --git a/asterix-hyracks-glue/src/main/java/edu/uci/ics/asterix/runtime/transaction/TreeResourceManager.java b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/logging/TreeResourceManager.java
similarity index 81%
rename from asterix-hyracks-glue/src/main/java/edu/uci/ics/asterix/runtime/transaction/TreeResourceManager.java
rename to asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/logging/TreeResourceManager.java
index 4309618..7c6d05a 100644
--- a/asterix-hyracks-glue/src/main/java/edu/uci/ics/asterix/runtime/transaction/TreeResourceManager.java
+++ b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/logging/TreeResourceManager.java
@@ -12,14 +12,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package edu.uci.ics.asterix.runtime.transaction;
+package edu.uci.ics.asterix.transaction.management.service.logging;
 
 import edu.uci.ics.asterix.transaction.management.exception.ACIDException;
-import edu.uci.ics.asterix.transaction.management.resource.TransactionalResourceRepository;
-import edu.uci.ics.asterix.transaction.management.service.logging.DataUtil;
-import edu.uci.ics.asterix.transaction.management.service.logging.ILogRecordHelper;
-import edu.uci.ics.asterix.transaction.management.service.logging.LogicalLogLocator;
 import edu.uci.ics.asterix.transaction.management.service.transaction.IResourceManager;
+import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionProvider;
 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.ITreeIndexTupleReference;
@@ -28,13 +25,10 @@
 
     public static final byte ID = (byte) 1;
 
-    private static final TreeResourceManager treeResourceMgr = new TreeResourceManager();
+    private final TransactionProvider provider;
 
-    private TreeResourceManager() {
-    }
-
-    public static TreeResourceManager getInstance() {
-        return treeResourceMgr;
+    public TreeResourceManager(TransactionProvider provider) {
+        this.provider = provider;
     }
 
     public byte getResourceManagerId() {
@@ -53,7 +47,8 @@
         System.arraycopy(logBufferContent, logContentBeginPos + 4, resourceIdBytes, 0, resourceIdLength);
 
         // look up the repository to obtain the resource object
-        ITreeIndex treeIndex = (ITreeIndex) TransactionalResourceRepository.getTransactionalResource(resourceIdBytes);
+        ITreeIndex treeIndex = (ITreeIndex) provider.getTransactionalResourceRepository().getTransactionalResource(
+                resourceIdBytes);
         int operationOffset = logContentBeginPos + 4 + resourceIdLength;
         int tupleBeginPos = operationOffset + 1;
 
diff --git a/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/recovery/RecoveryManager.java b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/recovery/RecoveryManager.java
index 085a9da..9c78b95 100644
--- a/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/recovery/RecoveryManager.java
+++ b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/recovery/RecoveryManager.java
@@ -110,7 +110,7 @@
                     break;
                 }
                 byte resourceMgrId = parser.getResourceMgrId(memLSN);
-                IResourceManager resourceMgr = TransactionalResourceRepository
+                IResourceManager resourceMgr = transactionProvider.getTransactionalResourceRepository()
                         .getTransactionalResourceMgr(resourceMgrId);
                 if (resourceMgr == null) {
                     throw new ACIDException("unknown resource mgr with id " + resourceMgrId);
@@ -217,7 +217,7 @@
                     }
 
                     // look up the repository to get the resource manager
-                    IResourceManager resourceMgr = TransactionalResourceRepository
+                    IResourceManager resourceMgr = transactionProvider.getTransactionalResourceRepository()
                             .getTransactionalResourceMgr(resourceMgrId);
                     if (resourceMgr == null) {
                         throw new ACIDException(txnContext, " unknown resource manager " + resourceMgrId);
diff --git a/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/transaction/TransactionProvider.java b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/transaction/TransactionProvider.java
index ede93a7..ef843f4 100644
--- a/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/transaction/TransactionProvider.java
+++ b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/transaction/TransactionProvider.java
@@ -15,10 +15,12 @@
 package edu.uci.ics.asterix.transaction.management.service.transaction;
 
 import edu.uci.ics.asterix.transaction.management.exception.ACIDException;
+import edu.uci.ics.asterix.transaction.management.resource.TransactionalResourceRepository;
 import edu.uci.ics.asterix.transaction.management.service.locking.ILockManager;
 import edu.uci.ics.asterix.transaction.management.service.locking.LockManager;
 import edu.uci.ics.asterix.transaction.management.service.logging.ILogManager;
 import edu.uci.ics.asterix.transaction.management.service.logging.LogManager;
+import edu.uci.ics.asterix.transaction.management.service.logging.TreeLoggerRepository;
 import edu.uci.ics.asterix.transaction.management.service.recovery.IRecoveryManager;
 import edu.uci.ics.asterix.transaction.management.service.recovery.RecoveryManager;
 
@@ -32,13 +34,17 @@
     private final ILockManager lockManager;
     private final ITransactionManager transactionManager;
     private final IRecoveryManager recoveryManager;
+    private final TransactionalResourceRepository resourceRepository;
+    private final TreeLoggerRepository loggerRepository;
 
     public TransactionProvider(String id) throws ACIDException {
         this.id = id;
-        transactionManager = new TransactionManager(this);
-        logManager = new LogManager(this);
-        lockManager = new LockManager(this);
-        recoveryManager = new RecoveryManager(this);
+        this.transactionManager = new TransactionManager(this);
+        this.logManager = new LogManager(this);
+        this.lockManager = new LockManager(this);
+        this.recoveryManager = new RecoveryManager(this);
+        this.loggerRepository = new TreeLoggerRepository(this);
+        this.resourceRepository = new TransactionalResourceRepository();
     }
 
     public ILogManager getLogManager() {
@@ -56,6 +62,14 @@
     public IRecoveryManager getRecoveryManager() {
         return recoveryManager;
     }
+    
+    public TransactionalResourceRepository getTransactionalResourceRepository() {
+        return resourceRepository;
+    }
+    
+    public TreeLoggerRepository getTreeLoggerRepository() {
+        return loggerRepository;
+    }
 
     public String getId() {
         return id;
diff --git a/asterix-transactions/src/test/java/edu/uci/ics/asterix/transaction/management/logging/test/TransactionWorkloadSimulator.java b/asterix-transactions/src/test/java/edu/uci/ics/asterix/transaction/management/logging/test/TransactionWorkloadSimulator.java
index 40ee93f..496260d 100644
--- a/asterix-transactions/src/test/java/edu/uci/ics/asterix/transaction/management/logging/test/TransactionWorkloadSimulator.java
+++ b/asterix-transactions/src/test/java/edu/uci/ics/asterix/transaction/management/logging/test/TransactionWorkloadSimulator.java
@@ -51,7 +51,7 @@
         provider = new TransactionProvider("nc1");
         logManager = provider.getLogManager();
         lockManager = provider.getLockManager();
-        TransactionalResourceRepository.registerTransactionalResourceManager(DummyResourceMgr.id,
+        provider.getTransactionalResourceRepository().registerTransactionalResourceManager(DummyResourceMgr.id,
                 new DummyResourceMgr());
         Transaction[] transactions = new Transaction[workload.numActiveThreads];
         long startTime = System.nanoTime();
diff --git a/asterix-transactions/src/test/java/edu/uci/ics/asterix/transaction/management/test/TransactionSimulator.java b/asterix-transactions/src/test/java/edu/uci/ics/asterix/transaction/management/test/TransactionSimulator.java
index fb198fe..ffa5af6 100644
--- a/asterix-transactions/src/test/java/edu/uci/ics/asterix/transaction/management/test/TransactionSimulator.java
+++ b/asterix-transactions/src/test/java/edu/uci/ics/asterix/transaction/management/test/TransactionSimulator.java
@@ -54,8 +54,8 @@
         logManager = transactionProvider.getLogManager();
         lockManager = transactionProvider.getLockManager();
         recoveryManager = transactionProvider.getRecoveryManager();
-        TransactionalResourceRepository.registerTransactionalResourceManager(resourceMgr.getResourceManagerId(),
-                resourceMgr);
+        transactionProvider.getTransactionalResourceRepository().registerTransactionalResourceManager(
+                resourceMgr.getResourceManagerId(), resourceMgr);
         this.resourceMgr = resourceMgr;
         this.logger = resource.getLogger();
         this.resource = resource;