diff --git a/LibClang.cabal b/LibClang.cabal
--- a/LibClang.cabal
+++ b/LibClang.cabal
@@ -1,6 +1,6 @@
 Name: LibClang
 Cabal-version: >= 1.6
-Version: 0.0.6
+Version: 0.0.7
 Author: Chetan Taralekar <chetant@gmail.com>
 Maintainer: Chetan Taralekar <chetant@gmail.com>
 Homepage: https://github.com/chetant/LibClang/issues
@@ -33,9 +33,8 @@
 
 Library
   build-depends: base < 5, ffi, greencard
-  build-tools: greencard
   extensions: TypeSynonymInstances, EmptyDataDecls
   hs-source-dirs: src
   c-sources: src/Clang/FFI_stub_ffi.c
   exposed-modules:
-    Clang,Clang.FFI,Clang.Type,Clang.Cursor,Clang.CrossReference,Clang.Source,Clang.Diagnostic,Clang.TranslationUnit,Clang.Token,Clang.Debug,Clang.Completion
+    Clang,Clang.FFI,Clang.Type,Clang.Cursor,Clang.CrossReference,Clang.Source,Clang.Diagnostic,Clang.TranslationUnit,Clang.Token,Clang.Debug,Clang.Completion,Clang.File,Clang.Traversal
diff --git a/configure b/configure
--- a/configure
+++ b/configure
@@ -1405,94 +1405,6 @@
 
 } # ac_fn_c_try_compile
 
-# ac_fn_c_try_link LINENO
-# -----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_link ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext conftest$ac_exeext
-  if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    grep -v '^ *+' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-    mv -f conftest.er1 conftest.err
-  fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext && {
-	 test "$cross_compiling" = yes ||
-	 $as_test_x conftest$ac_exeext
-       }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_retval=1
-fi
-  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
-  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
-  # interfere with the next link command; also delete a directory that is
-  # left behind by Apple's compiler.  We do this before executing the actions.
-  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_link
-
-# ac_fn_c_try_run LINENO
-# ----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
-# that executables *can* be run.
-ac_fn_c_try_run ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
-  { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: program exited with status $ac_status" >&5
-       $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_retval=$ac_status
-fi
-  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_run
-
 # ac_fn_c_try_cpp LINENO
 # ----------------------
 # Try to preprocess conftest.$ac_ext, and return whether this succeeded.
@@ -1617,6 +1529,48 @@
 
 } # ac_fn_c_check_header_mongrel
 
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
 # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
 # -------------------------------------------------------
 # Tests whether HEADER exists and can be compiled using the include files in
@@ -1647,6 +1601,52 @@
   eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
 
 } # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
@@ -2068,14 +2068,7 @@
 	fi
 fi
 
