Redesign libbcc api.
diff --git a/README.html b/README.html
index 56edd02..db49a3a 100644
--- a/README.html
+++ b/README.html
@@ -355,20 +355,23 @@
 <li><strong>bccLinkBC</strong> - Set the library bitcode for linking</li>
 <li><strong>bccPrepareExecutable</strong> - Create the in-memory executable by either
 just-in-time compilation or cache loading</li>
-<li><strong>bccDeleteScript</strong> - Destroy bcc script and release the resources</li>
-<li><strong>bccGetError</strong> - Get the error code</li>
-<li><strong>bccGetScriptInfoLog</strong> - <em>deprecated</em> - Don't use this</li>
+<li><strong>bccGetFuncAddr</strong> - Get the entry address of the function</li>
+<li><strong>bccDisposeScript</strong> - Destroy bcc script and release the resources</li>
+<li><strong>bccGetError</strong> - <em>deprecated</em> - Don't use this</li>
 </ul>
 <p><strong>Reflection:</strong></p>
 <ul class="simple">
-<li><strong>bccGetExportVars</strong> - Get the addresses of exported variables</li>
-<li><strong>bccGetExportFuncs</strong> - Get the addresses of exported functions</li>
-<li><strong>bccGetPragmas</strong> - Get the pragmas</li>
+<li><strong>bccGetExportVarCount</strong> - Get the count of exported variables</li>
+<li><strong>bccGetExportVarList</strong> - Get the addresses of exported variables</li>
+<li><strong>bccGetExportFuncCount</strong> - Get the count of exported functions</li>
+<li><strong>bccGetExportFuncList</strong> - Get the addresses of exported functions</li>
+<li><strong>bccGetPragmaCount</strong> - Get the count of pragmas</li>
+<li><strong>bccGetPragmaList</strong> - Get the pragmas</li>
 </ul>
 <p><strong>Debug:</strong></p>
 <ul class="simple">
-<li><strong>bccGetFunctions</strong> - Get the function name list</li>
-<li><strong>bccGetFunctionBinary</strong> - Get the address and the size of a function binary</li>
+<li><strong>bccGetFuncCount</strong> - Get the count of functions (including non-exported)</li>
+<li><strong>bccGetFuncInfoList</strong> - Get the function information (name, base, size)</li>
 </ul>
 </div>
 <div class="section" id="cache-file-format">
diff --git a/README.rst b/README.rst
index 887f0ee..44f4663 100644
--- a/README.rst
+++ b/README.rst
@@ -64,27 +64,33 @@
 * **bccPrepareExecutable** - Create the in-memory executable by either
   just-in-time compilation or cache loading
 
-* **bccDeleteScript** - Destroy bcc script and release the resources
+* **bccGetFuncAddr** - Get the entry address of the function
 
-* **bccGetError** - Get the error code
+* **bccDisposeScript** - Destroy bcc script and release the resources
 
-* **bccGetScriptInfoLog** - *deprecated* - Don't use this
+* **bccGetError** - *deprecated* - Don't use this
 
 
 **Reflection:**
 
-* **bccGetExportVars** - Get the addresses of exported variables
+* **bccGetExportVarCount** - Get the count of exported variables
 
-* **bccGetExportFuncs** - Get the addresses of exported functions
+* **bccGetExportVarList** - Get the addresses of exported variables
 
-* **bccGetPragmas** - Get the pragmas
+* **bccGetExportFuncCount** - Get the count of exported functions
+
+* **bccGetExportFuncList** - Get the addresses of exported functions
+
+* **bccGetPragmaCount** - Get the count of pragmas
+
+* **bccGetPragmaList** - Get the pragmas
 
 
 **Debug:**
 
-* **bccGetFunctions** - Get the function name list
+* **bccGetFuncCount** - Get the count of functions (including non-exported)
 
-* **bccGetFunctionBinary** - Get the address and the size of a function binary
+* **bccGetFuncInfoList** - Get the function information (name, base, size)
 
 
 
diff --git a/include/bcc/bcc.h b/include/bcc/bcc.h
index bc05757..299e193 100644
--- a/include/bcc/bcc.h
+++ b/include/bcc/bcc.h
@@ -17,116 +17,127 @@
 #ifndef ANDROID_BCC_BCC_H
 #define ANDROID_BCC_BCC_H
 
-#include <stdint.h>
-#include <sys/types.h>
+#include <stddef.h>
 
-typedef char                        BCCchar;
-typedef int32_t                     BCCint;
-typedef uint32_t                    BCCuint;
-typedef ssize_t                     BCCsizei;
-typedef unsigned int                BCCenum;
-typedef void                        BCCvoid;
+/*-------------------------------------------------------------------------*/
+
+/* libbcc script opaque type */
+typedef struct BCCOpaqueScript *BCCScriptRef;
+
+
+/* Function information struct */
+struct BCCFuncInfo {
+  char const *name;
+  void *addr;
+  size_t size;
+};
 
 #if !defined(__cplusplus)
-
-typedef struct BCCscript            BCCscript;
-
-#else
-
-namespace bcc {
-  class Script;
-}
-
-typedef bcc::Script                 BCCscript;
-
+typedef struct BCCFuncInfo BCCFuncInfo;
 #endif
 
-#define BCC_NO_ERROR                0x0000
-#define BCC_INVALID_ENUM            0x0500
-#define BCC_INVALID_OPERATION       0x0502
-#define BCC_INVALID_VALUE           0x0501
-#define BCC_OUT_OF_MEMORY           0x0505
 
-#define BCC_COMPILE_STATUS          0x8B81
-#define BCC_INFO_LOG_LENGTH         0x8B84
+/* Symbol lookup function type */
+typedef void *(*BCCSymbolLookupFn)(void *context, char const *symbolName);
 
 
-// ----------------------------------------------------------------------------
+/* llvm::Module (see <llvm>/include/llvm-c/Core.h for details) */
+typedef struct LLVMOpaqueModule *LLVMModuleRef;
+
+
+/*-------------------------------------------------------------------------*/
+
+
+#define BCC_NO_ERROR          0x0000
+#define BCC_INVALID_ENUM      0x0500
+#define BCC_INVALID_OPERATION 0x0502
+#define BCC_INVALID_VALUE     0x0501
+#define BCC_OUT_OF_MEMORY     0x0505
+
+
+/*-------------------------------------------------------------------------*/
+
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-BCCscript *bccCreateScript();
+BCCScriptRef bccCreateScript();
 
-void bccDeleteScript(BCCscript *script);
+void bccDisposeScript(BCCScriptRef script);
 
-typedef BCCvoid *(*BCCSymbolLookupFn)(BCCvoid *pContext, const BCCchar *name);
-
-void bccRegisterSymbolCallback(BCCscript *script,
+void bccRegisterSymbolCallback(BCCScriptRef script,
                                BCCSymbolLookupFn pFn,
-                               BCCvoid *pContext);
+                               void *pContext);
 
-BCCenum bccGetError( BCCscript *script );
+int bccGetError(BCCScriptRef script); /* deprecated */
 
-int bccReadBC(BCCscript *script,
-              const BCCchar *bitcode,
-              BCCint bitcodeSize,
-              long __DONT_USE_PARAM_1,
-              long __DONT_USE_PARAM_2,
-              const BCCchar *resName,
-              const BCCchar *cacheDir);
 
-// Interface for llvm::Module input. @module should be a valid llvm::Module
-// instance.
-int bccReadModule(BCCscript *script,
-                  BCCvoid *module);
 
-int bccLinkBC(BCCscript *script,
-              const BCCchar *bitcode,
-              BCCint size);
+int bccReadBC(BCCScriptRef script,
+              char const *resName,
+              char const *bitcode,
+              size_t bitcodeSize,
+              unsigned long flags);
 
-int bccPrepareExecutable(BCCscript *script);
+int bccReadModule(BCCScriptRef script,
+                  char const *resName,
+                  LLVMModuleRef module,
+                  unsigned long flags);
 
-void bccGetScriptInfoLog(BCCscript *script,
-                         BCCsizei maxLength,
-                         BCCsizei *length,
-                         BCCchar *infoLog);
+int bccLinkBC(BCCScriptRef script,
+              char const *resName,
+              char const *bitcode,
+              size_t bitcodeSize,
+              unsigned long flags);
 
