diff --git a/libs/utils/BufferedTextOutput.cpp b/libs/utils/BufferedTextOutput.cpp
new file mode 100644
index 0000000..989662e
--- /dev/null
+++ b/libs/utils/BufferedTextOutput.cpp
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2006 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.
+ */
+
+#include <utils/BufferedTextOutput.h>
+
+#include <utils/Atomic.h>
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+#include <cutils/threads.h>
+
+#include <private/utils/Static.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+struct BufferedTextOutput::BufferState : public RefBase
+{
+    BufferState(int32_t _seq)
+        : seq(_seq)
+        , buffer(NULL)
+        , bufferPos(0)
+        , bufferSize(0)
+        , atFront(true)
+        , indent(0)
+        , bundle(0) {
+    }
+    ~BufferState() {
+        free(buffer);
+    }
+    
+    status_t append(const char* txt, size_t len) {
+        if ((len+bufferPos) > bufferSize) {
+            void* b = realloc(buffer, ((len+bufferPos)*3)/2);
+            if (!b) return NO_MEMORY;
+            buffer = (char*)b;
+        }
+        memcpy(buffer+bufferPos, txt, len);
+        bufferPos += len;
+        return NO_ERROR;
+    }
+    
+    void restart() {
+        bufferPos = 0;
+        atFront = true;
+        if (bufferSize > 256) {
+            void* b = realloc(buffer, 256);
+            if (b) {
+                buffer = (char*)b;
+                bufferSize = 256;
+            }
+        }
+    }
+    
+    const int32_t seq;
+    char* buffer;
+    size_t bufferPos;
+    size_t bufferSize;
+    bool atFront;
+    int32_t indent;
+    int32_t bundle;
+};
+
+struct BufferedTextOutput::ThreadState
+{
+    Vector<sp<BufferedTextOutput::BufferState> > states;
+};
+
+static mutex_t          gMutex;
+
+static thread_store_t   tls;
+
+BufferedTextOutput::ThreadState* BufferedTextOutput::getThreadState()
+{
+    ThreadState*  ts = (ThreadState*) thread_store_get( &tls );
+    if (ts) return ts;
+    ts = new ThreadState;
+    thread_store_set( &tls, ts, threadDestructor );
+    return ts;
+}
+
+void BufferedTextOutput::threadDestructor(void *st)
+{
+    delete ((ThreadState*)st);
+}
+
+static volatile int32_t gSequence = 0;
+
+static volatile int32_t gFreeBufferIndex = -1;
+
+static int32_t allocBufferIndex()
+{
+    int32_t res = -1;
+    
+    mutex_lock(&gMutex);
+    
+    if (gFreeBufferIndex >= 0) {
+        res = gFreeBufferIndex;
+        gFreeBufferIndex = gTextBuffers[res];
+        gTextBuffers.editItemAt(res) = -1;
+
+    } else {
+        res = gTextBuffers.size();
+        gTextBuffers.add(-1);
+    }
+
+    mutex_unlock(&gMutex);
+    
+    return res;
+}
+
+static void freeBufferIndex(int32_t idx)
+{
+    mutex_lock(&gMutex);
+    gTextBuffers.editItemAt(idx) = gFreeBufferIndex;
+    gFreeBufferIndex = idx;
+    mutex_unlock(&gMutex);
+}
+
+// ---------------------------------------------------------------------------
+
+BufferedTextOutput::BufferedTextOutput(uint32_t flags)
+    : mFlags(flags)
+    , mSeq(android_atomic_inc(&gSequence))
+    , mIndex(allocBufferIndex())
+{
+    mGlobalState = new BufferState(mSeq);
+    if (mGlobalState) mGlobalState->incStrong(this);
+}
+    
+BufferedTextOutput::~BufferedTextOutput()
+{
+    if (mGlobalState) mGlobalState->decStrong(this);
+    freeBufferIndex(mIndex);
+}
+
+status_t BufferedTextOutput::print(const char* txt, size_t len)
+{
+    //printf("BufferedTextOutput: printing %d\n", len);
+    
+    AutoMutex _l(mLock);
+    BufferState* b = getBuffer();
+    
+    const char* const end = txt+len;
+    
+    status_t err;
+
+    while (txt < end) {
+        // Find the next line.
+        const char* first = txt;
+        while (txt < end && *txt != '\n') txt++;
+        
+        // Include this and all following empty lines.
+        while (txt < end && *txt == '\n') txt++;
+        
+        // Special cases for first data on a line.
+        if (b->atFront) {
+            if (b->indent > 0) {
+                // If this is the start of a line, add the indent.
+                const char* prefix = stringForIndent(b->indent);
+                err = b->append(prefix, strlen(prefix));
+                if (err != NO_ERROR) return err;
+                
+            } else if (*(txt-1) == '\n' && !b->bundle) {
+                // Fast path: if we are not indenting or bundling, and
+                // have been given one or more complete lines, just write
+                // them out without going through the buffer.
+                
+                // Slurp up all of the lines.
+                const char* lastLine = txt+1;
+                while (txt < end) {
+                    if (*txt++ == '\n') lastLine = txt;
+                }
+                struct iovec vec;
+                vec.iov_base = (void*)first;
+                vec.iov_len = lastLine-first;
+                //printf("Writing %d bytes of data!\n", vec.iov_len);
+                writeLines(vec, 1);
+                txt = lastLine;
+                continue;
+            }
+        }
+        
+        // Append the new text to the buffer.
+        err = b->append(first, txt-first);
+        if (err != NO_ERROR) return err;
+        b->atFront = *(txt-1) == '\n';
+        
+        // If we have finished a line and are not bundling, write
+        // it out.
+        //printf("Buffer is now %d bytes\n", b->bufferPos);
+        if (b->atFront && !b->bundle) {
+            struct iovec vec;
+            vec.iov_base = b->buffer;
+            vec.iov_len = b->bufferPos;
+            //printf("Writing %d bytes of data!\n", vec.iov_len);
+            writeLines(vec, 1);
+            b->restart();
+        }
+    }
+    
+    return NO_ERROR;
+}
+
+void BufferedTextOutput::moveIndent(int delta)
+{
+    AutoMutex _l(mLock);
+    BufferState* b = getBuffer();
+    b->indent += delta;
+    if (b->indent < 0) b->indent = 0;
+}
+
+void BufferedTextOutput::pushBundle()
+{
+    AutoMutex _l(mLock);
+    BufferState* b = getBuffer();
+    b->bundle++;
+}
+
+void BufferedTextOutput::popBundle()
+{
+    AutoMutex _l(mLock);
+    BufferState* b = getBuffer();
+    b->bundle--;
+    LOG_FATAL_IF(b->bundle < 0,
+        "TextOutput::popBundle() called more times than pushBundle()");
+    if (b->bundle < 0) b->bundle = 0;
+    
+    if (b->bundle == 0) {
+        // Last bundle, write out data if it is complete.  If it is not
+        // complete, don't write until the last line is done... this may
+        // or may not be the write thing to do, but it's the easiest.
+        if (b->bufferPos > 0 && b->atFront) {
+            struct iovec vec;
+            vec.iov_base = b->buffer;
+            vec.iov_len = b->bufferPos;
+            writeLines(vec, 1);
+            b->restart();
+        }
+    }
+}
+
+BufferedTextOutput::BufferState* BufferedTextOutput::getBuffer() const
+{
+    if ((mFlags&MULTITHREADED) != 0) {
+        ThreadState* ts = getThreadState();
+        if (ts) {
+            while (ts->states.size() <= (size_t)mIndex) ts->states.add(NULL);
+            BufferState* bs = ts->states[mIndex].get();
+            if (bs != NULL && bs->seq == mSeq) return bs;
+            
+            ts->states.editItemAt(mIndex) = new BufferState(mIndex);
+            bs = ts->states[mIndex].get();
+            if (bs != NULL) return bs;
+        }
+    }
+    
+    return mGlobalState;
+}
+
+}; // namespace android