-# Check whether --enable-llvm-shared was given.
-if test "${enable_llvm_shared+set}" = set; then :
-  enableval=$enable_llvm_shared; llvm_shared=$enableval
-fi
-
-if test "$llvm_shared" != ""
-then
-	ac_ext=c
+ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
@@ -2866,96 +2859,6 @@
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-as_ac_Lib=`$as_echo "ac_cv_lib_${llvm_shared}''_LLVMContextCreate" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LLVMContextCreate in -l${llvm_shared}" >&5
-$as_echo_n "checking for LLVMContextCreate in -l${llvm_shared}... " >&6; }
-if eval "test \"\${$as_ac_Lib+set}\"" = set; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-l${llvm_shared}  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char LLVMContextCreate ();
-int
-main ()
-{
-return LLVMContextCreate ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  eval "$as_ac_Lib=yes"
-else
-  eval "$as_ac_Lib=no"
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-eval ac_res=\$$as_ac_Lib
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
-  llvm_shared_lib_found=yes
-else
-  llvm_shared_lib_found=no
-fi
-
-	if test "$llvm_shared_lib_found" = no
-	then
-		as_fn_error $? "
-	-------------------------------------------------
-	llvm shared library ${llvm_shared} not found.
-	if the library is present, ensure it is available
-	on the lib search path (export LDFLAGS=...)
-	-------------------------------------------------" "$LINENO" 5
-	else
-		LDFLAGS="$LDFLAGS -l${llvm_shared}"
-		if test "$cross_compiling" = yes; then :
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run test program while cross compiling
-See \`config.log' for more details" "$LINENO" 5 ; }
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-int main(int argc, int argv[]){LLVMContextCreate();return 0;}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-  llvm_shared_lib_present=yes
-else
-  llvm_shared_lib_present=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-		if test "$llvm_shared_lib_present" = no
-		then
-		as_fn_error $? "
-	-------------------------------------------------------
-	specified llvm shared library ${llvm_shared} not found.
-	if the library is present, ensure it is available
-	on the lib search path (export LID_LIBRARY_PATH=...)
-	-------------------------------------------------------" "$LINENO" 5
-		fi
-	fi
-else
-	if test "$llvm_config_found" = yes
-	then
-		LDFLAGS="$LDFLAGS `llvm-config --libs`"
-	fi
-fi
-
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -3381,6 +3284,103 @@
 	-------------------------------------------------" "$LINENO" 5
 fi
 
+# Check whether --enable-llvm-shared was given.
+if test "${enable_llvm_shared+set}" = set; then :
+  enableval=$enable_llvm_shared; llvm_shared=$enableval
+fi
+
+if test "$llvm_shared" != ""
+then
+	as_ac_Lib=`$as_echo "ac_cv_lib_${llvm_shared}''_LLVMContextCreate" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LLVMContextCreate in -l${llvm_shared}" >&5
+$as_echo_n "checking for LLVMContextCreate in -l${llvm_shared}... " >&6; }
+if eval "test \"\${$as_ac_Lib+set}\"" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l${llvm_shared}  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char LLVMContextCreate ();
+int
+main ()
+{
+return LLVMContextCreate ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+  llvm_shared_lib_found=yes
+else
+  llvm_shared_lib_found=no
+fi
+
+	if test "$llvm_shared_lib_found" = no
+	then
+		as_fn_error $? "
+	-------------------------------------------------
+	llvm shared library ${llvm_shared} not found.
+	if the library is present, ensure it is available
+	on the lib search path (export LDFLAGS=...)
+	-------------------------------------------------" "$LINENO" 5
+	else
+		LDFLAGS="$LDFLAGS -l${llvm_shared}"
+		if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5 ; }
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int main(int argc, int argv[]){LLVMContextCreate();return 0;}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  llvm_shared_lib_present=yes
+else
+  llvm_shared_lib_present=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+		if test "$llvm_shared_lib_present" = no
+		then
+		as_fn_error $? "
+	-------------------------------------------------------
+	specified llvm shared library ${llvm_shared} not found.
+	if the library is present, ensure it is available
+	on the lib search path (export LID_LIBRARY_PATH=...)
+	-------------------------------------------------------" "$LINENO" 5
+		fi
+	fi
+else
+	if test "$llvm_config_found" = yes
+	then
+		LDFLAGS="$LDFLAGS `llvm-config --libs`"
+	fi
+fi
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clang_getClangVersion in -lclang" >&5
 $as_echo_n "checking for clang_getClangVersion in -lclang... " >&6; }
 if test "${ac_cv_lib_clang_clang_getClangVersion+set}" = set; then :
@@ -3445,7 +3445,7 @@
 	as_fn_error $? "Cannot find inttypes.h" "$LINENO" 5
 fi
 
-ac_config_files="$ac_config_files LibClang.buildinfo"
+ac_config_files="$ac_config_files LibClang.buildinfo test/Makefile"
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -4153,6 +4153,7 @@
 do
   case $ac_config_target in
     "LibClang.buildinfo") CONFIG_FILES="$CONFIG_FILES LibClang.buildinfo" ;;
+    "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
 
   *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
   esac
diff --git a/src/Clang/Cursor.hs b/src/Clang/Cursor.hs
--- a/src/Clang/Cursor.hs
+++ b/src/Clang/Cursor.hs
@@ -12,7 +12,7 @@
 
 ,nullCursor
 ,getHash
-,getKind
+,Clang.Cursor.getKind
 ,getLinkage
 ,getAvailability
 ,getLanguage
@@ -32,6 +32,7 @@
 ,getCanonicalCursor
 ,getTemplateKind
 ,getSpecializedTemplate
+,getTranslationUnitCursor
 
 -- attribute function
 ,getIBOutletCollectionType
@@ -92,6 +93,7 @@
 getCanonicalCursor = unsafePerformIO . FFI.getCanonicalCursor
 getTemplateKind = unsafePerformIO . FFI.getTemplateCursorKind
 getSpecializedTemplate = unsafePerformIO . FFI.getSpecializedCursorTemplate
