diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp
new file mode 100644
index 0000000..6b2e3b2
--- /dev/null
+++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp
@@ -0,0 +1,830 @@
+//===-- ScriptInterpreterPython.cpp -----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// In order to guarantee correct working with Python, Python.h *MUST* be
+// the *FIRST* header file included:
+
+#include <Python.h>
+
+#include "lldb/Interpreter/ScriptInterpreterPython.h"
+
+
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <string>
+
+#include "lldb/Breakpoint/Breakpoint.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/FileSpec.h"
+#include "lldb/Core/InputReader.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/Timer.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Target/Process.h"
+
+extern "C" void init_lldb (void);
+
+using namespace lldb;
+using namespace lldb_private;
+
+const char embedded_interpreter_string[] =
+"import readline\n\
+import code\n\
+import sys\n\
+import traceback\n\
+\n\
+class SimpleREPL(code.InteractiveConsole):\n\
+   def __init__(self, prompt, dict):\n\
+       code.InteractiveConsole.__init__(self,dict)\n\
+       self.prompt = prompt\n\
+       self.loop_exit = False\n\
+       self.dict = dict\n\
+\n\
+   def interact(self):\n\
+       try:\n\
+           sys.ps1\n\
+       except AttributeError:\n\
+           sys.ps1 = \">>> \"\n\
+       try:\n\
+           sys.ps2\n\
+       except AttributeError:\n\
+           sys.ps2 = \"... \"\n\
+\n\
+       while not self.loop_exit:\n\
+           try:\n\
+               self.read_py_command()\n\
+           except (SystemExit, EOFError):\n\
+               # EOF while in Python just breaks out to top level.\n\
+               self.write('\\n')\n\
+               self.loop_exit = True\n\
+               break\n\
+           except KeyboardInterrupt:\n\
+               self.write(\"\\nKeyboardInterrupt\\n\")\n\
+               self.resetbuffer()\n\
+               more = 0\n\
+           except:\n\
+               traceback.print_exc()\n\
+\n\
+   def process_input (self, in_str):\n\
+      # Canonicalize the format of the input string\n\
+      temp_str = in_str\n\
+      temp_str.strip(' \t')\n\
+      words = temp_str.split()\n\
+      temp_str = ('').join(words)\n\
+\n\
+      # Check the input string to see if it was the quit\n\
+      # command.  If so, intercept it, so that it doesn't\n\
+      # close stdin on us!\n\
+      if (temp_str.lower() == \"quit()\"):\n\
+         self.loop_exit = True\n\
+         in_str = \"raise SystemExit \"\n\
+      return in_str\n\
+\n\
+   def my_raw_input (self, prompt):\n\
+      stream = sys.stdout\n\
+      stream.write (prompt)\n\
+      stream.flush ()\n\
+      try:\n\
+         line = sys.stdin.readline()\n\
+      except KeyboardInterrupt:\n\
+         line = \" \\n\"\n\
+      except (SystemExit, EOFError):\n\
+         line = \"quit()\\n\"\n\
+      if not line:\n\
+         raise EOFError\n\
+      if line[-1] == '\\n':\n\
+         line = line[:-1]\n\
+      return line\n\
+\n\
+   def read_py_command(self):\n\
+       # Read off a complete Python command.\n\
+       more = 0\n\
+       while 1:\n\
+           if more:\n\
+               prompt = sys.ps2\n\
+           else:\n\
+               prompt = sys.ps1\n\
+           line = self.my_raw_input(prompt)\n\
+           # Can be None if sys.stdin was redefined\n\
+           encoding = getattr(sys.stdin, \"encoding\", None)\n\
+           if encoding and not isinstance(line, unicode):\n\
+               line = line.decode(encoding)\n\
+           line = self.process_input (line)\n\
+           more = self.push(line)\n\
+           if not more:\n\
+               break\n\
+\n\
+def run_python_interpreter (dict):\n\
+   # Pass in the dictionary, for continuity from one session to the next.\n\
+   repl = SimpleREPL('>>> ', dict)\n\
+   repl.interact()\n";
+
+static int
+_check_and_flush (FILE *stream)
+{
+  int prev_fail = ferror (stream);
+  return fflush (stream) || prev_fail ? EOF : 0;
+}
+
+ScriptInterpreterPython::ScriptInterpreterPython () :
+    ScriptInterpreter (eScriptLanguagePython),
+    m_compiled_module (NULL),
+    m_termios_valid (false)
+{
+
+    Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
+    // Find the module that owns this code and use that path we get to
+    // set the PYTHONPATH appropriately.
+
+    FileSpec this_module (Host::GetModuleFileSpecForHostAddress ((void *)init_lldb));
+    std::string python_path;
+
+    if (this_module.GetDirectory())
+    {
+        // Append the directory that the module that loaded this code
+        // belongs to
+        python_path += this_module.GetDirectory().AsCString("");
+
+#if defined (__APPLE__)
+        // If we are running on MacOSX we might be in a framework and should
+        // add an appropriate path so Resource can be found in a bundle
+
+        if (::strstr(this_module.GetDirectory().AsCString(""), ".framework"))
+        {
+            python_path.append(1, ':');
+            python_path.append(this_module.GetDirectory().AsCString(""));
+            python_path.append("/Resources/Python");
+        }
+#endif
+        // The the PYTHONPATH environment variable so that Python can find
+        // our lldb.py module and our _lldb.so.
+        ::setenv ("PYTHONPATH", python_path.c_str(), 1);
+    }
+
+    Py_Initialize ();
+
+    PyObject *compiled_module = Py_CompileString (embedded_interpreter_string, "embedded_interpreter.py",
+                                                  Py_file_input);
+
+    m_compiled_module = compiled_module;
+
+    init_lldb ();
+
+    // Update the path python uses to search for modules to include the current directory.
+
+    int success = PyRun_SimpleString ("import sys");
+    success = PyRun_SimpleString ("sys.path.append ('.')");
+    if (success == 0)
+    {
+        // Import the Script Bridge module.
+        success =  PyRun_SimpleString ("from lldb import *");
+    }
+
+    const char *pty_slave_name = GetScriptInterpreterPtyName ();
+    FILE *out_fh = Debugger::GetSharedInstance().GetOutputFileHandle();
+    
+    PyObject *pmod = PyImport_ExecCodeModule((char *)"embedded_interpreter", m_compiled_module);
+    if (pmod != NULL)
+    {
+        PyRun_SimpleString ("ConsoleDict = locals()");
+        PyRun_SimpleString ("from embedded_interpreter import run_python_interpreter");
+        PyRun_SimpleString ("import sys");
+        PyRun_SimpleString ("from termios import *");
+        PyRun_SimpleString ("old_stdin = sys.stdin");
+      
+        StreamString run_string;
+        run_string.Printf ("new_stdin = open('%s', 'r')", pty_slave_name);
+        PyRun_SimpleString (run_string.GetData());
+        PyRun_SimpleString ("sys.stdin = new_stdin");
+
+        PyRun_SimpleString ("old_stdout = sys.stdout");
+        
+        if (out_fh != NULL)
+        {
+            PyObject *new_sysout = PyFile_FromFile (out_fh, (char *) "", (char *) "w", 
+                                                        _check_and_flush);
+            PyObject *sysmod = PyImport_AddModule ("sys");
+            PyObject *sysdict = PyModule_GetDict (sysmod);
+
+            if ((new_sysout != NULL)
+                && (sysmod != NULL)
+                && (sysdict != NULL))
+            {
+                PyDict_SetItemString (sysdict, "stdout", new_sysout);
+            }
+
+            if (PyErr_Occurred())
+                PyErr_Clear();
+        }
+
+        PyRun_SimpleString ("new_mode = tcgetattr(new_stdin)");
+        PyRun_SimpleString ("new_mode[3] = new_mode[3] | ECHO | ICANON");
+        PyRun_SimpleString ("new_mode[6][VEOF] = 255");
+        PyRun_SimpleString ("tcsetattr (new_stdin, TCSANOW, new_mode)");
+    }
+
+
+}
+
+ScriptInterpreterPython::~ScriptInterpreterPython ()
+{
+    PyRun_SimpleString ("sys.stdin = old_stdin");
+    PyRun_SimpleString ("sys.stdout = old_stdout");
+    Py_Finalize ();
+}
+
+void
+ScriptInterpreterPython::ExecuteOneLine (const std::string& line, FILE *out, FILE *err)
+{
+    int success;
+
+    success = PyRun_SimpleString (line.c_str());
+    if (success != 0)
+    {
+        fprintf (err, "error: python failed attempting to evaluate '%s'\n", line.c_str());
+    }
+}
+
+
+
+size_t
+ScriptInterpreterPython::InputReaderCallback
+(
+    void *baton, 
+    InputReader *reader, 
+    lldb::InputReaderAction notification,
+    const char *bytes, 
+    size_t bytes_len
+)
+{
+    if (baton == NULL)
+        return 0;
+
+    ScriptInterpreterPython *interpreter = (ScriptInterpreterPython *) baton;            
+    switch (notification)
+    {
+    case eInputReaderActivate:
+        {
+            // Save terminal settings if we can
+            interpreter->m_termios_valid = ::tcgetattr (::fileno (reader->GetInputFileHandle()), 
+                                                        &interpreter->m_termios) == 0;
+            struct termios tmp_termios;
+            if (::tcgetattr (::fileno (reader->GetInputFileHandle()), &tmp_termios) == 0)
+            {
+                tmp_termios.c_cc[VEOF] = _POSIX_VDISABLE;
+                ::tcsetattr (::fileno (reader->GetInputFileHandle()), TCSANOW, &tmp_termios);
+            }
+        }
+        break;
+
+    case eInputReaderDeactivate:
+        break;
+
+    case eInputReaderReactivate:
+        break;
+
+    case eInputReaderGotToken:
+        if (bytes && bytes_len)
+        {
+            if ((int) bytes[0] == 4)
+                ::write (interpreter->GetMasterFileDescriptor(), "quit()", 6);
+            else
+                ::write (interpreter->GetMasterFileDescriptor(), bytes, bytes_len);
+        }
+        ::write (interpreter->GetMasterFileDescriptor(), "\n", 1);
+        break;
+        
+    case eInputReaderDone:
+        // Send a control D to the script interpreter
+        //::write (interpreter->GetMasterFileDescriptor(), "\nquit()\n", strlen("\nquit()\n"));
+        // Write a newline out to the reader output
+        //::fwrite ("\n", 1, 1, out_fh);
+        // Restore terminal settings if they were validly saved
+        if (interpreter->m_termios_valid)
+        {
+            ::tcsetattr (::fileno (reader->GetInputFileHandle()), 
+                         TCSANOW,
+                         &interpreter->m_termios);
+        }
+        break;
+    }
+
+    return bytes_len;
+}
+
+
+void
+ScriptInterpreterPython::ExecuteInterpreterLoop (FILE *out, FILE *err)
+{
+    Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
+
+    InputReaderSP reader_sp (new InputReader());
+    if (reader_sp)
+    {
+        Error error (reader_sp->Initialize (ScriptInterpreterPython::InputReaderCallback,
+                                            this,                         // baton
+                                            eInputReaderGranularityLine,  // token size, to pass to callback function
+                                            NULL,                         // end token
+                                            NULL,                         // prompt
+                                            true));                       // echo input
+     
+        if (error.Success())
+        {
+            Debugger::GetSharedInstance().PushInputReader (reader_sp);
+            ExecuteOneLine ("run_python_interpreter(ConsoleDict)", out, err);
+            Debugger::GetSharedInstance().PopInputReader (reader_sp);
+        }
+    }
+}
+
+bool
+ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
+                                                   ScriptInterpreter::ReturnType return_type,
+                                                   void *ret_value)
+{
+    PyObject *py_return = NULL;
+    PyObject *mainmod = PyImport_AddModule ("__main__");
+    PyObject *globals = PyModule_GetDict (mainmod);
+    PyObject *locals = globals;
+    PyObject *py_error = NULL;
+    bool ret_success;
+    int success;
+
+    if (in_string != NULL)
+    {
+        py_return = PyRun_String (in_string, Py_eval_input, globals, locals);
+        if (py_return == NULL)
+        {
+            py_error = PyErr_Occurred ();
+            if (py_error != NULL)
+                PyErr_Clear ();
+
+            py_return = PyRun_String (in_string, Py_single_input, globals, locals);
+        }
+
+        if (py_return != NULL)
+        {
+            switch (return_type)
+            {
+                case eCharPtr: // "char *"
+                {
+                    const char format[3] = "s#";
+                    success = PyArg_Parse (py_return, format, (char **) &ret_value);
+                    break;
+                }
+                case eBool:
+                {
+                    const char format[2] = "b";
+                    success = PyArg_Parse (py_return, format, (bool *) ret_value);
+                    break;
+                }
+                case eShortInt:
+                {
+                    const char format[2] = "h";
+                    success = PyArg_Parse (py_return, format, (short *) ret_value);
+                    break;
+                }
+                case eShortIntUnsigned:
+                {
+                    const char format[2] = "H";
+                    success = PyArg_Parse (py_return, format, (unsigned short *) ret_value);
+                    break;
+                }
+                case eInt:
+                {
+                    const char format[2] = "i";
+                    success = PyArg_Parse (py_return, format, (int *) ret_value);
+                    break;
+                }
+                case eIntUnsigned:
+                {
+                    const char format[2] = "I";
+                    success = PyArg_Parse (py_return, format, (unsigned int *) ret_value);
+                    break;
+                }
+                case eLongInt:
+                {
+                    const char format[2] = "l";
+                    success = PyArg_Parse (py_return, format, (long *) ret_value);
+                    break;
+                }
+                case eLongIntUnsigned:
+                {
+                    const char format[2] = "k";
+                    success = PyArg_Parse (py_return, format, (unsigned long *) ret_value);
+                    break;
+                }
+                case eLongLong:
+                {
+                    const char format[2] = "L";
+                    success = PyArg_Parse (py_return, format, (long long *) ret_value);
+                    break;
+                }
+                case eLongLongUnsigned:
+                {
+                    const char format[2] = "K";
+                    success = PyArg_Parse (py_return, format, (unsigned long long *) ret_value);
+                    break;
+                }
+                case eFloat:
+                {
+                    const char format[2] = "f";
+                    success = PyArg_Parse (py_return, format, (float *) ret_value);
+                    break;
+                }
+                case eDouble:
+                {
+                    const char format[2] = "d";
+                    success = PyArg_Parse (py_return, format, (double *) ret_value);
+                    break;
+                }
+                case eChar:
+                {
+                    const char format[2] = "c";
+                    success = PyArg_Parse (py_return, format, (char *) ret_value);
+                    break;
+                }
+                default:
+                  {}
+            }
+            Py_DECREF (py_return);
+            if (success)
+                ret_success = true;
+            else
+                ret_success = false;
+        }
+    }
+
+    py_error = PyErr_Occurred();
+    if (py_error != NULL)
+    {
+        if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
+            PyErr_Print ();
+        PyErr_Clear();
+        ret_success = false;
+    }
+
+    return ret_success;
+}
+
+bool
+ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string)
+{
+    bool success = false;
+    PyObject *py_return = NULL;
+    PyObject *mainmod = PyImport_AddModule ("__main__");
+    PyObject *globals = PyModule_GetDict (mainmod);
+    PyObject *locals = globals;
+    PyObject *py_error = NULL;
+
+    if (in_string != NULL)
+    {
+        struct _node *compiled_node = PyParser_SimpleParseString (in_string, Py_file_input);
+        if (compiled_node)
+        {
+            PyCodeObject *compiled_code = PyNode_Compile (compiled_node, "temp.py");
+            if (compiled_code)
+            {
+                py_return = PyEval_EvalCode (compiled_code, globals, locals);
+                if (py_return != NULL)
+                {
+                    success = true;
+                    Py_DECREF (py_return);
+                }
+            }
+        }
+    }
+
+    py_error = PyErr_Occurred ();
+    if (py_error != NULL)
+    {
+        if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
+            PyErr_Print ();
+        PyErr_Clear();
+        success = false;
+    }
+
+    return success;
+}
+
+static const char *g_reader_instructions = "Enter your Python command(s). Type 'DONE' to end.";
+
+size_t
+ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback
+(
+    void *baton, 
+    InputReader *reader, 
+    lldb::InputReaderAction notification,
+    const char *bytes, 
+    size_t bytes_len
+)
+{
+  static StringList commands_in_progress;
+
+    FILE *out_fh = reader->GetOutputFileHandle();
+    switch (notification)
+    {
+    case eInputReaderActivate:
+        {
+            commands_in_progress.Clear();
+            if (out_fh)
+            {
+                ::fprintf (out_fh, "%s\n", g_reader_instructions);
+                if (reader->GetPrompt())
+                    ::fprintf (out_fh, "%s", reader->GetPrompt());
+            }
+        }
+        break;
+
+    case eInputReaderDeactivate:
+        break;
+
+    case eInputReaderReactivate:
+        if (reader->GetPrompt() && out_fh)
+            ::fprintf (out_fh, "%s", reader->GetPrompt());
+        break;
+
+    case eInputReaderGotToken:
+        {
+            std::string temp_string (bytes, bytes_len);
+            commands_in_progress.AppendString (temp_string.c_str());
+            if (out_fh && !reader->IsDone() && reader->GetPrompt())
+                ::fprintf (out_fh, "%s", reader->GetPrompt());
+        }
+        break;
+
+    case eInputReaderDone:
+        {
+            BreakpointOptions *bp_options = (BreakpointOptions *)baton;
+            std::auto_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
+            data_ap->user_source.AppendList (commands_in_progress);
+            if (data_ap.get())
+            {
+                ScriptInterpreter *interpreter = Debugger::GetSharedInstance().GetCommandInterpreter().GetScriptInterpreter();
+                if (interpreter)
+                {
+                    if (interpreter->GenerateBreakpointCommandCallbackData (data_ap->user_source, 
+                                                                            data_ap->script_source))
+                    {
+                        if (data_ap->script_source.GetSize() == 1)
+                        {
+                            BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
+                            bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
+                        }
+                    }
+                }
+                else
+                {
+                    // FIXME:  Error processing.
+                }
+            }
+        }
+        break;
+        
+    }
+
+    return bytes_len;
+}
+
+void
+ScriptInterpreterPython::CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
+                                                                  CommandReturnObject &result)
+{
+    InputReaderSP reader_sp (new InputReader ());
+
+    if (reader_sp)
+    {
+        Error err = reader_sp->Initialize (
+                ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback,
+                bp_options,                 // baton
+                eInputReaderGranularityLine, // token size, for feeding data to callback function
+                "DONE",                     // end token
+                "> ",                       // prompt
+                true);                      // echo input
+    
+        if (err.Success())
+            Debugger::GetSharedInstance().PushInputReader (reader_sp);
+        else
+        {
+            result.AppendError (err.AsCString());
+            result.SetStatus (eReturnStatusFailed);
+        }
+    }
+    else
+    {
+        result.AppendError("out of memory");
+        result.SetStatus (eReturnStatusFailed);
+    }
+}
+
+bool
+ScriptInterpreterPython::ExportFunctionDefinitionToInterpreter (StringList &function_def)
+{
+    // Convert StringList to one long, newline delimited, const char *.
+    std::string function_def_string;
+
+    int num_lines = function_def.GetSize();
+
+    for (int i = 0; i < num_lines; ++i)
+    {
+        function_def_string.append (function_def.GetStringAtIndex(i));
+        if (function_def_string.at (function_def_string.length() - 1) != '\n')
+            function_def_string.append ("\n");
+
+    }
+
+    return ExecuteMultipleLines (function_def_string.c_str());
+}
+
+bool
+ScriptInterpreterPython::GenerateBreakpointCommandCallbackData (StringList &user_input, StringList &callback_data)
+{
+    static int num_created_functions = 0;
+
+    user_input.RemoveBlankLines ();
+    int num_lines = user_input.GetSize();
+    std::string last_function_call;
+
+    // Go through lines of input looking for any function definitions. For each function definition found,
+    // export the function definition to Python, create a potential function call for the function, and
+    // mark the lines of the function to be removed from the user input.
+
+    for (int i = 0; i < num_lines; ++i)
+    {
+        int function_start = i;
+        std::string current_str = user_input.GetStringAtIndex (i);
+        const char *current_line = current_str.c_str();
+        int len = 0;
+        if (current_line)
+            len = strlen (current_line);
+
+        // Check to see if the current line is the start of a Python function definition.
+        if (len > 4 && strncmp (current_line, "def ", 4) == 0)
+        {
+            // We've found the first line of a function. First, get the function name.
+
+            // Skip over the 'def '.
+            char *start = (char *) current_line + 4;
+
+            // Skip over white space.
+            while (start[0] == ' ' || start[0] == '\t')
+              ++start;
+
+            // Find the end of the function name.
+            char *end = start;
+            while (isalnum (end[0]) || end[0] == '_')
+              ++end;
+
+            int name_len = end - start;
+            std::string func_name = current_str.substr (4, name_len);
+
+            // Now to find the last line of the function.  That will be the first line that does not begin with
+            // any white space (thanks to Python's indentation rules).
+            ++i;
+            bool found = false;
+            while (i < num_lines && !found)
+            {
+                std::string next_str = user_input.GetStringAtIndex (i);
+                const char *next_line = next_str.c_str();
+                if (next_line[0] != ' ' && next_line[0] != '\t')
+                    found = true;
+                else
+                    ++i;
+            }
+            if (found)
+                --i;  // Make 'i' correspond to the last line of the function.
+            int function_end = i;
+
+            // Special case:  All of user_input is one big function definition.
+            if ((function_start == 0) && (function_end == (num_lines - 1)))
+            {
+                ExportFunctionDefinitionToInterpreter (user_input);
+                last_function_call = func_name + " ()";
+                callback_data.AppendString (last_function_call.c_str());
+                return callback_data.GetSize() > 0;
+            }
+            else
+              {
+                // Make a copy of the function definition:
+                StringList new_function;
+                for (int k = function_start; k <= function_end; ++k)
+                {
+                    new_function.AppendString (user_input.GetStringAtIndex (k));
+                    // Mark the string to be deleted from user_input.
+                    user_input.DeleteStringAtIndex (k);
+                    user_input.InsertStringAtIndex (k, "<lldb_delete>");
+                }
+                ExportFunctionDefinitionToInterpreter (new_function);
+                last_function_call = func_name + " ()";
+            }
+        }
+    }
+
+    // Now instead of trying to really delete the marked lines from user_input, we will just copy all the
+    // unmarked lines into a new StringList.
+
+    StringList new_user_input;
+
+    for (int i = 0; i < num_lines; ++i)
+    {
+        std::string current_string = user_input.GetStringAtIndex (i);
+        if (current_string.compare (0, 13, "<lldb_delete>") == 0)
+            continue;
+
+        new_user_input.AppendString (current_string.c_str());
+    }
+
+    num_lines = new_user_input.GetSize();
+
+    if (num_lines > 0)
+    {
+        if (num_lines == 1
+            && strchr (new_user_input.GetStringAtIndex(0), '\n') == NULL)
+        {
+            // If there's only one line of input, and it doesn't contain any newline characters....
+            callback_data.AppendString (new_user_input.GetStringAtIndex (0));
+        }
+        else
+        {
+            // Create the new function name.
+            StreamString func_name;
+            func_name.Printf ("lldb_bp_callback_func_%d", num_created_functions);
+            //std::string func_name = "lldb_bp_callback_func_" + num_created_functions;
+            ++num_created_functions;
+
+            // Create the function call for the new function.
+            last_function_call = func_name.GetString() + " ()";
+
+            // Create the Python function definition line (which will have to be inserted at the beginning of
+            // the function).
+            std::string def_line = "def " + func_name.GetString() + " ():";
+
+
+            // Indent all lines an additional four spaces (as they are now being put inside a function definition).
+            for (int i = 0; i < num_lines; ++i)
+              {
+                const char *temp_cstring = new_user_input.GetStringAtIndex(i);
+                std::string temp2 = "    ";
+                temp2.append(temp_cstring);
+                new_user_input.DeleteStringAtIndex (i);
+                new_user_input.InsertStringAtIndex (i, temp2.c_str());
+              }
+
+            // Insert the function definition line at the top of the new function.
+            new_user_input.InsertStringAtIndex (0, def_line.c_str());
+
+            ExportFunctionDefinitionToInterpreter (new_user_input);
+            callback_data.AppendString (last_function_call.c_str());
+        }
+    }
+    else
+    {
+        if (!last_function_call.empty())
+          callback_data.AppendString (last_function_call.c_str());
+    }
+
+    return callback_data.GetSize() > 0;
+}
+
+bool
+ScriptInterpreterPython::BreakpointCallbackFunction 
+(
+    void *baton, 
+    StoppointCallbackContext *context,
+    lldb::user_id_t break_id, 
+    lldb::user_id_t break_loc_id
+)
+{
+    bool ret_value = true;
+    bool temp_bool;
+
+    BreakpointOptions::CommandData *bp_option_data =  (BreakpointOptions::CommandData *) baton;
+
+    const char *python_string = bp_option_data->script_source.GetStringAtIndex(0);
+
+    if (python_string != NULL)
+    {
+        bool success =
+          Debugger::GetSharedInstance().GetCommandInterpreter().GetScriptInterpreter()->ExecuteOneLineWithReturn
+                                                                                            (python_string,
+                                                                                             ScriptInterpreter::eBool,
+                                                                                             (void *) &temp_bool);
+        if (success)
+          ret_value = temp_bool;
+    }
+
+    return ret_value;
+}