-void bccGetScriptLabel(BCCscript *script,
-                       const BCCchar *name,
-                       BCCvoid **address);
+int bccPrepareExecutable(BCCScriptRef script,
+                         char const *cachePath,
+                         unsigned long flags);
 
-void bccGetExportVars(BCCscript *script,
-                      BCCsizei *actualVarCount,
-                      BCCsizei maxVarCount,
-                      BCCvoid **vars);
+void *bccGetFuncAddr(BCCScriptRef script, char const *funcname);
 
-void bccGetExportFuncs(BCCscript *script,
-                       BCCsizei *actualFuncCount,
-                       BCCsizei maxFuncCount,
-                       BCCvoid **funcs);
 
-void bccGetPragmas(BCCscript *script,
-                   BCCsizei *actualStringCount,
-                   BCCsizei maxStringCount,
-                   BCCchar **strings);
 
-// Below two functions are for debugging
-void bccGetFunctions(BCCscript *script,
-                     BCCsizei *actualFunctionCount,
-                     BCCsizei maxFunctionCount,
-                     BCCchar **functions);
+size_t bccGetExportVarCount(BCCScriptRef script);
 
-void bccGetFunctionBinary(BCCscript *script,
-                          BCCchar *function,
-                          BCCvoid **base,
-                          BCCsizei *length);
+void bccGetExportVarList(BCCScriptRef script,
+                         size_t varListSize,
+                         void **varList);
+
+size_t bccGetExportFuncCount(BCCScriptRef script);
+
+void bccGetExportFuncList(BCCScriptRef script,
+                          size_t funcListSize,
+                          void **funcList);
+
+size_t bccGetPragmaCount(BCCScriptRef script);
+
+void bccGetPragmaList(BCCScriptRef script,
+                      size_t pragmaListSize,
+                      char const **keyList,
+                      char const **valueList);
+
+size_t bccGetFuncCount(BCCScriptRef script);
+
+
+
+void bccGetFuncInfoList(BCCScriptRef script,
+                        size_t funcInfoListSize,
+                        BCCFuncInfo *funcInfoList);
 
 #ifdef __cplusplus
 };
 #endif
 
-// ----------------------------------------------------------------------------
+
+/*-------------------------------------------------------------------------*/
+
+
+/* libbcc library build time */
+extern char const libbcc_build_time[24];
+
+
+/*-------------------------------------------------------------------------*/
 
 #endif
diff --git a/include/bcc/bcc_cache.h b/include/bcc/bcc_cache.h
index 6b83cbf..137d4cc 100644
--- a/include/bcc/bcc_cache.h
+++ b/include/bcc/bcc_cache.h
@@ -20,8 +20,6 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-extern char const libbcc_build_time[24];
-
 /* BCC Cache File Magic Word */
 #define OBCC_MAGIC "\0bcc"
 
diff --git a/lib/bcc/CacheWriter.cpp b/lib/bcc/CacheWriter.cpp
index a0b5da2..6d3a104 100644
--- a/lib/bcc/CacheWriter.cpp
+++ b/lib/bcc/CacheWriter.cpp
@@ -162,21 +162,16 @@
   tab->count = static_cast<size_t>(funcCount);
 
   // Get the function informations
-  vector<char const *> funcNameList(funcCount);
-  mpOwner->getFuncNameList(funcCount, &*funcNameList.begin());
+  vector<FuncInfo> funcInfoList(funcCount);
+  mpOwner->getFuncInfoList(funcCount, &*funcInfoList.begin());
 
   for (size_t i = 0; i < funcCount; ++i) {
-    char const *funcName = funcNameList[i];
-    size_t funcNameLen = strlen(funcName);
+    FuncInfo *info = &funcInfoList[i];
+    OBCC_FuncInfo *outputInfo = &tab->table[i];
 
-    void *funcAddr = NULL;
-    size_t funcBinarySize = 0;
-    mpOwner->getFuncBinary(funcName, &funcAddr, &funcBinarySize);
-
-    OBCC_FuncInfo *funcInfo = &tab->table[i];
-    funcInfo->name_strp_index = addString(funcName, funcNameLen);
-    funcInfo->cached_addr = funcAddr;
-    funcInfo->size = static_cast<size_t>(funcBinarySize);
+    outputInfo->name_strp_index = addString(info->name, strlen(info->name));
+    outputInfo->cached_addr = info->addr;
+    outputInfo->size = info->size;
   }
 
   return true;
diff --git a/lib/bcc/CodeEmitter.cpp b/lib/bcc/CodeEmitter.cpp
index f2eed18..29e0934 100644
--- a/lib/bcc/CodeEmitter.cpp
+++ b/lib/bcc/CodeEmitter.cpp
@@ -17,12 +17,12 @@
 #include "CodeEmitter.h"
 
 #include "CodeMemoryManager.h"
-#include "EmittedFuncInfo.h"
 #include "Runtime.h"
 #include "ScriptCompiled.h"
 
 #include <bcc/bcc.h>
 #include <bcc/bcc_cache.h>
+#include "bcc_internal.h"
 
 #include "llvm/ADT/APFloat.h"
 #include "llvm/ADT/APInt.h"
@@ -1269,9 +1269,12 @@
       mpMemMgr->startFunctionBody(F.getFunction(), ActualSize);
   BufferEnd = BufferBegin + ActualSize;
 
-  if (mpCurEmitFunction == NULL)
-    mpCurEmitFunction = new EmittedFuncInfo();
-  mpCurEmitFunction->FunctionBody = BufferBegin;
+  if (mpCurEmitFunction == NULL) {
+    mpCurEmitFunction = new FuncInfo(); // TODO(all): Allocation check!
+    mpCurEmitFunction->name = NULL;
+    mpCurEmitFunction->addr = NULL;
+    mpCurEmitFunction->size = 0;
+  }
 
   // Ensure the constant pool/jump table info is at least 4-byte aligned.
   emitAlignment(16);
@@ -1285,7 +1288,7 @@
 
   UpdateGlobalMapping(F.getFunction(), CurBufferPtr);
 
-  mpCurEmitFunction->Code = CurBufferPtr;
+  mpCurEmitFunction->addr = CurBufferPtr;
 
   mMBBLocations.clear();
 }
@@ -1379,7 +1382,7 @@
     return false;
 
   // Now that we've succeeded in emitting the function.