+getTranslationUnitCursor = unsafePerformIO . FFI.getTranslationUnitCursor
 
 -- attribute function
 getIBOutletCollectionType = unsafePerformIO . FFI.getIBOutletCollectionType
diff --git a/src/Clang/FFI.gc b/src/Clang/FFI.gc
--- a/src/Clang/FFI.gc
+++ b/src/Clang/FFI.gc
@@ -93,6 +93,7 @@
 ,getCursorExtent
 ,TypeKind(..)
 ,Type
+,getTypeKind
 ,getCursorType
 ,equalTypes
 ,getCanonicalType
@@ -186,10 +187,10 @@
 
 -- typedef void *CXIndex;
 data IndexObj
-type Index = ForeignPtr IndexObj
+type Index = Ptr IndexObj
 
 -- CXIndex clang_createIndex(int excludeDeclarationsFromPCH, int displayDiagnostics);
-%fun clang_createIndex :: Bool -> Bool -> IO Index
+%fun clang_createIndex :: Bool -> Bool -> IO (ForeignPtr IndexObj)
 %call (bool a) (bool b)
 %code CXIndex r = clang_createIndex(a, b);
 %result (index (ptr r))
@@ -202,13 +203,13 @@
 
 -- typedef struct CXTranslationUnitImpl *CXTranslationUnit;
 data TranslationUnitObj
-type TranslationUnit = ForeignPtr TranslationUnitObj
+type TranslationUnit = Ptr TranslationUnitObj
 
 -- void clang_disposeTranslationUnit(CXTranslationUnit);
-foreign import ccall unsafe "clang-c/Index.h &clang_disposeTranslationUnit" clang_disposeTranslationUnit :: FunPtr (Ptr TranslationUnitObj -> IO ())
+foreign import ccall unsafe "clang-c/Index.h &clang_disposeTranslationUnit" clang_disposeTranslationUnitPtr :: FunPtr (Ptr TranslationUnitObj -> IO ())
 
 unmarshall_translationUnit :: Ptr TranslationUnitObj -> IO (ForeignPtr TranslationUnitObj)
-unmarshall_translationUnit = newForeignPtr clang_disposeTranslationUnit
+unmarshall_translationUnit = newForeignPtr clang_disposeTranslationUnitPtr
 
 -- typedef void *CXClientData;
 data ClientDataObj
@@ -267,7 +268,7 @@
 
 -- CXFile clang_getFile(CXTranslationUnit tu, const char *file_name);
 %fun clang_getFile :: TranslationUnit -> String -> IO File
-%call (fptr (ptr t)) (string s)
+%call (ptr t) (string s)
 %code CXFile r = clang_getFile(t, s);
 %result (file r)
 
@@ -318,7 +319,7 @@
 --                                                   unsigned line,
 --                                                   unsigned column);
 %fun clang_getLocation :: TranslationUnit -> File -> Int -> Int -> IO SourceLocation
-%call (fptr (ptr t)) (file f) (int i) (int j)
+%call (ptr t) (file f) (int i) (int j)
 %code CXSourceLocation r = clang_getLocation((CXTranslationUnit)t, f, i, j);
 %result (sourceLocation {r.ptr_data[0]} {r.ptr_data[1]} {r.int_data})
 
@@ -326,7 +327,7 @@
 --                                                            CXFile file,
 --                                                            unsigned offset);
 %fun clang_getLocationForOffset :: TranslationUnit -> File -> Int -> IO SourceLocation
-%call (fptr (ptr t)) (file f) (int i)
+%call (ptr t) (file f) (int i)
 %code CXSourceLocation r = clang_getLocationForOffset((CXTranslationUnit)t, f, i);
 %result (sourceLocation {r.ptr_data[0]} {r.ptr_data[1]} {r.int_data})
 
@@ -402,13 +403,13 @@
 
 -- unsigned clang_getNumDiagnostics(CXTranslationUnit Unit);
 %fun clang_getNumDiagnostics :: TranslationUnit -> IO Int
-%call (fptr (ptr t))
+%call (ptr t)
 %code unsigned r = clang_getNumDiagnostics((CXTranslationUnit)t);
 %result (int r)
 
 -- CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index);
 %fun clang_getDiagnostic :: TranslationUnit -> Int -> IO Diagnostic
-%call (fptr (ptr t)) (int i)
+%call (ptr t) (int i)
 %code CXDiagnostic r = clang_getDiagnostic((CXTranslationUnit)t, i);
 %result (diag (ptr r))
 
