Addressed reviewer comments.
diff --git a/vm/Thread.c b/vm/Thread.c
index 8a4ae4b..7a8fc02 100644
--- a/vm/Thread.c
+++ b/vm/Thread.c
@@ -18,6 +18,7 @@
  * Thread support.
  */
 #include "Dalvik.h"
+#include "native/SystemThread.h"
 
 #include "utils/threads.h"      // need Android thread priorities
 
@@ -531,7 +532,7 @@
     u8 startWhen = 0;       // init req'd to placate gcc
     int sleepIter = 0;
     int cc;
-    
+
     do {
         cc = pthread_mutex_trylock(&gDvm._threadSuspendLock);
         if (cc != 0) {
@@ -2241,9 +2242,7 @@
 
     setThreadSelf(NULL);
 
-    if (self->statFile > 0) {
-        close(self->statFile);
-    }
+    dvmDetachSystemThread(self);
 
     freeThread(self);
 }
@@ -2429,7 +2428,7 @@
         char proc[100];
         sprintf(proc, "/proc/%d/exe", getpid());
         int len;
-        
+
         len = readlink(proc, exePath, sizeof(exePath)-1);
         exePath[len] = '\0';
     }
@@ -2670,7 +2669,7 @@
         /* wait for the other thread to see the pending suspend */
         waitForThreadSuspend(self, thread);
 
-        LOG_THREAD("threadid=%d:   threadid=%d status=%d c=%d dc=%d isSusp=%d\n", 
+        LOG_THREAD("threadid=%d:   threadid=%d status=%d c=%d dc=%d isSusp=%d\n",
             self->threadId,
             thread->threadId, thread->status, thread->suspendCount,
             thread->dbgSuspendCount, thread->isSuspended);
@@ -3877,122 +3876,10 @@
      * through the actual ThreadGroups, but it should be
      * equivalent.
      *
-     * This assumes that the ThreadGroup class object is in 
+     * This assumes that the ThreadGroup class object is in
      * the root set, which should always be true;  it's
      * loaded by the built-in class loader, which is part
      * of the root set.
      */
     gcScanAllThreads();
 }
-
-/* Converts a Linux thread state to a ThreadStatus. */
-static ThreadStatus stateToStatus(char state) {
-    switch (state) {
-        case 'R': return THREAD_RUNNING; // running
-        case 'S': return THREAD_WAIT;    // sleeping in interruptible wait
-        case 'D': return THREAD_WAIT;    // uninterruptible disk sleep
-        case 'Z': return THREAD_ZOMBIE;  // zombie
-        case 'T': return THREAD_WAIT;    // traced or stopped on a signal
-        case 'W': return THREAD_PAGING;  // paging memory
-        default:
-            LOGE("Unexpected state: %c", state);
-            return THREAD_NATIVE;
-    }
-}
-
-/* Reads the state char starting from the beginning of the file. */
-static char readStateFromBeginning(Thread* thread) {
-    char buffer[256];
-    int size = read(thread->statFile, buffer, sizeof(buffer));
-    if (size == 0) {
-        LOGE("EOF trying to read stat file.");
-        return 0;
-    }
-    char* endOfName = (char*) memchr(buffer, ')', sizeof(buffer));
-    if (endOfName == NULL) {
-        LOGE("End of executable name not found.");
-        return 0;
-    }
-    char* state = endOfName + 2;
-    thread->stateOffset = state - buffer;
-    if (*state == 0) {
-        LOGE("State char is 0.");
-    }
-    return *state;
-}
-
-/*
- * Looks for the state char at the last place we found it. Read from the
- * beginning if necessary.
- */
-static char readStateRelatively(Thread* thread) {
-    char buffer[3];
-    // Position file offset at end of executable name.
-    int result = lseek(thread->statFile, thread->stateOffset - 2, SEEK_SET);
-    if (result < 0) {
-        LOGE("lseek() error.");
-        return 0;
-    }
-    int size = read(thread->statFile, buffer, sizeof(buffer));
-    if (size < (int) sizeof(buffer)) {
-        LOGE("EOF trying to read stat file.");
-        return 0;
-    }
-    if (buffer[0] != ')') {
-        // The executable name must have changed.
-        result = lseek(thread->statFile, 0, SEEK_SET);
-        if (result < 0) {
-            LOGE("lseek() error.");
-            return 0;
-        }
-        return readStateFromBeginning(thread);
-    }
-    char state = buffer[2];
-    if (state == 0) {
-        LOGE("State char is 0.");
-    }
-    return state;
-}
-
-ThreadStatus dvmGetNativeThreadStatus(Thread* thread) {
-    // TODO: Add a custom hook so this just reads a char from memory.
-
-    ThreadStatus status = thread->status;
-    if (status != THREAD_NATIVE) {
-        // Return cached status so we don't accidentally return THREAD_NATIVE.
-        return status;
-    }
-
-    if (thread->statFile == -1) {
-        // We tried and failed to open the file earlier. Return current status.
-        return thread->status;
-    }
-
-    // Note: see "man proc" for the format of stat.
-    char state;
-    if (thread->statFile == 0) {
-        // We haven't tried to open the file yet. Do so.
-        char fileName[256];
-        sprintf(fileName, "/proc/self/task/%d/stat", thread->systemTid);
-        thread->statFile = open(fileName, O_RDONLY);
-        if (thread->statFile == NULL) {
-            LOGE("Error opening %s: %s", fileName, strerror(errno));
-            thread->statFile = -1;
-            return thread->status;
-        }
-        state = readStateFromBeginning(thread);
-    } else {
-        state = readStateRelatively(thread);
-    }
-
-    if (state == 0) {
-        close(thread->statFile);
-        thread->statFile = -1;
-        return thread->status;
-    }
-    ThreadStatus nativeStatus = stateToStatus(state);
-
-    // The thread status could have changed from NATIVE.
-    status = thread->status;
-    return status == THREAD_NATIVE ? nativeStatus : status;
-}