diff --git a/bitbake/lib/bb/ui/ncurses.py b/bitbake/lib/bb/ui/ncurses.py
new file mode 100644
index 0000000..9589a77
--- /dev/null
+++ b/bitbake/lib/bb/ui/ncurses.py
@@ -0,0 +1,373 @@
+#
+# BitBake Curses UI Implementation
+#
+# Implements an ncurses frontend for the BitBake utility.
+#
+# Copyright (C) 2006 Michael 'Mickey' Lauer
+# Copyright (C) 2006-2007 Richard Purdie
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+"""
+    We have the following windows:
+
+        1.) Main Window: Shows what we are ultimately building and how far we are. Includes status bar
+        2.) Thread Activity Window: Shows one status line for every concurrent bitbake thread.
+        3.) Command Line Window: Contains an interactive command line where you can interact w/ Bitbake.
+
+    Basic window layout is like that:
+
+        |---------------------------------------------------------|
+        | <Main Window>               | <Thread Activity Window>  |
+        |                             | 0: foo do_compile complete|
+        | Building Gtk+-2.6.10        | 1: bar do_patch complete  |
+        | Status: 60%                 | ...                       |
+        |                             | ...                       |
+        |                             | ...                       |
+        |---------------------------------------------------------|
+        |<Command Line Window>                                    |
+        |>>> which virtual/kernel                                 |
+        |openzaurus-kernel                                        |
+        |>>> _                                                    |
+        |---------------------------------------------------------|
+
+"""
+
+
+from __future__ import division
+import logging
+import os, sys, itertools, time, subprocess
+
+try:
+    import curses
+except ImportError:
+    sys.exit("FATAL: The ncurses ui could not load the required curses python module.")
+
+import bb
+import xmlrpclib
+from bb import ui
+from bb.ui import uihelper
+
+parsespin = itertools.cycle( r'|/-\\' )
+
+X = 0
+Y = 1
+WIDTH = 2
+HEIGHT = 3
+
+MAXSTATUSLENGTH = 32
+
+class NCursesUI:
+    """
+    NCurses UI Class
+    """
+    class Window:
+        """Base Window Class"""
+        def __init__( self, x, y, width, height, fg=curses.COLOR_BLACK, bg=curses.COLOR_WHITE ):
+            self.win = curses.newwin( height, width, y, x )
+            self.dimensions = ( x, y, width, height )
+            """
+            if curses.has_colors():
+                color = 1
+                curses.init_pair( color, fg, bg )
+                self.win.bkgdset( ord(' '), curses.color_pair(color) )
+            else:
+                self.win.bkgdset( ord(' '), curses.A_BOLD )
+            """
+            self.erase()
+            self.setScrolling()
+            self.win.noutrefresh()
+
+        def erase( self ):
+            self.win.erase()
+
+        def setScrolling( self, b = True ):
+            self.win.scrollok( b )
+            self.win.idlok( b )
+
+        def setBoxed( self ):
+            self.boxed = True
+            self.win.box()
+            self.win.noutrefresh()
+
+        def setText( self, x, y, text, *args ):
+            self.win.addstr( y, x, text, *args )
+            self.win.noutrefresh()
+
+        def appendText( self, text, *args ):
+            self.win.addstr( text, *args )
+            self.win.noutrefresh()
+
+        def drawHline( self, y ):
+            self.win.hline( y, 0, curses.ACS_HLINE, self.dimensions[WIDTH] )
+            self.win.noutrefresh()
+
+    class DecoratedWindow( Window ):
+        """Base class for windows with a box and a title bar"""
+        def __init__( self, title, x, y, width, height, fg=curses.COLOR_BLACK, bg=curses.COLOR_WHITE ):
+            NCursesUI.Window.__init__( self, x+1, y+3, width-2, height-4, fg, bg )
+            self.decoration = NCursesUI.Window( x, y, width, height, fg, bg )
+            self.decoration.setBoxed()
+            self.decoration.win.hline( 2, 1, curses.ACS_HLINE, width-2 )
+            self.setTitle( title )
+
+        def setTitle( self, title ):
+            self.decoration.setText( 1, 1, title.center( self.dimensions[WIDTH]-2 ), curses.A_BOLD )
+
+    #-------------------------------------------------------------------------#
+#    class TitleWindow( Window ):
+    #-------------------------------------------------------------------------#
+#        """Title Window"""
+#        def __init__( self, x, y, width, height ):
+#            NCursesUI.Window.__init__( self, x, y, width, height )
+#            version = bb.__version__
+#            title = "BitBake %s" % version
+#            credit = "(C) 2003-2007 Team BitBake"
+#            #self.win.hline( 2, 1, curses.ACS_HLINE, width-2 )
+#            self.win.border()
+#            self.setText( 1, 1, title.center( self.dimensions[WIDTH]-2 ), curses.A_BOLD )
+#            self.setText( 1, 2, credit.center( self.dimensions[WIDTH]-2 ), curses.A_BOLD )
+
+    #-------------------------------------------------------------------------#
+    class ThreadActivityWindow( DecoratedWindow ):
+    #-------------------------------------------------------------------------#
+        """Thread Activity Window"""
+        def __init__( self, x, y, width, height ):
+            NCursesUI.DecoratedWindow.__init__( self, "Thread Activity", x, y, width, height )
+
+        def setStatus( self, thread, text ):
+            line = "%02d: %s" % ( thread, text )
+            width = self.dimensions[WIDTH]
+            if ( len(line) > width ):
+                line = line[:width-3] + "..."
+            else:
+                line = line.ljust( width )
+            self.setText( 0, thread, line )
+
+    #-------------------------------------------------------------------------#
+    class MainWindow( DecoratedWindow ):
+    #-------------------------------------------------------------------------#
+        """Main Window"""
+        def __init__( self, x, y, width, height ):
+            self.StatusPosition = width - MAXSTATUSLENGTH
+            NCursesUI.DecoratedWindow.__init__( self, None, x, y, width, height )
+            curses.nl()
+
+        def setTitle( self, title ):
+            title = "BitBake %s" % bb.__version__
+            self.decoration.setText( 2, 1, title, curses.A_BOLD )
+            self.decoration.setText( self.StatusPosition - 8, 1, "Status:", curses.A_BOLD )
+
+        def setStatus(self, status):
+            while len(status) < MAXSTATUSLENGTH:
+                status = status + " "
+            self.decoration.setText( self.StatusPosition, 1, status, curses.A_BOLD )
+
+
+    #-------------------------------------------------------------------------#
+    class ShellOutputWindow( DecoratedWindow ):
+    #-------------------------------------------------------------------------#
+        """Interactive Command Line Output"""
+        def __init__( self, x, y, width, height ):
+            NCursesUI.DecoratedWindow.__init__( self, "Command Line Window", x, y, width, height )
+
+    #-------------------------------------------------------------------------#
+    class ShellInputWindow( Window ):
+    #-------------------------------------------------------------------------#
+        """Interactive Command Line Input"""
+        def __init__( self, x, y, width, height ):
+            NCursesUI.Window.__init__( self, x, y, width, height )
+
+# put that to the top again from curses.textpad import Textbox
+#            self.textbox = Textbox( self.win )
+#            t = threading.Thread()
+#            t.run = self.textbox.edit
+#            t.start()
+
+    #-------------------------------------------------------------------------#
+    def main(self, stdscr, server, eventHandler, params):
+    #-------------------------------------------------------------------------#
+        height, width = stdscr.getmaxyx()
+
+        # for now split it like that:
+        # MAIN_y + THREAD_y = 2/3 screen at the top
+        # MAIN_x = 2/3 left, THREAD_y = 1/3 right
+        # CLI_y = 1/3 of screen at the bottom
+        # CLI_x = full
+
+        main_left = 0
+        main_top = 0
+        main_height = ( height // 3 * 2 )
+        main_width = ( width // 3 ) * 2
+        clo_left = main_left
+        clo_top = main_top + main_height
+        clo_height = height - main_height - main_top - 1
+        clo_width = width
+        cli_left = main_left
+        cli_top = clo_top + clo_height
+        cli_height = 1
+        cli_width = width
+        thread_left = main_left + main_width
+        thread_top = main_top
+        thread_height = main_height
+        thread_width = width - main_width
+
+        #tw = self.TitleWindow( 0, 0, width, main_top )
+        mw = self.MainWindow( main_left, main_top, main_width, main_height )
+        taw = self.ThreadActivityWindow( thread_left, thread_top, thread_width, thread_height )
+        clo = self.ShellOutputWindow( clo_left, clo_top, clo_width, clo_height )
+        cli = self.ShellInputWindow( cli_left, cli_top, cli_width, cli_height )
+        cli.setText( 0, 0, "BB>" )
+
+        mw.setStatus("Idle")
+
+        helper = uihelper.BBUIHelper()
+        shutdown = 0
+
+        try:
+            params.updateFromServer(server)
+            cmdline = params.parseActions()
+            if not cmdline:
+                print("Nothing to do.  Use 'bitbake world' to build everything, or run 'bitbake --help' for usage information.")
+                return 1
+            if 'msg' in cmdline and cmdline['msg']:
+                logger.error(cmdline['msg'])
+                return 1
+            cmdline = cmdline['action']
+            ret, error = server.runCommand(cmdline)
+            if error:
+                print("Error running command '%s': %s" % (cmdline, error))
+                return
+            elif ret != True:
+                print("Couldn't get default commandlind! %s" % ret)
+                return
+        except xmlrpclib.Fault as x:
+            print("XMLRPC Fault getting commandline:\n %s" % x)
+            return
+
+        exitflag = False
+        while not exitflag:
+            try:
+                event = eventHandler.waitEvent(0.25)
+                if not event:
+                    continue
+
+                helper.eventHandler(event)
+                if isinstance(event, bb.build.TaskBase):
+                    mw.appendText("NOTE: %s\n" % event._message)
+                if isinstance(event, logging.LogRecord):
+                    mw.appendText(logging.getLevelName(event.levelno) + ': ' + event.getMessage() + '\n')
+
+                if isinstance(event, bb.event.CacheLoadStarted):
+                    self.parse_total = event.total
+                if isinstance(event, bb.event.CacheLoadProgress):
+                    x = event.current
+                    y = self.parse_total
+                    mw.setStatus("Loading Cache:   %s [%2d %%]" % ( next(parsespin), x*100/y ) )
+                if isinstance(event, bb.event.CacheLoadCompleted):
+                    mw.setStatus("Idle")
+                    mw.appendText("Loaded %d entries from dependency cache.\n"
+                                % ( event.num_entries))
+
+                if isinstance(event, bb.event.ParseStarted):
+                    self.parse_total = event.total
+                if isinstance(event, bb.event.ParseProgress):
+                    x = event.current
+                    y = self.parse_total
+                    mw.setStatus("Parsing Recipes: %s [%2d %%]" % ( next(parsespin), x*100/y ) )
+                if isinstance(event, bb.event.ParseCompleted):
+                    mw.setStatus("Idle")
+                    mw.appendText("Parsing finished. %d cached, %d parsed, %d skipped, %d masked.\n"
+                                % ( event.cached, event.parsed, event.skipped, event.masked ))
+
+#                if isinstance(event, bb.build.TaskFailed):
+#                    if event.logfile:
+#                        if data.getVar("BBINCLUDELOGS", d):
+#                            bb.error("log data follows (%s)" % logfile)
+#                            number_of_lines = data.getVar("BBINCLUDELOGS_LINES", d)
+#                            if number_of_lines:
+#                                subprocess.call('tail -n%s %s' % (number_of_lines, logfile), shell=True)
+#                            else:
+#                                f = open(logfile, "r")
+#                                while True:
+#                                    l = f.readline()
+#                                    if l == '':
+#                                        break
+#                                    l = l.rstrip()
+#                                    print '| %s' % l
+#                                f.close()
+#                        else:
+#                            bb.error("see log in %s" % logfile)
+
+                if isinstance(event, bb.command.CommandCompleted):
+                    # stop so the user can see the result of the build, but
+                    # also allow them to now exit with a single ^C
+                    shutdown = 2
+                if isinstance(event, bb.command.CommandFailed):
+                    mw.appendText("Command execution failed: %s" % event.error)
+                    time.sleep(2)
+                    exitflag = True
+                if isinstance(event, bb.command.CommandExit):
+                    exitflag = True
+                if isinstance(event, bb.cooker.CookerExit):
+                    exitflag = True
+
+                if isinstance(event, bb.event.LogExecTTY):
+                    mw.appendText('WARN: ' + event.msg + '\n')
+                if helper.needUpdate:
+                    activetasks, failedtasks = helper.getTasks()
+                    taw.erase()
+                    taw.setText(0, 0, "")
+                    if activetasks:
+                        taw.appendText("Active Tasks:\n")
+                        for task in activetasks.itervalues():
+                            taw.appendText(task["title"] + '\n')
+                    if failedtasks:
+                        taw.appendText("Failed Tasks:\n")
+                        for task in failedtasks:
+                            taw.appendText(task["title"] + '\n')
+
+                curses.doupdate()
+            except EnvironmentError as ioerror:
+                # ignore interrupted io
+                if ioerror.args[0] == 4:
+                    pass
+
+            except KeyboardInterrupt:
+                if shutdown == 2:
+                    mw.appendText("Third Keyboard Interrupt, exit.\n")
+                    exitflag = True
+                if shutdown == 1:
+                    mw.appendText("Second Keyboard Interrupt, stopping...\n")
+                    _, error = server.runCommand(["stateForceShutdown"])
+                    if error:
+                        print("Unable to cleanly stop: %s" % error)
+                if shutdown == 0:
+                    mw.appendText("Keyboard Interrupt, closing down...\n")
+                    _, error = server.runCommand(["stateShutdown"])
+                    if error:
+                        print("Unable to cleanly shutdown: %s" % error)
+                shutdown = shutdown + 1
+                pass
+
+def main(server, eventHandler, params):
+    if not os.isatty(sys.stdout.fileno()):
+        print("FATAL: Unable to run 'ncurses' UI without a TTY.")
+        return
+    ui = NCursesUI()
+    try:
+        curses.wrapper(ui.main, server, eventHandler, params)
+    except:
+        import traceback
+        traceback.print_exc()