@@ -498,7 +499,7 @@
 -- CXString
 -- clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit);
 %fun clang_getTranslationUnitSpelling :: TranslationUnit -> IO CXString
-%call (fptr (ptr t))
+%call (ptr t)
 %code CXString *r = mkStrObj();*r = clang_getTranslationUnitSpelling(t);
 %result (cxString (ptr r))
 
@@ -509,15 +510,15 @@
 --                                    const char * const *clang_command_line_args,
 --                                          unsigned num_unsaved_files,
 --                                          struct CXUnsavedFile *unsaved_files);
-%fun clang_createTranslationUnitFromSourceFile :: Index -> String -> [String] -> [UnsavedFile] -> IO TranslationUnit
-%call (fptr (ptr i)) (string s) (listLenString ((fptr (ptr ss)), (int ns))) (listLenUnsavedFile ((fptr (ptr ufs)), (int nufs)))
+%fun clang_createTranslationUnitFromSourceFile :: Index -> String -> [String] -> [UnsavedFile] -> IO (ForeignPtr TranslationUnitObj)
+%call (ptr i) (string s) (listLenString ((fptr (ptr ss)), (int ns))) (listLenUnsavedFile ((fptr (ptr ufs)), (int nufs)))
 %code r = clang_createTranslationUnitFromSourceFile(i,s,ns,ss,nufs,ufs);
 %result (translationUnit (ptr r))
 
 -- CXTranslationUnit clang_createTranslationUnit(CXIndex,
 --                                              const char *ast_filename);
-%fun clang_createTranslationUnit :: Index -> String -> IO TranslationUnit
-%call (fptr (ptr i)) (string s)
+%fun clang_createTranslationUnit :: Index -> String -> IO (ForeignPtr TranslationUnitObj)
+%call (ptr i) (string s)
 %code CXTranslationUnit r = clang_createTranslationUnit(i, s);
 %result (translationUnit (ptr r))
 
@@ -554,8 +555,8 @@
 --                                             struct CXUnsavedFile *unsaved_files,
 --                                                      unsigned num_unsaved_files,
 --                                                             unsigned options);
-%fun clang_parseTranslationUnit :: Index -> Maybe String -> [String] -> [UnsavedFile] -> Int -> IO (Maybe TranslationUnit)
-%call (fptr (ptr i)) (maybeT {nullPtr} (string s)) (listLenString ((fptr (ptr ss)), (int ns))) (listLenUnsavedFile ((fptr (ptr ufs)), (int nufs))) (int i2)
+%fun clang_parseTranslationUnit :: Index -> Maybe String -> [String] -> [UnsavedFile] -> Int -> IO (Maybe (ForeignPtr TranslationUnitObj))
+%call (ptr i) (maybeT {nullPtr} (string s)) (listLenString ((fptr (ptr ss)), (int ns))) (listLenUnsavedFile ((fptr (ptr ufs)), (int nufs))) (int i2)
 %code r = clang_parseTranslationUnit(i,s,ss,ns,ufs,nufs,i2);
 %result (maybeT {nullPtr} (translationUnit (ptr r)))
 
@@ -606,7 +607,7 @@
 
 -- unsigned clang_defaultSaveOptions(CXTranslationUnit TU);
 %fun clang_defaultSaveOptions :: TranslationUnit -> IO Int
-%call (fptr (ptr t))
+%call (ptr t)
 %code r = clang_defaultSaveOptions(t);
 %result (int r)
 
@@ -614,7 +615,7 @@
 --                                              const char *FileName,
 --                                              unsigned options);
 %fun clang_saveTranslationUnit :: TranslationUnit -> String -> Int -> IO Bool
-%call (fptr (ptr t)) (string s) (int i)
+%call (ptr t) (string s) (int i)
 %code unsigned r = clang_saveTranslationUnit(t, s, i);
 %result (bool {r!=0?0:1})
 
@@ -629,7 +630,7 @@
 
 -- unsigned clang_defaultReparseOptions(CXTranslationUnit TU);
 %fun clang_defaultReparseOptions :: TranslationUnit -> IO Int
-%call (fptr (ptr t))
+%call (ptr t)
 %code r = clang_defaultReparseOptions(t);
 %result (int r)
 
@@ -638,7 +639,7 @@
 --                                           struct CXUnsavedFile *unsaved_files,
 --                                                 unsigned options);
 %fun clang_reparseTranslationUnit :: TranslationUnit -> [UnsavedFile] -> Int -> IO Bool