-  mpCurEmitFunction->Size = CurBufferPtr - BufferBegin;
+  mpCurEmitFunction->size = CurBufferPtr - BufferBegin;
   BufferBegin = CurBufferPtr = 0;
 
   if (F.getFunction()->hasName()) {
diff --git a/lib/bcc/CodeEmitter.h b/lib/bcc/CodeEmitter.h
index 8e1bb99..289c954 100644
--- a/lib/bcc/CodeEmitter.h
+++ b/lib/bcc/CodeEmitter.h
@@ -16,6 +16,7 @@
 
 #include <bcc/bcc.h>
 #include <bcc/bcc_cache.h>
+#include "bcc_internal.h"
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
@@ -57,7 +58,6 @@
 
 namespace bcc {
   class CodeMemoryManager;
-  class EmittedFuncInfo;
   class ScriptCompiled;
 
   class CodeEmitter : public llvm::JITCodeEmitter {
@@ -88,7 +88,7 @@
     const llvm::TargetData *mpTD;
 
 
-    EmittedFuncInfo *mpCurEmitFunction;
+    FuncInfo *mpCurEmitFunction;
 
     GlobalAddressMapTy mGlobalAddressMap;
 
@@ -171,7 +171,7 @@
     }
 #endif
 
-    void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid *pContext) {
+    void registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
       mpSymbolLookupFn = pFn;
       mpSymbolLookupContext = pContext;
     }
diff --git a/lib/bcc/Compiler.cpp b/lib/bcc/Compiler.cpp
index 77813c8..188a0ff 100644
--- a/lib/bcc/Compiler.cpp
+++ b/lib/bcc/Compiler.cpp
@@ -283,14 +283,11 @@
 // Compiler::readBC
 // Parameters:
 //
-int Compiler::readBC(const char *bitcode,
-                     size_t bitcodeSize,
-                     const BCCchar *resName /* Deprecated */,
-                     const BCCchar *cacheDir /* Deprecated */) {
+int Compiler::readBC(const char *bitcode, size_t bitcodeSize) {
   llvm::OwningPtr<llvm::MemoryBuffer> MEM;
 
   if (bitcode == NULL || bitcodeSize <= 0)
-    return 0;
+    return 1;
 
   // Package input to object MemoryBuffer
   MEM.reset(llvm::MemoryBuffer::getMemBuffer(
@@ -312,7 +309,7 @@
   llvm::OwningPtr<llvm::MemoryBuffer> MEM;
 
   if (bitcode == NULL || bitcodeSize <= 0) {
-    LOGE("Invalid bitcode for linkBC: bitcode=%p, size=%lu.\n", bitcode, (unsigned long)bitcodeSize);
+    LOGE("Invalid bitcode for linkBC\n");
     return 1;
   }
 
diff --git a/lib/bcc/Compiler.h b/lib/bcc/Compiler.h
index 450ccea..5f3961c 100644
--- a/lib/bcc/Compiler.h
+++ b/lib/bcc/Compiler.h
@@ -100,8 +100,7 @@
 
     static void GlobalInitialization();
 
-    // interface for BCCscript::registerSymbolCallback()
-    void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid *pContext) {
+    void registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
       mpSymbolLookupFn = pFn;
       mpSymbolLookupContext = pContext;
     }
@@ -115,10 +114,7 @@
       return hasError();
     }
 
-    int readBC(const char *bitcode,
-               size_t bitcodeSize,
-               const BCCchar *resName,
-               const BCCchar *cacheDir);
+    int readBC(const char *bitcode, size_t bitcodeSize);
 
     int linkBC(const char *bitcode, size_t bitcodeSize);
 
diff --git a/lib/bcc/EmittedFuncInfo.h b/lib/bcc/EmittedFuncInfo.h
deleted file mode 100644
index b0fdb06..0000000
--- a/lib/bcc/EmittedFuncInfo.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2010, The Android Open Source Project
- *
- * 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 at
- *
- *     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.
- */
-
-#ifndef BCC_EMITTEDFUNCINFO_H
-#define BCC_EMITTEDFUNCINFO_H
-
-#include <stddef.h>
-
-namespace bcc {
-
-  class EmittedFuncInfo {
-  public:
-    // Beginning of the function's allocation.
-    void *FunctionBody;
-
-    // The address the function's code actually starts at.
-    void *Code;
-
-    // The size of the function code
-    int Size;
-
-    EmittedFuncInfo() : FunctionBody(NULL), Code(NULL) {
-    }
-
-  };
-
-} // namespace bcc
-
-#endif // BCC_EMITTEDFUNCINFO_H
diff --git a/lib/bcc/Script.cpp b/lib/bcc/Script.cpp
index 735b2f7..760dfe6 100644
--- a/lib/bcc/Script.cpp
+++ b/lib/bcc/Script.cpp
@@ -35,69 +35,10 @@
 
 namespace {
 
-// Input: cacheDir
-// Input: resName
-// Input: extName
-//
-// Note: cacheFile = resName + extName
-//
-// Output: Returns cachePath == cacheDir + cacheFile
-char *genCacheFileName(const char *cacheDir,
-                       const char *resName,
-                       const char *extName) {
-  char cachePath[512];
-  char cacheFile[sizeof(cachePath)];
-  const size_t kBufLen = sizeof(cachePath) - 1;
-
-  cacheFile[0] = '\0';
-  // Note: resName today is usually something like
-  //       "/com.android.fountain:raw/fountain"
-  if (resName[0] != '/') {
-    // Get the absolute path of the raw/***.bc file.
-
-    // Generate the absolute path.  This doesn't do everything it
-    // should, e.g. if resName is "./out/whatever" it doesn't crunch
-    // the leading "./" out because this if-block is not triggered,
-    // but it'll make do.
-    //
-    if (getcwd(cacheFile, kBufLen) == NULL) {
-      LOGE("Can't get CWD while opening raw/***.bc file\n");
-      return NULL;
-    }
-    // Append "/" at the end of cacheFile so far.
-    strncat(cacheFile, "/", kBufLen);
-  }
-
-  // cacheFile = resName + extName
-  //
-  strncat(cacheFile, resName, kBufLen);
-  if (extName != NULL) {
-    // TODO(srhines): strncat() is a bit dangerous
-    strncat(cacheFile, extName, kBufLen);
-  }
-
-  // Turn the path into a flat filename by replacing
-  // any slashes after the first one with '@' characters.
-  char *cp = cacheFile + 1;
-  while (*cp != '\0') {
-    if (*cp == '/') {
-      *cp = '@';
-    }
-    cp++;
-  }
-
-  // Tack on the file name for the actual cache file path.
-  strncpy(cachePath, cacheDir, kBufLen);
-  strncat(cachePath, cacheFile, kBufLen);
-
-  LOGV("Cache file for '%s' '%s' is '%s'\n", resName, extName, cachePath);
-  return strdup(cachePath);
-}
-
 bool getBooleanProp(const char *str) {
-    char buf[PROPERTY_VALUE_MAX];
-    property_get(str, buf, "0");
-    return strcmp(buf, "0") != 0;
+  char buf[PROPERTY_VALUE_MAX];
+  property_get(str, buf, "0");
+  return strcmp(buf, "0") != 0;
 }
 
 } // namespace anonymous
@@ -113,10 +54,10 @@
 }
 
 
-int Script::readBC(const char *bitcode,
+int Script::readBC(char const *resName,
+                   const char *bitcode,
                    size_t bitcodeSize,
-                   const BCCchar *resName,
-                   const BCCchar *cacheDir) {
+                   unsigned long flags) {
   if (mStatus != ScriptStatus::Unknown) {
     mErrorCode = BCC_INVALID_OPERATION;
     LOGE("Invalid operation: %s\n", __func__);
@@ -126,16 +67,13 @@
   sourceBC = bitcode;
   sourceResName = resName;
   sourceSize = bitcodeSize;
-
-  if (cacheDir && resName) {
-    cacheFile = genCacheFileName(cacheDir, resName, ".oBCC");
-  }
-
   return 0;
 }
 
 
-int Script::readModule(llvm::Module *module) {
+int Script::readModule(char const *resName,
+                       llvm::Module *module,
+                       unsigned long flags) {
   if (mStatus != ScriptStatus::Unknown) {
     mErrorCode = BCC_INVALID_OPERATION;
     LOGE("Invalid operation: %s\n", __func__);
@@ -147,7 +85,10 @@
 }
 
 
-int Script::linkBC(const char *bitcode, size_t bitcodeSize) {
+int Script::linkBC(char const *resName,
+                   const char *bitcode,
+                   size_t bitcodeSize,
+                   unsigned long flags) {
   if (mStatus != ScriptStatus::Unknown) {
     mErrorCode = BCC_INVALID_OPERATION;
     LOGE("Invalid operation: %s\n", __func__);
@@ -161,7 +102,7 @@
 }
 
 
-int Script::prepareExecutable() {
+int Script::prepareExecutable(char const *cachePath, unsigned long flags) {
   if (mStatus != ScriptStatus::Unknown) {
     mErrorCode = BCC_INVALID_OPERATION;
     LOGE("Invalid operation: %s\n", __func__);
@@ -169,7 +110,8 @@
   }
 
   // Load Cache File
-  if (cacheFile && internalLoadCache() == 0) {
+  mCachePath = cachePath;
+  if (cachePath && internalLoadCache() == 0) {
     return 0;
   }
 
@@ -185,21 +127,25 @@
     return 1;
   }
 
-  if (!cacheFile) {
-    // The application developer has not specify resName or cacheDir, so
+  if (!mCachePath) {
+    // The application developer has not specify the cachePath, so
     // we don't know where to open the cache file.
     return 1;
   }
 
+  // If we are going to use the cache file.  We have to calculate sha1sum
+  // first (no matter we can open the file now or not.)
   if (sourceBC) {
-    // If we are going to create cache file.  We have to calculate sha1sum
-    // first (no matter we can open the file now or not.)
     calcSHA1(sourceSHA1, sourceBC, sourceSize);
   }
 
+  //if (libraryBC) {
+  //  calcSHA1(librarySHA1, libraryBC, librarySize);
+  //}
+
   FileHandle file;
 
-  if (file.open(cacheFile, OpenMode::Read) < 0) {
+  if (file.open(mCachePath, OpenMode::Read) < 0) {
     // Unable to open the cache file in read mode.
     return 1;
   }
@@ -217,6 +163,10 @@
     reader.addDependency(BCC_APK_RESOURCE, sourceResName, sourceSHA1);
   }
 
+  //if (libraryBC) {
+  //  reader.addDependency(BCC_APK_RESOURCE, libraryResName, librarySHA1);
+  //}
+
   // Read cache file
   ScriptCached *cached = reader.readCacheFile(&file, this);
   if (!cached) {
@@ -256,24 +206,22 @@
 
   // Setup the source bitcode / module
   if (sourceBC) {
-    if (mCompiled->readBC(sourceBC, sourceSize, sourceResName, 0) != 0) {
+    if (mCompiled->readBC(sourceResName, sourceBC, sourceSize, 0) != 0) {
       LOGE("Unable to readBC, bitcode=%p, size=%lu\n",
            sourceBC, (unsigned long)sourceSize);
       return 1;
     }
-
     LOGI("Load sourceBC\n");
   } else if (sourceModule) {
-    if (mCompiled->readModule(sourceModule) != 0) {
+    if (mCompiled->readModule(NULL, sourceModule, 0) != 0) {
       return 1;
     }
-
     LOGI("Load sourceModule\n");
   }
 
   // Link the source module with the library module
   if (libraryBC) {
-    if (mCompiled->linkBC(libraryBC, librarySize) != 0) {
+    if (mCompiled->linkBC(NULL, libraryBC, librarySize, 0) != 0) {
       return 1;
     }
 
@@ -287,10 +235,10 @@
   }
 
   // TODO(logan): Write the cache out
-  if (cacheFile && !getBooleanProp("debug.bcc.nocache")) {
+  if (mCachePath && !getBooleanProp("debug.bcc.nocache")) {
     FileHandle file;
 
-    if (file.open(cacheFile, OpenMode::Write) >= 0) {
+    if (file.open(mCachePath, OpenMode::Write) >= 0) {
       CacheWriter writer;
 
       // Dependencies
@@ -316,9 +264,9 @@
         file.truncate();
         file.close();
 
-        if (unlink(cacheFile) != 0) {
+        if (unlink(mCachePath) != 0) {
           LOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
-               cacheFile, strerror(errno));
+               mCachePath, strerror(errno));
         }
       }
     }
@@ -439,12 +387,12 @@
 }
 
 
-void Script::getFuncNameList(size_t funcNameListSize,
-                             char const **funcNameList) {
+void Script::getFuncInfoList(size_t funcInfoListSize,
+                             FuncInfo *funcInfoList) {
   switch (mStatus) {
 #define DELEGATE(STATUS) \
   case ScriptStatus::STATUS: \
-    m##STATUS->getFuncNameList(funcNameListSize, funcNameList);
+    m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList);
     break;
 
   DELEGATE(Cached);
@@ -468,27 +416,7 @@
 }
 
 
-void Script::getFuncBinary(char const *funcname,
-                           void **base,
-                           size_t *length) {
-  switch (mStatus) {
-#define DELEGATE(STATUS) \
-  case ScriptStatus::STATUS: \
-    m##STATUS->getFuncBinary(funcname, base, length); \
-    break;
-
-  DELEGATE(Cached);
-  DELEGATE(Compiled);
-#undef DELEGATE
-
-  default:
-    *base = NULL;
-    *length = 0;
-  }
-}
-
-
-void Script::registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid *pContext) {
+void Script::registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
   mpExtSymbolLookupFn = pFn;
   mpExtSymbolLookupFnContext = pContext;
 
diff --git a/lib/bcc/Script.h b/lib/bcc/Script.h
index 7bbb36c..1965828 100644
--- a/lib/bcc/Script.h
+++ b/lib/bcc/Script.h
@@ -18,6 +18,7 @@
 #define BCC_SCRIPT_H
 
 #include <bcc/bcc.h>
+#include "bcc_internal.h"
 
 #include "Compiler.h"
 
@@ -41,7 +42,7 @@
 
   class Script {
   private:
-    BCCenum mErrorCode;
+    int mErrorCode;
 
     ScriptStatus::StatusType mStatus;
 
@@ -50,7 +51,7 @@
       ScriptCached *mCached;
     };
 
-    char *cacheFile;
+    char const *mCachePath;
 
     // ReadBC
     char const *sourceBC;
@@ -67,11 +68,11 @@
 
     // Register Symbol Lookup Function
     BCCSymbolLookupFn mpExtSymbolLookupFn;
-    BCCvoid *mpExtSymbolLookupFnContext;
+    void *mpExtSymbolLookupFnContext;
 
   public:
     Script() : mErrorCode(BCC_NO_ERROR), mStatus(ScriptStatus::Unknown),
-               cacheFile(NULL),
+               mCachePath(NULL),
                sourceBC(NULL), sourceResName(NULL), sourceSize(0),
                sourceModule(NULL), libraryBC(NULL), librarySize(0),
                mpExtSymbolLookupFn(NULL), mpExtSymbolLookupFnContext(NULL) {
@@ -80,16 +81,21 @@
 
     ~Script();
 
-    int readBC(const char *bitcode,
+    int readBC(char const *resName,
+               const char *bitcode,
                size_t bitcodeSize,
-               const BCCchar *resName,
-               const BCCchar *cacheDir);
+               unsigned long flags);
 
-    int readModule(llvm::Module *module);
+    int readModule(char const *resName,
+                   llvm::Module *module,
+                   unsigned long flags);
 
-    int linkBC(const char *bitcode, size_t bitcodeSize);
+    int linkBC(char const *resName,
+               const char *bitcode,
+               size_t bitcodeSize,
+               unsigned long flags);
 
-    int prepareExecutable();
+    int prepareExecutable(char const *cachePath, unsigned long flags);
 
     char const *getCompilerErrorMessage();
 
@@ -113,24 +119,22 @@
                        char const **keyList,
                        char const **valueList);
 
-    void getFuncNameList(size_t size, char const **list);
-
-    void getFuncBinary(char const *funcname, void **base, size_t *length);
+    void getFuncInfoList(size_t size, FuncInfo *list);
 
 
-    void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid *pContext);
+    void registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext);
 
     char *getContext();
 
 
-    void setError(BCCenum error) {
+    void setError(int error) {
       if (mErrorCode == BCC_NO_ERROR && error != BCC_NO_ERROR) {
         mErrorCode = error;
       }
     }
 
-    BCCenum getError() {
-      BCCenum result = mErrorCode;
+    int getError() {
+      int result = mErrorCode;
       mErrorCode = BCC_NO_ERROR;
       return result;
     }
diff --git a/lib/bcc/ScriptCached.cpp b/lib/bcc/ScriptCached.cpp
index 8011458..b4cf99d 100644
--- a/lib/bcc/ScriptCached.cpp
+++ b/lib/bcc/ScriptCached.cpp
@@ -22,7 +22,6 @@
 #include <bcc/bcc_cache.h>
 
 #include "ContextManager.h"
-#include "EmittedFuncInfo.h"
 
 #include <stdlib.h>
 
@@ -96,41 +95,25 @@
 }
 
 
-void ScriptCached::getFuncNameList(size_t funcNameListSize,
-                                   char const **funcNameList) {
-  if (funcNameList) {
+void ScriptCached::getFuncInfoList(size_t funcInfoListSize,
+                                   FuncInfo *funcInfoList) {
+  if (funcInfoList) {
     size_t funcCount = getFuncCount();
 
-    if (funcCount > funcNameListSize) {
-      funcCount = funcNameListSize;
+    if (funcCount > funcInfoListSize) {
+      funcCount = funcInfoListSize;
     }
 
+    FuncInfo *info = funcInfoList;
     for (FuncTable::const_iterator
          I = mFunctions.begin(), E = mFunctions.end();
-         I != E && funcCount > 0; I++, funcCount--) {
-      *funcNameList++ = I->first.c_str();
+         I != E && funcCount > 0; ++I, ++info, --funcCount) {
+      info->name = I->first.c_str();
+      info->addr = I->second.first;
+      info->size = I->second.second;
     }
   }
 }
 
 
-void ScriptCached::getFuncBinary(char const *funcname,
-                                 void **base,
-                                 size_t *length) {
-  FuncTable::const_iterator I = mFunctions.find(funcname);
-
-#define DEREF_ASSIGN(VAR, VALUE) if (VAR) { *(VAR) = (VALUE); }
-
-  if (I == mFunctions.end()) {
-    DEREF_ASSIGN(base, NULL);
-    DEREF_ASSIGN(length, 0);
-  } else {
-    DEREF_ASSIGN(base, I->second.first);
-    DEREF_ASSIGN(length, I->second.second);
-  }
-
-#undef DEREF_ASSIGN
-}
-
-
 } // namespace bcc
diff --git a/lib/bcc/ScriptCached.h b/lib/bcc/ScriptCached.h
index 49495dd..c484546 100644
--- a/lib/bcc/ScriptCached.h
+++ b/lib/bcc/ScriptCached.h
@@ -19,6 +19,7 @@
 
 #include <bcc/bcc.h>
 #include <bcc/bcc_cache.h>
+#include "bcc_internal.h"
 
 #include <llvm/ADT/SmallVector.h>
 
@@ -99,11 +100,7 @@
                        char const **keyList,
                        char const **valueList);
 
-    void getFuncNameList(size_t funcNameListSize, char const **funcNameList);
-
-    void getFuncBinary(char const *function,
-                       void **base,
-                       size_t *length);
+    void getFuncInfoList(size_t funcInfoListSize, FuncInfo *funcNameList);
 
 
     char *getContext() {
diff --git a/lib/bcc/ScriptCompiled.cpp b/lib/bcc/ScriptCompiled.cpp
index 9868580..052d2a7 100644
--- a/lib/bcc/ScriptCompiled.cpp
+++ b/lib/bcc/ScriptCompiled.cpp
@@ -19,8 +19,8 @@
 
 #include "ScriptCompiled.h"
 
+#include "bcc_internal.h"
 #include "ContextManager.h"
-#include "EmittedFuncInfo.h"
 
 namespace bcc {
 
@@ -31,7 +31,7 @@
   }
 
   // Delete the emitted function information
-  for (EmittedFunctionsMapTy::iterator I = mEmittedFunctions.begin(),
+  for (FuncInfoMap::iterator I = mEmittedFunctions.begin(),
        E = mEmittedFunctions.end(); I != E; I++) {
     if (I->second != NULL) {
       delete I->second;
@@ -92,46 +92,30 @@
 
 
 void *ScriptCompiled::lookup(const char *name) {
-  EmittedFunctionsMapTy::const_iterator I = mEmittedFunctions.find(name);
-  return (I == mEmittedFunctions.end()) ? NULL : I->second->Code;
+  FuncInfoMap::const_iterator I = mEmittedFunctions.find(name);
+  return (I == mEmittedFunctions.end()) ? NULL : I->second->addr;
 }
 
 
-void ScriptCompiled::getFuncNameList(size_t funcNameListSize,
-                                     char const **funcNameList) {
-  if (funcNameList) {
+void ScriptCompiled::getFuncInfoList(size_t funcInfoListSize,
+                                     FuncInfo *funcInfoList) {
+  if (funcInfoList) {
     size_t funcCount = getFuncCount();
 
-    if (funcCount > funcNameListSize) {
-      funcCount = funcNameListSize;
+    if (funcCount > funcInfoListSize) {
+      funcCount = funcInfoListSize;
     }
 
-    for (EmittedFunctionsMapTy::const_iterator
+    FuncInfo *info = funcInfoList;
+    for (FuncInfoMap::const_iterator
          I = mEmittedFunctions.begin(), E = mEmittedFunctions.end();
-         I != E && funcCount > 0; ++I, --funcCount) {
-      *funcNameList++ = I->first.c_str();
+         I != E && funcCount > 0; ++I, ++info, --funcCount) {
+      info->name = I->first.c_str();
+      info->addr = I->second->addr;
+      info->size = I->second->size;
     }
   }
 }
 
 
-void ScriptCompiled::getFuncBinary(char const *funcname,
-                                   void **base,
-                                   size_t *length) {
-  EmittedFunctionsMapTy::const_iterator I = mEmittedFunctions.find(funcname);
-
-#define DEREF_ASSIGN(VAR, VALUE) if (VAR) { *(VAR) = (VALUE); }
-
-  if (I == mEmittedFunctions.end()) {
-    DEREF_ASSIGN(base, NULL);
-    DEREF_ASSIGN(length, 0);
-  } else {
-    DEREF_ASSIGN(base, I->second->Code);
-    DEREF_ASSIGN(length, I->second->Size);
-  }
-
-#undef DEREF_ASSIGN
-}
-
-
 } // namespace bcc
diff --git a/lib/bcc/ScriptCompiled.h b/lib/bcc/ScriptCompiled.h
index a160b78..01af974 100644
--- a/lib/bcc/ScriptCompiled.h
+++ b/lib/bcc/ScriptCompiled.h
@@ -32,7 +32,6 @@
 }
 
 namespace bcc {
-  class EmittedFuncInfo;
   class Script;
 
   class ScriptCompiled {
@@ -43,7 +42,7 @@
     typedef std::list<std::pair<std::string, std::string> > PragmaList;
     typedef std::list<void*> ExportVarList;
     typedef std::list<void*> ExportFuncList;
-    typedef std::map<std::string, EmittedFuncInfo *> EmittedFunctionsMapTy;
+    typedef std::map<std::string, FuncInfo *> FuncInfoMap;
 
   private:
     Script *mpOwner;
@@ -54,7 +53,7 @@
     ExportFuncList mExportFuncs;
     PragmaList mPragmas;
 
-    EmittedFunctionsMapTy mEmittedFunctions;
+    FuncInfoMap mEmittedFunctions;
 
     char *mContext; // Context of BCC script (code and data)
 
@@ -65,14 +64,23 @@
 
     ~ScriptCompiled();
 
-    int readBC(const char *bitcode,
+    int readBC(char const *resName,
+               char const *bitcode,
                size_t bitcodeSize,
-               const BCCchar *resName,
-               const BCCchar *cacheDir) {
-      return mCompiler.readBC(bitcode, bitcodeSize, resName, cacheDir);
+               unsigned long flags) {
+      return mCompiler.readBC(bitcode, bitcodeSize);
     }
 
-    int linkBC(const char *bitcode, size_t bitcodeSize) {
+    int readModule(char const *resName,
+                   llvm::Module *module,
+                   unsigned long flags) {
+      return mCompiler.readModule(module);
+    }
+
+    int linkBC(char const *resName,
+               char const *bitcode,
+               size_t bitcodeSize,
+               unsigned long flags) {
       return mCompiler.linkBC(bitcode, bitcodeSize);
     }
 
@@ -112,23 +120,16 @@
                        char const **keyList,
                        char const **valueList);
 
-    void getFuncNameList(size_t funcNameListSize, char const **funcNameList);
-
-    void getFuncBinary(char const *function,
-                       void **base,
-                       size_t *length);
+    void getFuncInfoList(size_t funcInfoListSize,
+                         FuncInfo *funcInfoList);
 
     char *getContext() {
       return mContext;
     }
 
-    void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid *pContext) {
+    void registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
       mCompiler.registerSymbolCallback(pFn, pContext);
     }
-
-    int readModule(llvm::Module *module) {
-      return mCompiler.readModule(module);
-    }
   };
 
 } // namespace bcc
diff --git a/lib/bcc/bcc.cpp b/lib/bcc/bcc.cpp
index a52c8f9..bc7f16d 100644
--- a/lib/bcc/bcc.cpp
+++ b/lib/bcc/bcc.cpp
@@ -20,13 +20,16 @@
 #define LOG_TAG "bcc"
 #include <cutils/log.h>
 
+#include <bcc/bcc.h>
+#include "bcc_internal.h"
+
 #include "Compiler.h"
 #include "Script.h"
 
-#include <bcc/bcc.h>
-
 #include <utils/StopWatch.h>
 
+using namespace bcc;
+
 char const libbcc_build_time[24] = __DATE__ " " __TIME__;
 
 namespace bcc {
@@ -53,102 +56,100 @@
 }
 
 
-extern "C" BCCscript *bccCreateScript() {
+extern "C" BCCScriptRef bccCreateScript() {
   BCC_FUNC_LOGGER();
-  return new BCCscript();
+  return wrap(new bcc::Script());
 }
 
-extern "C" BCCenum bccGetError(BCCscript *script) {
+extern "C" void bccDisposeScript(BCCScriptRef script) {
   BCC_FUNC_LOGGER();
-  return script->getError();
+  delete unwrap(script);
 }
 
-extern "C" void bccDeleteScript(BCCscript *script) {
-  BCC_FUNC_LOGGER();
-  delete script;
-}
-
-extern "C" void bccRegisterSymbolCallback(BCCscript *script,
+extern "C" void bccRegisterSymbolCallback(BCCScriptRef script,
                                           BCCSymbolLookupFn pFn,
-                                          BCCvoid *pContext) {
+                                          void *pContext) {
   BCC_FUNC_LOGGER();
-  script->registerSymbolCallback(pFn, pContext);
+  return unwrap(script)->registerSymbolCallback(pFn, pContext);
 }
 
-extern "C" int bccReadModule(BCCscript *script, BCCvoid *module) {
+extern "C" int bccGetError(BCCScriptRef script) {
   BCC_FUNC_LOGGER();
-  return script->readModule(reinterpret_cast<llvm::Module*>(module));
+  return unwrap(script)->getError();
 }
 
-extern "C" int bccReadBC(BCCscript *script,
-                         const BCCchar *bitcode,
-                         BCCint bitcodeSize,
-                         long __DONT_USE_PARAM_1,
-                         long __DONT_USE_PARAM_2,
-                         const BCCchar *resName,
-                         const BCCchar *cacheDir) {
+
+extern "C" int bccReadBC(BCCScriptRef script,
+                         char const *resName,
+                         char const *bitcode,
+                         size_t bitcodeSize,
+                         unsigned long flags) {
   BCC_FUNC_LOGGER();
-  return script->readBC(bitcode, bitcodeSize, resName, cacheDir);
+  return unwrap(script)->readBC(resName, bitcode, bitcodeSize, flags);
 }
 
-extern "C" int bccLinkBC(BCCscript *script,
-                         const BCCchar *bitcode,
-                         BCCint size) {
+
+extern "C" int bccReadModule(BCCScriptRef script,
+                             char const *resName,
+                             LLVMModuleRef module,
+                             unsigned long flags) {
   BCC_FUNC_LOGGER();
-  return script->linkBC(bitcode, size);
+  return unwrap(script)->readModule(resName, unwrap(module), flags);
 }
 
-extern "C" int bccPrepareExecutable(BCCscript *script) {
+
+extern "C" int bccLinkBC(BCCScriptRef script,
+                         char const *resName,
+                         char const *bitcode,
+                         size_t bitcodeSize,
+                         unsigned long flags) {
   BCC_FUNC_LOGGER();
+  return unwrap(script)->linkBC(resName, bitcode, bitcodeSize, flags);
+}
+
+
+extern "C" int bccPrepareExecutable(BCCScriptRef script,
+                                    char const *cachePath,
+                                    unsigned long flags) {
+  BCC_FUNC_LOGGER();
+
 #if defined(__arm__)
   android::StopWatch compileTimer("bcc: PrepareExecutable time");
 #endif
 
-  int result = script->prepareExecutable();
-  if (result)
-    script->setError(BCC_INVALID_OPERATION);
-
-  return result;
+  return unwrap(script)->prepareExecutable(cachePath, flags);
 }
 
-extern "C" void bccGetScriptInfoLog(BCCscript *script,
-                                    BCCsizei maxLength,
-                                    BCCsizei *length,
-                                    BCCchar *infoLog) {
-  BCC_FUNC_LOGGER();
-  LOGE("%s is deprecated. *********************************\n", __func__);
-}
 
-extern "C" void bccGetScriptLabel(BCCscript *script,
-                                  const BCCchar *name,
-                                  BCCvoid **address) {
+extern "C" void *bccGetFuncAddr(BCCScriptRef script, char const *funcname) {
   BCC_FUNC_LOGGER();
-  void *value = script->lookup(name);
-  if (value) {
-    *address = value;
+
+  void *addr = unwrap(script)->lookup(funcname);
+
 #if defined(USE_DISASSEMBLER_FILE)
-    LOGI("[GetScriptLabel] %s @ 0x%x", name, value);
+  LOGD("Function Address: %s --> 0x%p\n", funcname, addr);
 #endif
-  } else {
-    script->setError(BCC_INVALID_VALUE);
-  }
+
+  return addr;
 }
 
-extern "C" void bccGetExportVars(BCCscript *script,
-                                 BCCsizei *actualCount,
-                                 BCCsizei varListSize,
-                                 BCCvoid **varList) {
-  BCC_FUNC_LOGGER();
 
-  if (actualCount) {
-    *actualCount = static_cast<BCCsizei>(script->getExportVarCount());
-  }
+extern "C" size_t bccGetExportVarCount(BCCScriptRef script) {
+  BCC_FUNC_LOGGER();
+  return unwrap(script)->getExportVarCount();
+}
+
+
+extern "C" void bccGetExportVarList(BCCScriptRef script,
+                                    size_t varListSize,
+                                    void **varList) {
+  BCC_FUNC_LOGGER();
 
   if (varList) {
-    script->getExportVarList(static_cast<size_t>(varListSize), varList);
+    unwrap(script)->getExportVarList(varListSize, varList);
 
 #if defined(USE_DISASSEMBLER_FILE)
-    size_t count = script->getExportVarCount();
+    size_t count = unwrap(script)->getExportVarCount();
     LOGD("ExportVarCount = %lu\n", (unsigned long)count);
 
     if (count > varListSize) {
@@ -162,21 +163,23 @@
   }
 }
 
-extern "C" void bccGetExportFuncs(BCCscript *script,
-                                  BCCsizei *actualCount,
-                                  BCCsizei funcListSize,
-                                  BCCvoid **funcList) {
+
+extern "C" size_t bccGetExportFuncCount(BCCScriptRef script) {
+  BCC_FUNC_LOGGER();
+  return unwrap(script)->getExportFuncCount();
+}
+
+
+extern "C" void bccGetExportFuncList(BCCScriptRef script,
+                                     size_t funcListSize,
+                                     void **funcList) {
   BCC_FUNC_LOGGER();
 
-  if (actualCount) {
-    *actualCount = static_cast<BCCsizei>(script->getExportFuncCount());
-  }
-
   if (funcList) {
-    script->getExportFuncList(static_cast<size_t>(funcListSize), funcList);
+    unwrap(script)->getExportFuncList(funcListSize, funcList);
 
 #if defined(USE_DISASSEMBLER_FILE)
-    size_t count = script->getExportFuncCount();
+    size_t count = unwrap(script)->getExportFuncCount();
     LOGD("ExportFuncCount = %lu\n", (unsigned long)count);
 
     if (count > funcListSize) {
@@ -190,37 +193,22 @@
   }
 }
 
-extern "C" void bccGetPragmas(BCCscript *script,
-                              BCCsizei *actualCount,
-                              BCCsizei stringListSize,
-                              BCCchar **stringList) {
+
+extern "C" size_t bccGetPragmaCount(BCCScriptRef script) {
   BCC_FUNC_LOGGER();
+  return unwrap(script)->getPragmaCount();
+}
 
-  if (actualCount) {
-    *actualCount = static_cast<BCCsizei>(script->getPragmaCount() * 2);
-  }
 
-  if (stringList) {
-    size_t pragmaListSize = static_cast<size_t>(stringListSize) / 2;
-
-    char const **buf = new (nothrow) char const *[pragmaListSize * 2];
-    if (!buf) {
-      return;
-    }
-
-    char const **keyList = buf;
-    char const **valueList = buf + pragmaListSize;
-
-    script->getPragmaList(pragmaListSize, keyList, valueList);
-
-    for (size_t i = 0; i < pragmaListSize; ++i) {
-      *stringList++ = const_cast<BCCchar *>(keyList[i]);
-      *stringList++ = const_cast<BCCchar *>(valueList[i]);
-    }
-
-    delete [] buf;
+extern "C" void bccGetPragmaList(BCCScriptRef script,
+                                 size_t pragmaListSize,
+                                 const char **keyList,
+                                 const char **valueList) {
+  BCC_FUNC_LOGGER();
+  unwrap(script)->getPragmaList(pragmaListSize, keyList, valueList);
 
 #if defined(USE_DISASSEMBLER_FILE)
+  if (keyList && valueList) {
     size_t count = script->getPragmaCount();
     LOGD("PragmaCount = %lu\n", count);
 
@@ -230,38 +218,25 @@
 
     for (size_t i = 0; i < count; ++i) {
       LOGD("Pragma[%lu] = (%s , %s)\n",
-           (unsigned long)i, stringList[2 * i], stringList[2 * i + 1]);
+           (unsigned long)i, keyList[i], valueList[i]);
     }
+  }
 #endif
-  }
 }
 
-extern "C" void bccGetFunctions(BCCscript *script,
-                                BCCsizei *actualCount,
-                                BCCsizei funcNameListSize,
-                                BCCchar **funcNameList) {
+
+extern "C" size_t bccGetFuncCount(BCCScriptRef script) {
   BCC_FUNC_LOGGER();
-
-  if (actualCount) {
-    *actualCount = static_cast<BCCsizei>(script->getFuncCount());
-  }
-
-  if (funcNameList) {
-    script->getFuncNameList(static_cast<size_t>(funcNameListSize),
-                            const_cast<char const **>(funcNameList));
-  }
+  return unwrap(script)->getFuncCount();
 }
 
-extern "C" void bccGetFunctionBinary(BCCscript *script,
-                                     BCCchar *funcname,
-                                     BCCvoid **base,
-                                     BCCsizei *length) {
+
+extern "C" void bccGetFuncInfoList(BCCScriptRef script,
+                                   size_t funcInfoListSize,
+                                   BCCFuncInfo *funcInfoList) {
   BCC_FUNC_LOGGER();
 
-  size_t funcLength = 0;
-  script->getFuncBinary(funcname, base, &funcLength);
-
-  if (length) {
-    *length = static_cast<BCCsizei>(funcLength);
+  if (funcInfoList) {
+    unwrap(script)->getFuncInfoList(funcInfoListSize, funcInfoList);
   }
 }
diff --git a/lib/bcc/bcc_internal.h b/lib/bcc/bcc_internal.h
new file mode 100644
index 0000000..af1b647
--- /dev/null
+++ b/lib/bcc/bcc_internal.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * 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 at
+ *
+ *     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.
+ */
+
+#ifndef BCC_INTERNAL_H
+#define BCC_INTERNAL_H
+
+#include <bcc/bcc.h>
+
+#if defined(__cplusplus)
+
+#define BCC_OPAQUE_TYPE_CONVERSION(TRANSPARENT_TYPE, OPAQUE_TYPE)           \
+  inline OPAQUE_TYPE wrap(TRANSPARENT_TYPE ptr) {                           \
+    return reinterpret_cast<OPAQUE_TYPE>(ptr);                              \
+  }                                                                         \
+                                                                            \
+  inline TRANSPARENT_TYPE unwrap(OPAQUE_TYPE ptr) {                         \
+    return reinterpret_cast<TRANSPARENT_TYPE>(ptr);                         \
+  }
+
+namespace llvm {
+  class Module;
+}
+
+namespace bcc {
+  class Script;
+
+  // Alias BCCFuncInfo to bcc::FuncInfo
+  typedef struct BCCFuncInfo FuncInfo;
+
+  BCC_OPAQUE_TYPE_CONVERSION(bcc::Script *, BCCScriptRef);
+  BCC_OPAQUE_TYPE_CONVERSION(llvm::Module *, LLVMModuleRef);
+
+} // namespace bcc
+
+#undef BCC_OPAQUE_TYPE_CONVERSION
+
+#endif // defined(__cplusplus)
+
+#endif // BCC_INTERNAL_H
diff --git a/tests/Android.mk b/tests/Android.mk
index 343cd4a..01475d7 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -22,14 +22,14 @@
 
 LOCAL_MODULE := bcc
 
-LOCAL_SRC_FILES:= \
-	main.cpp
+LOCAL_SRC_FILES := \
+  main.cpp
 
 LOCAL_SHARED_LIBRARIES := \
-	libbcc
+  libbcc
 
-LOCAL_C_INCLUDES :=	\
-	$(LOCAL_PATH)/../include
+LOCAL_C_INCLUDES := \
+  $(LOCAL_PATH)/../include
 
 LOCAL_MODULE_TAGS := tests
 
@@ -41,18 +41,18 @@
 # ========================================================
 include $(CLEAR_VARS)
 
-LOCAL_MODULE:= bcc
+LOCAL_MODULE := bcc
 
-LOCAL_SRC_FILES:= \
-	main.cpp \
-	disassem.cpp
+LOCAL_SRC_FILES := \
+  main.cpp \
+  disassem.cpp
 
-LOCAL_SHARED_LIBRARIES := \
-	libbcc	\
-	libdl
+LOCAL_SHARED_LIBRARIES := libdl libstlport libbcc
 
-LOCAL_C_INCLUDES :=	\
-	$(LOCAL_PATH)/../include
+LOCAL_C_INCLUDES := \
+  bionic \
+  external/stlport/stlport \
+  $(LOCAL_PATH)/../include
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/tests/main.cpp b/tests/main.cpp
index df6248e..6efbb08 100644
--- a/tests/main.cpp
+++ b/tests/main.cpp
@@ -39,76 +39,73 @@
 
 #include <bcc/bcc.h>
 
+#include <vector>
+
+
 typedef int (*MainPtr)(int, char**);
+
 // This is a separate function so it can easily be set by breakpoint in gdb.
-static int run(MainPtr mainFunc, int argc, char** argv)
-{
+static int run(MainPtr mainFunc, int argc, char** argv) {
   return mainFunc(argc, argv);
 }
 
-static BCCvoid* symbolLookup(BCCvoid* pContext, const BCCchar* name)
-{
-  return (BCCvoid*) dlsym(RTLD_DEFAULT, name);
+static void* lookupSymbol(void* pContext, const char* name) {
+  return (void*) dlsym(RTLD_DEFAULT, name);
 }
 
 #ifdef PROVIDE_ARM_DISASSEMBLY
 
 static FILE* disasmOut;
 
-static u_int
-disassemble_readword(u_int address)
-{
+static u_int disassemble_readword(u_int address) {
   return(*((u_int *)address));
 }
 
-static void
-disassemble_printaddr(u_int address)
-{
+static void disassemble_printaddr(u_int address) {
   fprintf(disasmOut, "0x%08x", address);
 }
 
-static void
-disassemble_printf(const char *fmt, ...) {
+static void disassemble_printf(const char *fmt, ...) {
   va_list ap;
   va_start(ap, fmt);
   vfprintf(disasmOut, fmt, ap);
   va_end(ap);
 }
 
-static int disassemble(BCCscript* script, FILE* out) {
+static int disassemble(BCCScriptRef script, FILE* out) {
   disasmOut = out;
   disasm_interface_t  di;
   di.di_readword = disassemble_readword;
   di.di_printaddr = disassemble_printaddr;
   di.di_printf = disassemble_printf;
 
-  BCCvoid* base;
-  BCCsizei length;
-
-  BCCsizei numFunctions;
-  bccGetFunctions(script, &numFunctions, 0, NULL);
+  size_t numFunctions = bccGetFuncCount(script);
+  fprintf(stderr, "Function Count: %lu\n", (unsigned long)numFunctions);
   if (numFunctions) {
-    char** labels = new char*[numFunctions];
-    bccGetFunctions(script, NULL, numFunctions, labels);
+    BCCFuncInfo *infos = new BCCFuncInfo[numFunctions];
+    bccGetFuncInfoList(script, numFunctions, infos);
 
-    for(BCCsizei i = 0; i < numFunctions; i++) {
-      bccGetFunctionBinary(script, labels[i], &base, &length);
+    for(size_t i = 0; i < numFunctions; i++) {
+      fprintf(stderr, "-----------------------------------------------------\n");
+      fprintf(stderr, "%s\n", infos[i].name);
+      fprintf(stderr, "-----------------------------------------------------\n");
 
-      unsigned long* pBase = (unsigned long*) base;
-      unsigned long* pEnd = (unsigned long*) (((unsigned char*) base) + length);
+      unsigned long* pBase = (unsigned long*) infos[i].addr;
+      unsigned long* pEnd =
+        (unsigned long*) (((unsigned char*) infos[i].addr) + infos[i].size);
 
       for(unsigned long* pInstruction = pBase; pInstruction < pEnd; pInstruction++) {
         fprintf(out, "%08x: %08x  ", (int) pInstruction, (int) *pInstruction);
         ::disasm(&di, (uint) pInstruction, 0);
       }
     }
-    delete[] labels;
+    delete [] infos;
   }
 
   return 1;
 }
 #else
-static int disassemble(BCCscript* script, FILE* out) {
+static int disassemble(BCCScriptRef script, FILE* out) {
   fprintf(stderr, "Disassembler not supported on this build.\n");
   return 1;
 }
@@ -158,11 +155,10 @@
   }
 
   inFile = argv[optind];
-
   return 1;
 }
 
-static BCCscript* loadScript() {
+static BCCScriptRef loadScript() {
   if (!inFile) {
     fprintf(stderr, "input file required\n");
     return NULL;
@@ -185,134 +181,99 @@
     return NULL;
   }
 
-  size_t codeSize = (size_t)statInFile.st_size;
-  BCCchar* bitcode = new BCCchar[codeSize + 1];
-  size_t bytesRead = fread(bitcode, 1, codeSize, in);
-  if (bytesRead != codeSize)
+  size_t bitcodeSize = statInFile.st_size;
+
+  std::vector<char> bitcode(bitcodeSize + 1, '\0');
+  size_t nread = fread(&*bitcode.begin(), 1, bitcodeSize, in);
+
+  if (nread != bitcodeSize)
       fprintf(stderr, "Could not read all of file %s\n", inFile);
 
-  BCCscript* script = bccCreateScript();
+  BCCScriptRef script = bccCreateScript();
 
-  bitcode[codeSize] = '\0'; /* must be null-terminated */
-  if (bccReadBC(script, bitcode, codeSize,
-                statInFile.st_mtime, 0, "file", "/tmp") != 0) {
+  if (bccReadBC(script, "file", &*bitcode.begin(), bitcodeSize, 0) != 0) {
     fprintf(stderr, "bcc: FAILS to read bitcode");
+    bccDisposeScript(script);
     return NULL;
   }
 
-  if (bccPrepareExecutable(script) != 0) {
-    fprintf(stderr, "bcc: FAILS to prepare executable");
+  bccRegisterSymbolCallback(script, lookupSymbol, NULL);
+
+  if (bccPrepareExecutable(script, "cache.oBCC", 0) != 0) {
+    fprintf(stderr, "bcc: FAILS to prepare executable.\n");
+    bccDisposeScript(script);
     return NULL;
   }
 
-  //delete [] bitcode;
-
   return script;
 }
 
-static int compile(BCCscript* script) {
-  bccRegisterSymbolCallback(script, symbolLookup, NULL);
+static void printPragma(BCCScriptRef script) {
+  size_t numPragma = bccGetPragmaCount(script);
+  if (numPragma) {
+    char const ** keyList = new char const *[numPragma];
+    char const ** valueList = new char const *[numPragma];
 
-  if (bccPrepareExecutable(script) != 0) {
-    fprintf(stderr, "Something wrong\n");
-  }
-
-  int result = bccGetError(script);
-  if (result != 0) {
-    BCCsizei bufferLength;
-    bccGetScriptInfoLog(script, 0, &bufferLength, NULL);
-    char* buf = (char*) malloc(bufferLength + 1);
-    if (buf != NULL) {
-        bccGetScriptInfoLog(script, bufferLength + 1, NULL, buf);
-        fprintf(stderr, "%s", buf);
-        free(buf);
-    } else {
-        fprintf(stderr, "Out of memory.\n");
+    bccGetPragmaList(script, numPragma, keyList, valueList);
+    for(size_t i = 0; i < numPragma; ++i) {
+      fprintf(stderr, "#pragma %s(%s)\n", keyList[i], valueList[i]);
     }
-    bccDeleteScript(script);
+
+    delete [] keyList;
+    delete [] valueList;
+  }
+}
+
+static int runMain(BCCScriptRef script, int argc, char** argv) {
+  MainPtr mainPointer = (MainPtr)bccGetFuncAddr(script, "root");
+
+  if (!mainPointer) {
+    fprintf(stderr, "Could not find root.\n");
     return 0;
   }
 
-  {
-    BCCsizei numPragmaStrings;
-    bccGetPragmas(script, &numPragmaStrings, 0, NULL);
-    if (numPragmaStrings) {
-      char** strings = new char*[numPragmaStrings];
-      bccGetPragmas(script, NULL, numPragmaStrings, strings);
-      for(BCCsizei i = 0; i < numPragmaStrings; i += 2)
-        fprintf(stderr, "#pragma %s(%s)\n", strings[i], strings[i+1]);
-      delete[] strings;
-    }
-  }
+  fprintf(stderr, "Executing compiled code:\n");
+
+  int argc1 = argc - optind;
+  char** argv1 = argv + optind;
+
+  int result = run(mainPointer, argc1, argv1);
+  fprintf(stderr, "result: %d\n", result);
 
   return 1;
 }
 
-static int runMain(BCCscript* script, int argc, char** argv) {
-  MainPtr mainPointer = 0;
-
-  bccGetScriptLabel(script, "root", (BCCvoid**) &mainPointer);
-
-  int result = bccGetError(script);
-  if (result != BCC_NO_ERROR) {
-    fprintf(stderr, "Could not find root: %d\n", result);
-  } else {
-    fprintf(stderr, "Executing compiled code:\n");
-    int codeArgc = argc - optind;
-    char** codeArgv = argv + optind;
-    //codeArgv[0] = (char*) (inFile ? inFile : "stdin");
-    result = run(mainPointer, codeArgc, codeArgv);
-    fprintf(stderr, "result: %d\n", result);
-  }
-
-  return 1;
-
-}
-
-int main(int argc, char** argv)
-{
-  int result = 0;
-  BCCscript* script;
-
+int main(int argc, char** argv) {
   if(!parseOption(argc, argv)) {
-    result = 1;
     fprintf(stderr, "failed to parse option\n");
-    goto exit;
+    return 1;
   }
 
+  BCCScriptRef script;
+
   if((script = loadScript()) == NULL) {
-    result = 2;
     fprintf(stderr, "failed to load source\n");
-    goto exit;
+    return 2;
   }
 
 #if 0
   if(printTypeInformation && !reflection(script, stderr)) {
-    result = 3;
     fprintf(stderr, "failed to retrieve type information\n");
-    goto exit;
+    return 3;
   }
 #endif
 
-  if(!compile(script)) {
-    result = 4;
-    fprintf(stderr, "failed to compile\n");
-    goto exit;
-  }
+  printPragma(script);
 
   if(printListing && !disassemble(script, stderr)) {
-    result = 5;
     fprintf(stderr, "failed to disassemble\n");
-    goto exit;
+    return 5;
   }
 
   if(runResults && !runMain(script, argc, argv)) {
-    result = 6;
     fprintf(stderr, "failed to execute\n");
-    goto exit;
+    return 6;
   }
 
-exit:
-
-  return result;
+  return 0;
 }