-%call (fptr (ptr t)) (listLenUnsavedFile ((fptr (ptr ufs)), (int nufs))) (int i)
+%call (ptr t) (listLenUnsavedFile ((fptr (ptr ufs)), (int nufs))) (int i)
 %code r = clang_reparseTranslationUnit(t, nufs, ufs, i);
 %result (bool r)
 
@@ -746,7 +747,7 @@
 
 -- CXCursor clang_getTranslationUnitCursor(CXTranslationUnit);
 %fun clang_getTranslationUnitCursor :: TranslationUnit -> IO Cursor
-%call (fptr (ptr t))
+%call (ptr t)
 %code CXCursor r = clang_getTranslationUnitCursor(t);
 %result (cursor {r.kind} {r.data[0]} {r.data[1]} {r.data[2]})
 
@@ -910,7 +911,7 @@
   
 -- CXCursor clang_getCursor(CXTranslationUnit, CXSourceLocation);
 %fun clang_getCursor :: TranslationUnit -> SourceLocation -> IO Cursor
-%call (fptr (ptr t)) (sourceLocation p1 p2 d)
+%call (ptr t) (sourceLocation p1 p2 d)
 %code CXSourceLocation l = {{p1, p2}, d};
 %     CXCursor r = clang_getCursor(t, l);
 %result (cursor {r.kind} {r.data[0]} {r.data[1]} {r.data[2]})
@@ -985,6 +986,8 @@
 data Type = Type TypeKind (Ptr ()) (Ptr ())
 %dis type k p1 p2 = Type (typeKind k) (ptr p1) (ptr p2)
 
+getTypeKind (Type k _ _) = k
+
 -- CXType clang_getCursorType(CXCursor C);
 %fun clang_getCursorType :: Cursor -> IO Type
 %call (cursor k p1 p2 p3)
@@ -1327,7 +1330,7 @@
 
 -- CXString clang_getTokenSpelling(CXTranslationUnit, CXToken);
 %fun clang_getTokenSpelling :: TranslationUnit -> Token -> IO CXString
-%call (fptr (ptr t)) (token w x y z p)
+%call (ptr t) (token w x y z p)
 %code CXToken a = {{w, x, y, z}, p};
 %     CXString *r = mkStrObj();*r = clang_getTokenSpelling(t, a);
 %result (cxString (ptr r))
@@ -1335,14 +1338,14 @@
 -- CXSourceLocation clang_getTokenLocation(CXTranslationUnit,
 --                                                        CXToken);
 %fun clang_getTokenLocation :: TranslationUnit -> Token -> IO SourceLocation
-%call (fptr (ptr t)) (token w x y z p)
+%call (ptr t) (token w x y z p)
 %code CXToken a = {{w, x, y, z}, p};
 %     CXSourceLocation r = clang_getTokenLocation(t, a);
 %result (sourceLocation {r.ptr_data[0]} {r.ptr_data[1]} {r.int_data})
 
 -- CXSourceRange clang_getTokenExtent(CXTranslationUnit, CXToken);
 %fun clang_getTokenExtent :: TranslationUnit -> Token -> IO SourceRange
-%call (fptr (ptr t)) (token w x y z p)
+%call (ptr t) (token w x y z p)
 %code CXToken a = {{w, x, y, z}, p};
 %     CXSourceRange r = clang_getTokenExtent(t, a);
 %result (sourceRange {r.ptr_data[0]} {r.ptr_data[1]} {r.begin_int_data} {r.end_int_data})
@@ -1393,7 +1396,7 @@
 -- void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
 --                                    CXToken **Tokens, unsigned *NumTokens);
 %fun clang_tokenize :: TranslationUnit -> SourceRange -> IO TokenList
-%call (fptr (ptr t)) (sourceRange p1 p2 d1 d2)
+%call (ptr t) (sourceRange p1 p2 d1 d2)
 %code CXSourceRange a = {{p1, p2}, d1, d2};
 %     CXToken * tokens;unsigned numTokens;
 %     clang_tokenize(t, a, &tokens, &numTokens);
@@ -1417,7 +1420,7 @@
 --                                          CXToken *Tokens, unsigned NumTokens,
 --                                          CXCursor *Cursors);
 %fun clang_annotateTokens :: TranslationUnit -> TokenList -> IO CursorList
-%call (fptr (ptr t)) (tokenList ((int nts), (fptr (ptr ts))))
+%call (ptr t) (tokenList ((int nts), (fptr (ptr ts))))
 %code CXCursor * cs = (CXCursor *)malloc(sizeof(CXCursor)*nts);
 %     clang_annotateTokens(t, ts, nts, cs);
 %result (cursorListExt nts (ptr cs))
@@ -1545,7 +1548,7 @@
 --                                             unsigned num_unsaved_files,
 --                                             unsigned options);
 %fun clang_codeCompleteAt :: TranslationUnit -> String -> Int -> Int -> [UnsavedFile] -> Int -> IO CodeCompleteResults
-%call (fptr (ptr t)) (string s) (int i1) (int i2) (listLenUnsavedFile ((fptr (ptr ufs)), (int nufs))) (int i3)
+%call (ptr t) (string s) (int i1) (int i2) (listLenUnsavedFile ((fptr (ptr ufs)), (int nufs))) (int i3)
 %code r = clang_codeCompleteAt(t, s, i1, i2, ufs, nufs, i3)
 %result (codeCompleteResults (ptr r))
 
@@ -1588,12 +1591,11 @@
 type InclusionVisitor = File -> [SourceLocation] -> Ptr () -> IO ()
 
 -- %fun clang_getInclusions :: TranslationUnit -> InclusionVisitor -> Ptr () -> IO ()
--- %call (fptr (ptr t)) (inclusionVisitor (ptr f)) (ptr p)
+-- %call (ptr t) (inclusionVisitor (ptr f)) (ptr p)
 -- %code clang_getInclusions(t, f, p);
 
 getInclusions :: TranslationUnit -> InclusionVisitor -> Ptr () -> IO ()
-getInclusions tu iv p =
-  (marshall_fptr tu) >>= \ (t) ->
+getInclusions t iv p =
   (marshall_inclusionVisitor iv) >>= \ (f) ->
   prim_getInclusions_ t f p >> freeHaskellFunPtr f
 
diff --git a/src/Clang/File.hs b/src/Clang/File.hs
new file mode 100644
--- /dev/null
+++ b/src/Clang/File.hs
@@ -0,0 +1,16 @@
+module Clang.File
+(
+ FFI.UnsavedFile
+,FFI.File
+,
+) where
+
+import Control.Monad((>=>))
+import System.IO.Unsafe(unsafePerformIO)
+import qualified Clang.FFI as FFI
+
+getFileName :: FFI.File -> FilePath
+getFileName = unsafePerformIO . (FFI.getFileName >=> FFI.getCString)
+getFileTime = unsafePerformIO . FFI.getFileTime
+getFile :: FFI.TranslationUnit -> FilePath -> FFI.File
+getFile t f = unsafePerformIO $ FFI.getFile t f
diff --git a/src/Clang/Token.hs b/src/Clang/Token.hs
--- a/src/Clang/Token.hs
+++ b/src/Clang/Token.hs
@@ -1,7 +1,7 @@
 module Clang.Token
 (
  FFI.Token
-,getKind
+,Clang.Token.getKind
 ,getSpelling
 ,Clang.Token.getLocation
 ,getExtent
diff --git a/src/Clang/TranslationUnit.hs b/src/Clang/TranslationUnit.hs
--- a/src/Clang/TranslationUnit.hs
+++ b/src/Clang/TranslationUnit.hs
@@ -3,11 +3,11 @@
  FFI.Index
 ,FFI.TranslationUnitFlags(..)
 ,FFI.SaveTranslationUnitFlags(..)
-,create
-,createIndex
 ,getSpelling
-,createFromSourceFile
-,parse
+,withCreateIndex
+,withCreate
+,withCreateFromSourceFile
+,withParse
 ,defaultSaveOptions
 ,save
 ,defaultReparseOptions
@@ -17,27 +17,34 @@
 import System.IO.Unsafe(unsafePerformIO)
 import Data.Bits((.&.))
 import Data.Maybe(catMaybes)
-import Control.Monad(mzero)
+import Control.Monad(mzero, (<=<))
+import Foreign.ForeignPtr(withForeignPtr)
 
 import Clang.Type
 import Clang.Source
 import qualified Clang.FFI as FFI
 
 getSpelling = unsafePerformIO . FFI.getTranslationUnitSpelling
-create = FFI.createTranslationUnit
-createFromSourceFile :: FFI.Index -- ^ Index for the source
+withCreate i s f = flip withForeignPtr f =<< FFI.createTranslationUnit i s
+
+withCreateFromSourceFile :: FFI.Index -- ^ Index for the source
                      -> FilePath -- ^ Source filename
                      -> [String] -- ^ Command line arguments ( this can include all clang compatible flags)
                      -> [FFI.UnsavedFile] -- ^ Unsaved files
-                     -> IO FFI.TranslationUnit
-createFromSourceFile = FFI.createTranslationUnitFromSourceFile
-parse :: FFI.Index -- ^ Index for the source
+                     -> (FFI.TranslationUnit -> IO a) -- ^ Function that will process the TranslationUnit
+                     -> IO a
+withCreateFromSourceFile i fn ss ufs f = flip withForeignPtr f =<< FFI.createTranslationUnitFromSourceFile i fn ss ufs
+
+withParse :: FFI.Index -- ^ Index for the source
       -> Maybe FilePath -- ^ Source filename
       -> [String] -- ^ Command line arguments ( this can include all clang compatible flags)
       -> [FFI.UnsavedFile] -- ^ Unsaved files
       -> [FFI.TranslationUnitFlags] -- ^ TranslationUnit flags
-      -> IO (Maybe FFI.TranslationUnit)
-parse i ms ss ufs opts = FFI.parseTranslationUnit i ms ss ufs (FFI.getTranslationUnitFlagsSum opts)
+      -> (FFI.TranslationUnit -> IO a) -- ^ Function that will process the TranslationUnit
+      -> IO a -- ^ Result to be returned if source couldn't be parsed
+      -> IO a
+withParse i ms ss ufs opts f nr = maybe nr (flip withForeignPtr f) =<< 
+                                  FFI.parseTranslationUnit i ms ss ufs (FFI.getTranslationUnitFlagsSum opts)
 
 -- No other option right now
 defaultSaveOptions = [FFI.SaveTranslationUnit_None]
@@ -50,8 +57,6 @@
 
 -- No other option right now
 defaultReparseOptions = [FFI.Reparse_None]
-    -- where defVal = unsafePerformIO . FFI.defaultReparseOptions
-    --       val1 v = if (v .&. 0x1) == 0x1 then return FFI.Diagnostic_DisplaySourceLocation else mzero
 
 reparse :: FFI.TranslationUnit -- ^ TranslationUnit to save
         -> [FFI.UnsavedFile] -- ^ All the unsaved files
@@ -60,4 +65,4 @@
 reparse t ufs opts = FFI.reparseTranslationUnit t ufs (FFI.getReparseFlagsSum opts)
 
 -- index functions
-createIndex = FFI.createIndex
+withCreateIndex i1 i2 f = flip withForeignPtr f =<< FFI.createIndex i1 i2
diff --git a/src/Clang/Traversal.hs b/src/Clang/Traversal.hs
new file mode 100644
--- /dev/null
+++ b/src/Clang/Traversal.hs
@@ -0,0 +1,14 @@
+module Clang.Traversal
+(
+ annotateTokens
+,FFI.ChildVisitor
+,FFI.ChildVisitResult(..)
+,FFI.visitChildren
+) where
+
+import qualified Clang.FFI as FFI
+
+annotateTokens :: FFI.TranslationUnit -- ^ The translation unit related to the tokens
+               -> [FFI.Token] -- ^ Token list that you want cursors for
+               -> IO [FFI.Cursor] -- ^ Cursors corresponding to the tokens
+annotateTokens = FFI.annotateTokens
diff --git a/src/Clang/Type.hs b/src/Clang/Type.hs
--- a/src/Clang/Type.hs
+++ b/src/Clang/Type.hs
@@ -5,6 +5,7 @@
 ,FFI.TypeKind(..)
 ,FFI.CXXAccessSpecifier(..)
 
+,getKind
 ,getCanonicalType
 ,getPointeeType
 ,getResultType
@@ -14,6 +15,7 @@
 ,isRestrictQualifiedType
 ,isPODType
 ,isVirtualBase
+,getTypeKindSpelling
 )
 where
 
@@ -25,6 +27,8 @@
 
 instance Eq FFI.Type where
     a == b = unsafePerformIO (FFI.equalTypes a b)
+
+getKind = FFI.getTypeKind
 
 getCanonicalType = unsafePerformIO . FFI.getCanonicalType
 getPointeeType = unsafePerformIO . FFI.getPointeeType
