diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp
index 9c364861d0e609b5dc71e6f4dbc65279e611b7f7..ebfee675a3b4e441a9a6f0e9e16f06aa533c7e20 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp
@@ -164,6 +164,21 @@ namespace
     return buffer.str();
   }
 
+  /**
+   * Releases the GIL, executes the calling algorithm object and re-acquires the GIL.
+   * As an algorithm is a potentially time-consuming operation, this allows other threads
+   * to execute python code while this thread is executing C code
+   * @param self :: A reference to the calling object
+   */
+  bool executeWhileReleasingGIL(IAlgorithm & self)
+  {
+    bool result(false);
+    Py_BEGIN_ALLOW_THREADS;
+    result = self.execute();
+    Py_END_ALLOW_THREADS;
+    return result;
+  }
+
 }
 
 void export_ialgorithm()
@@ -195,7 +210,7 @@ void export_ialgorithm()
         "are NOT stored in the Analysis Data Service but must be retrieved from the property.")
     .def("setLogging", &IAlgorithm::setLogging, "Toggle logging on/off.")
     .def("initialize", &IAlgorithm::initialize, "Initializes the algorithm")
-    .def("execute", &IAlgorithm::execute, "Runs the algorithm")
+    .def("execute", &executeWhileReleasingGIL, "Runs the algorithm and returns whether it has been successful")
     // Special methods
     .def("__str__", &IAlgorithm::toString)
     ;
diff --git a/Code/Mantid/MantidPlot/CMakeLists.txt b/Code/Mantid/MantidPlot/CMakeLists.txt
index b9d84381b8dea01ce1485ddc239fc7febc206098..6a5baf97a28471302b266b76227584a59c01873e 100644
--- a/Code/Mantid/MantidPlot/CMakeLists.txt
+++ b/Code/Mantid/MantidPlot/CMakeLists.txt
@@ -13,6 +13,7 @@ set ( QTIPLOT_SRCS src/ApplicationWindow.cpp
                    src/Bar.cpp
                    src/BoxCurve.cpp
                    src/CanvasPicker.cpp
+                   src/CommandLineInterpreter.cpp
                    src/ColorMapDialog.cpp
                    src/Cone3D.cpp
                    src/ConfigDialog.cpp
@@ -100,11 +101,12 @@ set ( QTIPLOT_SRCS src/ApplicationWindow.cpp
                    src/ScreenPickerTool.cpp
                    src/Script.cpp
                    src/Scripted.cpp
-                   src/ScriptEdit.cpp
                    src/ScriptingEnv.cpp
                    src/ScriptingLangDialog.cpp
                    src/ScriptingWindow.cpp
+                   src/ScriptFileInterpreter.cpp
                    src/ScriptManagerWidget.cpp
+                   src/ScriptOutputDisplay.cpp
                    src/SelectionMoveResizer.cpp
                    src/SendToProgramDialog.cpp
                    src/SetColValuesDialog.cpp
@@ -119,6 +121,7 @@ set ( QTIPLOT_SRCS src/ApplicationWindow.cpp
                    src/TableStatistics.cpp
                    src/TextDialog.cpp
                    src/TextEditor.cpp
+                   src/TextFileIO.cpp
                    src/TitlePicker.cpp
                    src/ThreadAdapter.cpp
                    src/TranslateCurveTool.cpp
@@ -232,6 +235,7 @@ set ( QTIPLOT_HDRS src/ApplicationWindow.h
                    src/Bar.h
                    src/BoxCurve.h
                    src/CanvasPicker.h
+                   src/CommandLineInterpreter.h
                    src/ColorMapDialog.h
                    src/Cone3D.h
                    src/ConfigDialog.h
@@ -313,6 +317,7 @@ set ( QTIPLOT_HDRS src/ApplicationWindow.h
                    src/PythonScript.h
                    src/PythonScripting.h
                    src/PythonSystemHeader.h
+                   src/PythonThreading.h
                    src/QwtBarCurve.h
                    src/qwt_compat.h
                    src/QwtErrorPlotCurve.h
@@ -325,12 +330,13 @@ set ( QTIPLOT_HDRS src/ApplicationWindow.h
                    src/ScalePicker.h
                    src/ScreenPickerTool.h
                    src/Scripted.h
-                   src/ScriptEdit.h
                    src/Script.h
                    src/ScriptingEnv.h
                    src/ScriptingLangDialog.h
                    src/ScriptingWindow.h
                    src/ScriptManagerWidget.h
+                   src/ScriptOutputDisplay.h
+                   src/ScriptFileInterpreter.h
                    src/SelectionMoveResizer.h
                    src/SendToProgramDialog.h
                    src/SetColValuesDialog.h
@@ -346,6 +352,7 @@ set ( QTIPLOT_HDRS src/ApplicationWindow.h
                    src/ThreadAdapter.h
                    src/TextDialog.h
                    src/TextEditor.h
+                   src/TextFileIO.h
                    src/TitlePicker.h
                    src/TranslateCurveTool.h
                    src/UserFunction.h
@@ -518,6 +525,7 @@ set ( QTIPLOT_MOC_FILES src/ApplicationWindow.h
                         src/AxesDialog.h
                         src/CanvasPicker.h
                         src/ColorMapDialog.h
+                        src/CommandLineInterpreter.h
                         src/ConfigDialog.h
                         src/ContourLinesEditor.h
                         src/Convolution.h
@@ -587,12 +595,13 @@ set ( QTIPLOT_MOC_FILES src/ApplicationWindow.h
                         src/RenameWindowDialog.h
                         src/ScalePicker.h
                         src/ScreenPickerTool.h
-                        src/ScriptEdit.h
                         src/Script.h
                         src/ScriptingEnv.h
                         src/ScriptingLangDialog.h
                         src/ScriptingWindow.h
                         src/ScriptManagerWidget.h
+                        src/ScriptOutputDisplay.h
+                        src/ScriptFileInterpreter.h
                         src/SelectionMoveResizer.h
                         src/SendToProgramDialog.h
                         src/SetColValuesDialog.h
diff --git a/Code/Mantid/MantidPlot/mantidplot.py b/Code/Mantid/MantidPlot/mantidplot.py
index 65cba5eae5053c2b3dc81a8c1bff736c0619d880..15f464a52b716fd72b3acfc0580856c49d800dfd 100644
--- a/Code/Mantid/MantidPlot/mantidplot.py
+++ b/Code/Mantid/MantidPlot/mantidplot.py
@@ -8,7 +8,6 @@ try:
 except ImportError:
     raise ImportError('The "mantidplot" module can only be used from within MantidPlot.')
 
-
 import mantidplotpy.proxies as proxies
 
 from PyQt4 import QtCore, QtGui
@@ -17,6 +16,7 @@ from PyQt4.QtCore import Qt
 # Import into the global namespace qti classes that:
 #   (a) don't need a proxy & (b) can be constructed from python
 from _qti import PlotSymbol, ImageSymbol, ArrowMarker, ImageMarker
+from _qti import ThreadAdapter
 
 #-------------------------- Mantid Python access functions----------------
 # Grab a few Mantid things so that we can recognise workspace variables
@@ -34,6 +34,22 @@ def _get_analysis_data_service():
     else:
         import MantidFramework
         return MantidFramework.mtd
+    
+#-------------------------- MantidPlot Threaded Access -------------------
+def threadsafe_call(func_name, *args):
+    """
+        Calls the given function with the given arguments
+        by passing it through the ThreadAdapter. This
+        ensures that the calls to the GUI functions
+        happen on the correct thread
+    """
+    adapter = ThreadAdapter(_qti.app, _qti.app.mantidUI)
+    try:
+        callable = getattr(adapter, func_name)
+    except AttributeError:
+        raise AttributeError("ThreadAdaptor has not been updated for %s. "
+                             "Cannot perform call as it would be dangerous")
+    return callable(*args)
 
 #-------------------------- Wrapped MantidPlot functions -----------------
 
@@ -184,12 +200,16 @@ def plotSpectrum(source, indices, error_bars = False, type = -1):
     """
     workspace_names = __getWorkspaceNames(source)
     index_list = __getWorkspaceIndices(indices)
-    if len(workspace_names) > 0 and len(index_list) > 0:
-        return __tryPlot(workspace_names, index_list, error_bars, type)
+    if len(workspace_names) == 0:
+        raise ValueError("No workspace names given to plot")
+    if len(index_list) == 0:
+        raise ValueError("No indices given to plot")
+    graph = proxies.Graph(threadsafe_call('plotSpectraList', workspace_names, index_list, error_bars, type))
+    if graph._getHeldObject() == None:
+        raise RuntimeError("Cannot create graph, see log for details.")
     else:
-        return None
+        return graph
     
-
 #-----------------------------------------------------------------------------
 def plotBin(source, indices, error_bars = False, type = 0):
     """Create a 1D Plot of bin count vs spectrum in a workspace.
@@ -208,7 +228,7 @@ def plotBin(source, indices, error_bars = False, type = 0):
     Returns:
         A handle to the created Graph widget.
     """
-    return __doPlotting(source,indices,error_bars,type)
+    return __doBinPlot(source,indices,error_bars,type)
 
 #-----------------------------------------------------------------------------
 def stemPlot(source, index, power=None, startPoint=None, endPoint=None):
@@ -387,7 +407,7 @@ def matrixToTable(matrix, conversionType=_qti.app.Direct):
 
 def mergePlots(graph1,graph2):
     """Combine two graphs into a single plot"""
-    return proxies.Graph(_qti.app.mantidUI.mergePlots(graph1._getHeldObject(),graph2._getHeldObject()))
+    return proxies.Graph(threadsafe_call('mergePlots',graph1._getHeldObject(),graph2._getHeldObject()))
 
 def convertToWaterfall(graph):
     """Convert a graph (containing a number of plotted spectra) to a waterfall plot"""
@@ -662,12 +682,15 @@ def __doSliceViewer(wsname, label="", xydim=None, slicepoint=None,
     
     return svw
 
+#=============================================================================
+# Helper methods
+#=============================================================================
 
-    
-    
-    
-#-----------------------------------------------------------------------------
 def __getWorkspaceIndices(source):
+    """
+        Returns a list of workspace indices from a source.
+        The source can be a list, a tuple, an int or a string.
+    """
     index_list = []
     if isinstance(source,list) or isinstance(source,tuple):
         for i in source:
@@ -687,53 +710,53 @@ def __getWorkspaceIndices(source):
         raise TypeError('Incorrect type passed as index argument "' + str(source) + '"')
     return index_list
 
-# Try plotting, raising an error if no plot object is created
-def __tryPlot(workspace_names, indices, error_bars, type):
-    adapter = _qti.ThreadAdapter(_qti.app, _qti.app.mantidUI)
-    graph = proxies.Graph(adapter.plotSpectraList(workspace_names, indices, error_bars, type))
-    if graph._getHeldObject() == None:
-        raise RuntimeError("Cannot create graph, see log for details.")
-    else:
-        return graph
-        
+#-----------------------------------------------------------------------------
 
-# Refactored functions for common code
-def __doPlotting(source, indices, error_bars,type):
+def __doBinPlot(source, indices, error_bars,type):
+    """
+       Runs plotBin in the manner most suited to the input
+       
+       If the source is a list/tuple then a plot of all of the 
+       bins merged together is created.
+       If the source is a single str or workspace then a single
+       bin plot is produced
+    """
     if isinstance(source, list) or isinstance(source, tuple):
-        return __PlotList(source, indices, error_bars,type)
+        return __plotBinList(source, indices, error_bars,type)
     elif isinstance(source, str) or hasattr(source, 'getName'):
-        return __PlotSingle(source, indices, error_bars,type)
+        return __plotBinSingle(source, indices, error_bars,type)
     else:
         raise TypeError("Source is not a workspace name or a workspace variable")
     
-def __PlotSingle(workspace, indices, error_bars,type):
+def __plotBinSingle(workspace, indices, error_bars,type):
     if isinstance(indices, list) or isinstance(indices, tuple):
         master_graph = __CallPlotFunction(workspace, indices[0], error_bars,type)
         for index in indices[1:]:
             mergePlots(master_graph, __CallPlotFunction(workspace, index, error_bars,type))
         return master_graph
     else:
-        return __CallPlotFunction(workspace, indices, error_bars,type)
+        return __callPlotBin(workspace, indices, error_bars,type)
     
-def __PlotList(workspace_list, indices, error_bars,type):
+def __plotBinList(workspace_list, indices, error_bars,type):
     if isinstance(indices, list) or isinstance(indices, tuple):
-        master_graph = __CallPlotFunction(workspace_list[0], indices[0], error_bars,type)
+        master_graph = __callPlotBin(workspace_list[0], indices[0], error_bars,type)
         start = 1
         for workspace in workspace_list:
             for index in indices[start:]:
-                mergePlots(master_graph, __CallPlotFunction(workspace, index, error_bars,type))
+                mergePlots(master_graph, __callPlotBin(workspace, index, error_bars,type))
                 start = 0
                 
         return master_graph
     else:
-        master_graph = __CallPlotFunction(workspace_list[0], indices, error_bars,type)
+        master_graph = __callPlotBin(workspace_list[0], indices, error_bars,type)
         for workspace in workspace_list[1:]:
             mergePlots(master_graph, __CallPlotFunction(workspace, indices, error_bars,type))
         return master_graph
 
-def __CallPlotFunction(workspace, index, error_bars,type):
+def __callPlotBin(workspace, index, error_bars,type):
     if isinstance(workspace, str):
         wkspname = workspace
     else:
         wkspname = workspace.getName()
-    return proxies.Graph(_qti.app.mantidUI.plotBin(wkspname, index, error_bars,type))
+    return proxies.Graph(threadsafe_call('plotBin',wkspname, index, error_bars,type))
+#------------------------------------------------------------------------------------------
\ No newline at end of file
diff --git a/Code/Mantid/MantidPlot/mantidplotpy/proxies.py b/Code/Mantid/MantidPlot/mantidplotpy/proxies.py
index de6a7a9d985498b15b0d940adbf117a6520d381e..003a64b907e84c40a390401a1cd4454f5ff3ace9 100644
--- a/Code/Mantid/MantidPlot/mantidplotpy/proxies.py
+++ b/Code/Mantid/MantidPlot/mantidplotpy/proxies.py
@@ -47,14 +47,10 @@ class QtProxyObject(QtCore.QObject):
             QtCore.QObject.connect( self.__obj, QtCore.SIGNAL("destroyed()"),
                                     self._heldObjectDestroyed)
 
-    def __del__(self):
-        # Disconnect the signal or you get a segfault on quitting MantidPlot
-        if self.__obj is not None:
-            QtCore.QObject.disconnect( self.__obj, QtCore.SIGNAL("destroyed()"), self._heldObjectDestroyed )
-
     def _heldObjectDestroyed(self):
         """Slot called when the held object is destroyed.
         Sets it to None, preventing segfaults """
+        QtCore.QObject.disconnect( self.__obj, QtCore.SIGNAL("destroyed()"), self._heldObjectDestroyed )
         self._kill_object()
 
     def __getattr__(self, attr):
diff --git a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp
index 6620c398432bc9c0d0544bf5bb53eda9b532128e..93ad4eeb38227a35146d2b83a1cb46d992308f0e 100644
--- a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp
+++ b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp
@@ -83,7 +83,7 @@
 #include "plot2D/ScaleEngine.h"
 #include "ScriptingLangDialog.h"
 #include "ScriptingWindow.h"
-#include "ScriptManagerWidget.h"
+#include "CommandLineInterpreter.h"
 #include "TableStatistics.h"
 #include "Fit.h"
 #include "MultiPeakFit.h"
@@ -451,7 +451,8 @@ void ApplicationWindow::init(bool factorySettings, const QStringList& args)
   //Scripting
   m_script_envs = QHash<QString, ScriptingEnv*>();
   setScriptingLanguage(defaultScriptingLang);
-  m_scriptInterpreter = new ScriptManagerWidget(scriptingEnv(), m_interpreterDock,true);
+  m_scriptInterpreter = new CommandLineInterpreter(m_interpreterDock);
+  m_scriptInterpreter->setup(*scriptingEnv());
   delete m_interpreterDock->widget();
   m_interpreterDock->setWidget(m_scriptInterpreter);
   m_iface_script = NULL;
@@ -8414,7 +8415,6 @@ void ApplicationWindow::pasteSelection()
 {  
   if (m_interpreterDock->hasFocus())
   {
-    
     m_scriptInterpreter->paste();
     return;
   }
@@ -11120,7 +11120,7 @@ void ApplicationWindow::openScriptWindow(const QStringList &list)
   showScriptWindow();
   if(!scriptingWindow) 
     return;
-  scriptingWindow->setWindowTitle("MantidPlot: " + scriptingEnv()->scriptingLanguage() + " Window");
+  scriptingWindow->setWindowTitle("MantidPlot: " + scriptingEnv()->languageName() + " Window");
   QString s=list[0];
   QStringList scriptnames=s.split("\t");
   int count=scriptnames.size();
@@ -16192,19 +16192,6 @@ void ApplicationWindow::saveScriptWindowGeometry()
 
 void ApplicationWindow::showScriptInterpreter()
 {
-  if( !m_interpreterDock )
-  {
-    m_interpreterDock = new QDockWidget(this);
-    m_interpreterDock->setObjectName("interpreterDock");
-    m_interpreterDock->setWindowTitle("Script Interpreter");
-    addDockWidget( Qt::BottomDockWidgetArea, m_interpreterDock );
-
-    m_scriptInterpreter = new ScriptManagerWidget(scriptingEnv(), m_interpreterDock,true);
-    m_interpreterDock->setWidget(m_scriptInterpreter);
-    m_interpreterDock->setFocusPolicy(Qt::StrongFocus);
-    m_interpreterDock->setFocusProxy(m_scriptInterpreter);
-    
-  }
   if( m_interpreterDock->isVisible() )
   {
     m_interpreterDock->hide();
@@ -17154,30 +17141,25 @@ bool ApplicationWindow::runPythonScript(const QString & code, bool quiet, bool r
   if( m_iface_script == NULL )
   {
     setScriptingLanguage("Python");
-    m_iface_script = scriptingEnv()->newScript("",this, "",false, false);
-    m_iface_script->setLineOffset(0);
-    connect(m_iface_script, SIGNAL(print(const QString &)), this, SLOT(scriptPrint(const QString&)));
-    connect(m_iface_script, SIGNAL(error(const QString &, const QString&, int)), this, 
-        SLOT(scriptPrint(const QString &)));
+    m_iface_script = scriptingEnv()->newScript("<Interface>", NULL, Script::NonInteractive);
+
   }
-  m_iface_script->setCode(code);
   if( !quiet )
   {
     // Output a message to say we've started
     scriptPrint("Script execution started.", false, true);
   }
-  const bool cachedEmit = m_iface_script->emitErrors();
-  if (!redirect)
+  if(redirect)
   {
-    m_iface_script->redirectStdOut(false);
-    // The redirect option was introduced for IPython, where was also don't want errors to go to the console window
-    m_iface_script->setEmitErrors(false);
+    m_iface_script->redirectStdOut(true);
+    connect(m_iface_script, SIGNAL(print(const QString &)), this, SLOT(scriptPrint(const QString&)));
+    connect(m_iface_script, SIGNAL(error(const QString &, const QString&, int)), this,
+            SLOT(scriptPrint(const QString &)));
   }
-  bool success = m_iface_script->exec();
-  if (!redirect)
+  bool success = m_iface_script->execute(code);
+  if (redirect)
   {
-    m_iface_script->redirectStdOut(true);
-    m_iface_script->setEmitErrors(cachedEmit);
+    m_iface_script->redirectStdOut(false);
   }
   if(success && !quiet)
   {
diff --git a/Code/Mantid/MantidPlot/src/ApplicationWindow.h b/Code/Mantid/MantidPlot/src/ApplicationWindow.h
index bc070ca07bb5859a183b70911aa2962643e1d7fd..88f536169e4997b03eb394d7ae84345bb1a03aee 100644
--- a/Code/Mantid/MantidPlot/src/ApplicationWindow.h
+++ b/Code/Mantid/MantidPlot/src/ApplicationWindow.h
@@ -106,7 +106,7 @@ class FitPropertyBrowser;
 //Mantid
 class MantidUI;
 class ScriptingWindow;
-class ScriptManagerWidget;
+class CommandLineInterpreter;
 
 /**
 * \brief QtiPlot's main window.
@@ -1361,7 +1361,7 @@ private:
   QDockWidget *consoleWindow;
   QTextEdit *console;
   QDockWidget *m_interpreterDock;
-  ScriptManagerWidget *m_scriptInterpreter;
+  CommandLineInterpreter *m_scriptInterpreter;
   QMdiArea *d_workspace;
 
   QToolBar *fileTools, *plotTools, *tableTools, *columnTools, *plot3DTools, *displayBar, *editTools, *plotMatrixBar;
diff --git a/Code/Mantid/MantidPlot/src/CommandLineInterpreter.cpp b/Code/Mantid/MantidPlot/src/CommandLineInterpreter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d01bffcf76bee7ceae709ab39ffdb16e30ea308e
--- /dev/null
+++ b/Code/Mantid/MantidPlot/src/CommandLineInterpreter.cpp
@@ -0,0 +1,53 @@
+#include "CommandLineInterpreter.h"
+#include "MantidQtMantidWidgets/ScriptEditor.h"
+#include "ScriptingEnv.h"
+
+#include <QVBoxLayout>
+
+/**
+ * Construct an object with the given parent
+ */
+CommandLineInterpreter::CommandLineInterpreter(QWidget *parent)
+  : QWidget(parent), m_editor(new ScriptEditor(this,true, NULL)), m_runner()
+{
+  setFocusProxy(m_editor);
+  m_editor->setFocus();
+  QVBoxLayout *mainLayout = new QVBoxLayout;
+  mainLayout->addWidget(m_editor);
+  mainLayout->setContentsMargins(0,0,0,0);
+  setLayout(mainLayout);
+}
+
+/**
+ * Setup with a scripting environment
+ * @param environ A reference to a scripting environment
+ */
+void CommandLineInterpreter::setup(const ScriptingEnv & environ)
+{
+  m_runner = QSharedPointer<Script>(environ.newScript("<CommandLine>",this,Script::Interactive));
+  m_editor->setLexer(environ.createCodeLexer());
+}
+
+/**
+ * Persist the current settings to the store
+ */
+void CommandLineInterpreter::saveSettings() const
+{
+
+}
+
+/**
+ * Copy to the clipboard
+ */
+void CommandLineInterpreter::copy()
+{
+  m_editor->copy();
+}
+
+/**
+ * Paste from the clipboard
+ */
+void CommandLineInterpreter::paste()
+{
+  m_editor->paste();
+}
diff --git a/Code/Mantid/MantidPlot/src/CommandLineInterpreter.h b/Code/Mantid/MantidPlot/src/CommandLineInterpreter.h
new file mode 100644
index 0000000000000000000000000000000000000000..05f5c4ec5743bb70deaa501cc06210d7cc0611ef
--- /dev/null
+++ b/Code/Mantid/MantidPlot/src/CommandLineInterpreter.h
@@ -0,0 +1,44 @@
+#ifndef COMMANDLINEINTERPRETER_H_
+#define COMMANDLINEINTERPRETER_H_
+
+#include <QWidget>
+
+//-----------------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------------
+class Script;
+class ScriptingEnv;
+class ScriptEditor;
+
+/**
+ * Defines a widget that uses a ScriptEditor and a Script object
+ * to define a command line environment with the script output
+ * inline with the input
+ *
+ */
+class CommandLineInterpreter : public QWidget
+{
+  Q_OBJECT
+
+public:
+  /// Construct
+  CommandLineInterpreter(QWidget *parent = NULL);
+  /// Setup with a scripting environment
+  void setup(const ScriptingEnv & environ);
+
+  /// Persist to store
+  void saveSettings() const;
+
+  //----------------------- Actions -------------------------------------------
+  /// Copy to clipboard
+  void copy();
+  /// Paste from clipboard
+  void paste();
+
+private:
+  Q_DISABLE_COPY(CommandLineInterpreter);
+  ScriptEditor *m_editor;
+  QSharedPointer<Script> m_runner;
+};
+
+#endif /* COMMANDLINEINTERPRETER_H_ */
diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidUI.cpp b/Code/Mantid/MantidPlot/src/Mantid/MantidUI.cpp
index 19ba2f2a0589d5b437f5b8705499bdb15ceba0b8..c1dabaac33e51c198effd446454dd5f0ed04b336 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/MantidUI.cpp
+++ b/Code/Mantid/MantidPlot/src/Mantid/MantidUI.cpp
@@ -72,6 +72,7 @@ using MantidQt::SliceViewer::SliceViewerWindow;
 namespace MantidException = Mantid::Kernel::Exception;
 
 Q_DECLARE_METATYPE(Graph::CurveType);
+Q_DECLARE_METATYPE(MultiLayer*);
 
 MantidUI::MantidUI(ApplicationWindow *aw):
 m_finishedLoadDAEObserver(*this, &MantidUI::handleLoadDAEFinishedNotification),
@@ -95,6 +96,7 @@ m_finishedLoadDAEObserver(*this, &MantidUI::handleLoadDAEFinishedNotification),
     //Register std::string as well as we use it alot
     qRegisterMetaType<std::string>();
     qRegisterMetaType<Graph::CurveType>();
+    qRegisterMetaType<MultiLayer*>();
   }
 
   m_exploreMantid = new MantidDockWidget(this,aw);
@@ -1060,25 +1062,6 @@ bool MantidUI::drop(QDropEvent* e)
   return false;
 }
 
-/** 
-* Run the named algorithm asynchronously 
-*/ 
-bool MantidUI::runAlgorithmAsync_PyCallback(const QString & alg_name) 
-{ 
-  bool result(false);
-  Mantid::API::IAlgorithm_sptr alg = findAlgorithmPointer(alg_name); 
-
-  if( !alg ) 
-  { 
-    return false; 
-  } 
-  Py_BEGIN_ALLOW_THREADS
-  result = executeAlgorithmAsync(alg, true);
-  Py_END_ALLOW_THREADS
-
-  return result;
-}
-
 /**
 executes Save Nexus
 saveNexus Input Dialog is a generic dialog.Below code is added to remove
diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidUI.h b/Code/Mantid/MantidPlot/src/Mantid/MantidUI.h
index a96ba0c31cafa9235c343b2794b012f77d86b741..f9ff62b17013693224abc171620fd4fd0e5c7bff 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/MantidUI.h
+++ b/Code/Mantid/MantidPlot/src/Mantid/MantidUI.h
@@ -195,8 +195,6 @@ public:
   /// Show the algorithm dock widget
   void showAlgWidget(bool on = true);
 
-  bool runAlgorithmAsync_PyCallback(const QString & algName);
-
 public:
   // Create a 1d graph form specified spectra in a MatrixWorkspace
   MultiLayer* plotSpectraList(const QStringList& wsnames, const QList<int>& spec_list, bool errs=true, Graph::CurveType style = Graph::Unspecified);
diff --git a/Code/Mantid/MantidPlot/src/Matrix.cpp b/Code/Mantid/MantidPlot/src/Matrix.cpp
index 8626353f7613c0e3036fa202d7dc5d2f35a54f2a..d1efa64c8ac218fbae40efaf1bce8cd174fe9cdd 100644
--- a/Code/Mantid/MantidPlot/src/Matrix.cpp
+++ b/Code/Mantid/MantidPlot/src/Matrix.cpp
@@ -462,7 +462,7 @@ bool Matrix::canCalculate(bool useMuParser)
     return false;
 
   if (useMuParser){
-    muParserScript *mup = new muParserScript(scriptingEnv(), formula_str, this, QString("<%1>").arg(objectName()), false);
+    muParserScript *mup = new muParserScript(scriptingEnv(),QString("<%1>").arg(objectName()), this, false);
     connect(mup, SIGNAL(error(const QString&,const QString&,int)), scriptingEnv(), SIGNAL(error(const QString&, const QString&,int)));
 
     double *ri = mup->defineVariable("i");
@@ -472,7 +472,7 @@ bool Matrix::canCalculate(bool useMuParser)
     double *x = mup->defineVariable("x");
     double *y = mup->defineVariable("y");
 
-    if (!mup->compile())
+    if (!mup->compile(formula_str))
       return false;
 
     double r = 1.0;
@@ -482,16 +482,14 @@ bool Matrix::canCalculate(bool useMuParser)
     if (codeLines == 1 && gsl_isnan(mup->evalSingleLine()))
       return false;
     else if (codeLines > 1){
-      QVariant res = mup->eval();
+      QVariant res = mup->evaluate(formula_str);
       if (!res.canConvert(QVariant::Double))
         return false;
     }
   } else {
-    Script *script = scriptingEnv()->newScript(formula_str, this, QString("<%1>").arg(objectName()), false);
+    Script *script = scriptingEnv()->newScript(QString("<%1>").arg(objectName()),this, Script::NonInteractive);
     connect(script, SIGNAL(error(const QString&,const QString&,int)), scriptingEnv(), SIGNAL(error(const QString&,const QString&,int)));
     connect(script, SIGNAL(print(const QString&)), scriptingEnv(), SIGNAL(print(const QString&)));
-    if (!script->compile())
-      return false;
 
     double r = 1.0;
     script->setDouble(r, "i");
@@ -504,7 +502,7 @@ bool Matrix::canCalculate(bool useMuParser)
     double y = 1.0;
     script->setDouble(y, "y");
 
-    QVariant res = script->eval();
+    QVariant res = script->evaluate(formula_str);
     if (!res.canConvert(QVariant::Double))
       return false;
   }
diff --git a/Code/Mantid/MantidPlot/src/MatrixModel.cpp b/Code/Mantid/MantidPlot/src/MatrixModel.cpp
index 8666d36b34509e940fab80a74cb68298a6c9c568..7da8e804236eae600d4f26885d611ea00468eaff 100644
--- a/Code/Mantid/MantidPlot/src/MatrixModel.cpp
+++ b/Code/Mantid/MantidPlot/src/MatrixModel.cpp
@@ -809,7 +809,7 @@ double * MatrixModel::dataCopy(int startRow, int endRow, int startCol, int endCo
 bool MatrixModel::muParserCalculate(int startRow, int endRow, int startCol, int endCol)
 {
 	ScriptingEnv *scriptEnv = d_matrix->scriptingEnv();
-    muParserScript *mup = new muParserScript(scriptEnv, d_matrix->formula(), d_matrix, QString("<%1>").arg(d_matrix->objectName()));
+  muParserScript *mup = new muParserScript(scriptEnv, QString("<%1>").arg(d_matrix->objectName()), d_matrix);
 	connect(mup, SIGNAL(error(const QString&,const QString&,int)), scriptEnv, SIGNAL(error(const QString&,const QString&,int)));
 	connect(mup, SIGNAL(print(const QString&)), scriptEnv, SIGNAL(print(const QString&)));
 
@@ -831,7 +831,7 @@ bool MatrixModel::muParserCalculate(int startRow, int endRow, int startCol, int
     double *x = mup->defineVariable("x");
     double *y = mup->defineVariable("y");
 
-	if (!mup->compile()){
+	if (!mup->compile( d_matrix->formula())){
 		QApplication::restoreOverrideCursor();
 		return false;
 	}
@@ -864,7 +864,7 @@ bool MatrixModel::muParserCalculate(int startRow, int endRow, int startCol, int
                 double c = col + 1.0;
                 *cj = c; *cc = c;
                 *x = x_start + col*dx;
-                res = mup->eval();
+                res = mup->evaluate(d_matrix->formula());
                 if (res.canConvert(QVariant::Double))
                      d_data[aux++] = res.toDouble();
                 else
@@ -886,14 +886,9 @@ bool MatrixModel::calculate(int startRow, int endRow, int startCol, int endCol)
 	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
 
 	ScriptingEnv *scriptEnv = d_matrix->scriptingEnv();
-	  Script *script = scriptEnv->newScript(formula, this, QString("<%1>").arg(objectName()), false);
+	Script *script = scriptEnv->newScript(QString("<%1>").arg(objectName()), this, Script::NonInteractive);
 	connect(script, SIGNAL(error(const QString&,const QString&,int)), scriptEnv, SIGNAL(error(const QString&,const QString&,int)));
 	connect(script, SIGNAL(print(const QString&)), scriptEnv, SIGNAL(print(const QString&)));
-	
-	if (!script->compile()){
-		QApplication::restoreOverrideCursor();
-		return false;
-	}
 
 	if (endRow < 0)
 		endRow = d_rows - 1;
@@ -921,7 +916,7 @@ bool MatrixModel::calculate(int startRow, int endRow, int startCol, int endCol)
 			script->setDouble(c, "j");
 			script->setDouble(c, "col");
 			script->setDouble(x_start + col*dx, "x");
-			res = script->eval();
+			res = script->evaluate(formula);
 			if (res.canConvert(QVariant::Double))
 				d_data[aux++] = res.toDouble();
 			else {
diff --git a/Code/Mantid/MantidPlot/src/MatrixValuesDialog.cpp b/Code/Mantid/MantidPlot/src/MatrixValuesDialog.cpp
index ebacef47b4c6d6f8e34b0efdcd183d67b13c3e04..9e44103c36526b0496ccbdae569822fda05e8e57 100644
--- a/Code/Mantid/MantidPlot/src/MatrixValuesDialog.cpp
+++ b/Code/Mantid/MantidPlot/src/MatrixValuesDialog.cpp
@@ -31,6 +31,7 @@
  ***************************************************************************/
 #include "MatrixValuesDialog.h"
 #include "MatrixCommand.h"
+#include "MantidQtMantidWidgets/ScriptEditor.h"
 
 #include <QLayout>
 #include <QSpinBox>
@@ -99,7 +100,7 @@ MatrixValuesDialog::MatrixValuesDialog( ScriptingEnv *env, QWidget* parent, Qt::
 
 	QHBoxLayout *hbox3 = new QHBoxLayout();
 
-	commands = new ScriptEdit( scriptingEnv());
+	commands = new ScriptEditor(this,false, scriptingEnv()->createCodeLexer());
 	commands->setFocus();
 	hbox3->addWidget(commands);
 
@@ -178,7 +179,6 @@ void MatrixValuesDialog::setMatrix(Matrix* m)
 
 	matrix = m;
 	commands->setText(m->formula());
-	commands->setContext(m);
 
     endCol->setValue(m->numCols());
     endRow->setValue(m->numRows());
@@ -204,7 +204,7 @@ void MatrixValuesDialog::insertExplain(int index)
 
 void MatrixValuesDialog::insertFunction()
 {
-	commands->insertFunction(functions->currentText());
+  QMessageBox::warning(this, "MantidPlot", "Deprecated functionality");
 }
 
 void MatrixValuesDialog::addCell()
diff --git a/Code/Mantid/MantidPlot/src/MatrixValuesDialog.h b/Code/Mantid/MantidPlot/src/MatrixValuesDialog.h
index 5c98467ee43c64919b8c98439b9aab8d619f835f..b87a56bc1ab7a2b75cc811e21dcab66076479c47 100644
--- a/Code/Mantid/MantidPlot/src/MatrixValuesDialog.h
+++ b/Code/Mantid/MantidPlot/src/MatrixValuesDialog.h
@@ -33,7 +33,6 @@
 #include <QDialog>
 #include "ScriptingEnv.h"
 #include "Script.h"
-#include "ScriptEdit.h"
 #include "Matrix.h"
 
 #ifdef SCRIPTING_PYTHON
@@ -43,7 +42,7 @@ class QComboBox;
 class QTextEdit;
 class QSpinBox;
 class QPushButton;
-class ScriptEdit;
+class ScriptEditor;
 class Matrix;
 
 //! Set matrix values dialog
@@ -67,7 +66,7 @@ private:
 	QSize sizeHint() const ;
 	void customEvent( QEvent *e);
 
-	ScriptEdit* commands;
+	ScriptEditor* commands;
     QComboBox* functions;
     QPushButton* btnAddFunction;
 	QPushButton* btnAddCell;
diff --git a/Code/Mantid/MantidPlot/src/PythonScript.cpp b/Code/Mantid/MantidPlot/src/PythonScript.cpp
index 426d567ec764913d6b5f386d29f5d23f478488ec..21698df117af24209361af7cdeb6cbac71ffeef5 100644
--- a/Code/Mantid/MantidPlot/src/PythonScript.cpp
+++ b/Code/Mantid/MantidPlot/src/PythonScript.cpp
@@ -33,86 +33,64 @@
 
 #include "PythonScript.h"
 #include "PythonScripting.h"
-#include "ApplicationWindow.h"
 
-#include <QObject>
 #include <QVariant>
 #include <QMessageBox>
-#include <QFileInfo>
-#include <iostream>
-#include <stdexcept>
-
 #include <QtConcurrentRun>
 
-namespace
-{
-  // Keep a reference to the current PyCode filename object for the line tracing.
-  // The tracing function is a static member function so this variable needs to be global
-  // so it's kept in an anonymous namespace to keep it at this file scope.
-  PyObject* ROOT_CODE_OBJECT = NULL;
-  PythonScript *CURRENT_SCRIPT_OBJECT = NULL;
-
-  static int _trace_callback(PyObject *, _frame *frame, int what, PyObject *)
-  {
-    // If we are in the main code and this is a line number event
-    if( ROOT_CODE_OBJECT && CURRENT_SCRIPT_OBJECT && frame->f_code->co_filename == ROOT_CODE_OBJECT
-      && what == PyTrace_LINE )
-    {
-      CURRENT_SCRIPT_OBJECT->broadcastNewLineNumber(frame->f_lineno);
-    }
-    // I don't care about the return value
-    return 0;
-  }
-
-  /**
-   * Sets a pointer to null when its destructor is run
-   */
-  struct ScriptNullifier
-  {
-    ScriptNullifier(PythonScript *script) :
-      m_script(script)
-    {}
+#include <iostream>
+#include <stdexcept>
 
-    ~ScriptNullifier()
-    {
-      m_script = NULL;
-    }
-  private:
-    PythonScript *m_script;
-  };
 
-}
+//namespace
+//{
+//  // Keep a reference to the current PyCode filename object for the line tracing.
+//  // The tracing function is a static member function so this variable needs to be global
+//  // so it's kept in an anonymous namespace to keep it at this file scope.
+//  PyObject* ROOT_CODE_OBJECT = NULL;
+//  PythonScript *CURRENT_SCRIPT_OBJECT = NULL;
+//
+//  static int _trace_callback(PyObject *, _frame *frame, int what, PyObject *)
+//  {
+//    // If we are in the main code and this is a line number event
+//    if( ROOT_CODE_OBJECT && CURRENT_SCRIPT_OBJECT && frame->f_code->co_filename == ROOT_CODE_OBJECT
+//      && what == PyTrace_LINE )
+//    {
+//      CURRENT_SCRIPT_OBJECT->broadcastNewLineNumber(frame->f_lineno);
+//    }
+//    // I don't care about the return value
+//    return 0;
+//  }
+//
+//  /**
+//   * Sets a pointer to null when its destructor is run
+//   */
+//  struct ScriptNullifier
+//  {
+//    ScriptNullifier(PythonScript *script) :
+//      m_script(script)
+//    {}
+//
+//    ~ScriptNullifier()
+//    {
+//      m_script = NULL;
+//    }
+//  private:
+//    PythonScript *m_script;
+//  };
+//
+//}
 
 /**
  * Constructor
  */
-PythonScript::PythonScript(PythonScripting *env, const QString &code, QObject *context, 
-         const QString &name, bool interactive, bool reportProgress)
-  : Script(env, code, context, name, interactive, reportProgress), PyCode(NULL), localDict(NULL),
+PythonScript::PythonScript(PythonScripting *env, const QString &name, const InteractionType interact,
+                           QObject * context)
+  : Script(env, name, interact, context), m_pythonEnv(env), localDict(NULL),
     stdoutSave(NULL), stderrSave(NULL), isFunction(false), m_isInitialized(false),
-    m_workspaceHandles()
+    m_pathHolder(name), m_workspaceHandles()
 {
-  ROOT_CODE_OBJECT = NULL;
-  CURRENT_SCRIPT_OBJECT = this;
-
-  PyObject *pymodule = PyImport_AddModule("__main__");
-  localDict = PyDict_Copy(PyModule_GetDict(pymodule));
-  if( QFileInfo(Name).exists() )
-  {
-    QString scriptPath = QFileInfo(Name).absoluteFilePath();
-    // Make sure the __file__ variable is set
-    PyDict_SetItem(localDict,PyString_FromString("__file__"), PyString_FromString(scriptPath.toAscii().data()));
-  }
-  setQObject(Context, "self");
-  updatePath(Name, true);
-
-  // Observe ADS updates
-  if( false ) // Disabled as it causes random crashes in different places on different systems
-  {
-    observeAdd();
-    observePostDelete();
-    observeADSClear();
-  }
+  initialize(name, context);
 }
 
 /**
@@ -120,149 +98,67 @@ PythonScript::PythonScript(PythonScripting *env, const QString &code, QObject *c
  */
 PythonScript::~PythonScript()
 {
+  GlobalInterpreterLock pythonLock;
   observeAdd(false);
   observeAfterReplace(false);
   observePostDelete(false);
   observeADSClear(false);
 
   this->disconnect();
-  updatePath(Name, false);
-  Py_XDECREF(PyCode);
   Py_XDECREF(localDict);
 }
 
 /**
- * Compile the code
+ * Compile the code returning true if successful, false otherwise
+ * @param code
+ * @return True if success, false otherwise
  */
-bool PythonScript::compile(bool for_eval)
+bool PythonScript::compile(const QString & code)
 {
-  // Support for the convenient col() and cell() functions.
-  // This can't be done anywhere else, because we need access to the local
-  // variables self, i and j.
-  if( Context )
+  PyObject *codeObject = compileToByteCode(code, false);
+  if(codeObject)
   {
-    if( Context->inherits("Table") ) 
-    {
-      // A bit of a hack, but we need either IndexError or len() from __builtins__.
-      PyDict_SetItemString(localDict, "__builtins__",
-         PyDict_GetItemString(env()->globalDict(), "__builtins__"));
-      PyObject *ret = PyRun_String(
-           "def col(c,*arg):\n"
-           "\ttry: return self.cell(c,arg[0])\n"
-           "\texcept(IndexError): return self.cell(c,i)\n"
-           "def cell(c,r):\n"
-           "\treturn self.cell(c,r)\n"
-           "def tablecol(t,c):\n"
-           "\treturn self.folder().rootFolder().table(t,True).cell(c,i)\n"
-           "def _meth_table_col_(t,c):\n"
-           "\treturn t.cell(c,i)\n"
-           "self.__class__.col = _meth_table_col_",
-           Py_file_input, localDict, localDict);
-      if (ret)
-  Py_DECREF(ret);
-      else
-  PyErr_Print();
-    } 
-    else if(Context->inherits("Matrix")) 
-    {
-      // A bit of a hack, but we need either IndexError or len() from __builtins__.
-      PyDict_SetItemString(localDict, "__builtins__",
-         PyDict_GetItemString(env()->globalDict(), "__builtins__"));
-      PyObject *ret = PyRun_String(
-           "def cell(*arg):\n"
-           "\ttry: return self.cell(arg[0],arg[1])\n"
-           "\texcept(IndexError): return self.cell(i,j)\n",
-           Py_file_input, localDict, localDict);
-      if (ret)
-  Py_DECREF(ret);
-      else
-  PyErr_Print();
-    }
-  }
-  bool success(false);
-  Py_XDECREF(PyCode);
-  // Simplest case: Code is a single expression
-  PyCode = Py_CompileString(Code, Name, Py_file_input);
-  
-  if( PyCode )
-  {
-    success = true;
-  }
-  else if (for_eval) 
-  {
-    // Code contains statements (or errors) and we want to get a return
-    // value from it.
-    // So we wrap the code into a function definition,
-    // execute that (as Py_file_input) and store the function object in PyCode.
-    // See http://mail.python.org/pipermail/python-list/2001-June/046940.html
-    // for why there isn't an easier way to do this in Python.
-    PyErr_Clear(); // silently ignore errors
-    PyObject *key(NULL), *value(NULL);
-    Py_ssize_t i(0);
-    QString signature = "";
-    while(PyDict_Next(localDict, &i, &key, &value))
-    {
-      signature.append(PyString_AsString(key)).append(",");
-    }
-    signature.truncate(signature.length()-1);
-    QString fdef = "def __doit__("+signature+"):\n";
-    fdef.append(Code);
-    fdef.replace('\n',"\n\t");
-    PyCode = Py_CompileString(fdef, Name, Py_file_input);
-    if( PyCode )
-    {
-      PyObject *tmp = PyDict_New();
-      Py_XDECREF(PyEval_EvalCode((PyCodeObject*)PyCode, localDict, tmp));
-      Py_DECREF(PyCode);
-      PyCode = PyDict_GetItemString(tmp,"__doit__");
-      Py_XINCREF(PyCode);
-      Py_DECREF(tmp);
-    }
-    success = (PyCode != NULL);
-  } 
-  else 
-  {
-    // Code contains statements (or errors), but we do not need to get
-    // a return value.
-    PyErr_Clear(); // silently ignore errors
-    PyCode = Py_CompileString(Code, Name, Py_file_input);
-    success = (PyCode != NULL);
+    return true;
   }
-  
-  if(!success )
-  {
-    compiled = compileErr;
-    emit_error(constructErrorMsg(), 0);
-  } 
   else
   {
-    compiled = isCompiled;
+    return false;
   }
-  return success;
 }
 
-QVariant PythonScript::eval()
-{  
-  if (!isFunction) compiled = notCompiled;
-  if (compiled != isCompiled && !compile(true))
-    return QVariant();
-  
+/**
+ * Evaluate the code and return the value
+ * @return
+ */
+QVariant PythonScript::evaluate(const QString & code)
+{
+  PyObject *compiledCode = this->compileToByteCode(code, true);
+  if(!compiledCode)
+  {
+    return QVariant("");
+  }
   PyObject *pyret;
   beginStdoutRedirect();
-  if (PyCallable_Check(PyCode)){
+  if (PyCallable_Check(compiledCode)){
     PyObject *empty_tuple = PyTuple_New(0);
-    pyret = PyObject_Call(PyCode, empty_tuple, localDict);
+    pyret = PyObject_Call(compiledCode, empty_tuple, localDict);
     Py_DECREF(empty_tuple);
-  } else
-    pyret = PyEval_EvalCode((PyCodeObject*)PyCode, localDict, localDict);
+  }
+  else
+  {
+    pyret = PyEval_EvalCode((PyCodeObject*)compiledCode, localDict, localDict);
+  }
   endStdoutRedirect();
-  if (!pyret){
-    if (PyErr_ExceptionMatches(PyExc_ValueError) ||
-  PyErr_ExceptionMatches(PyExc_ZeroDivisionError)){        
+  if (!pyret)
+  {
+    if (PyErr_ExceptionMatches(PyExc_ValueError) || PyErr_ExceptionMatches(PyExc_ZeroDivisionError))
+    {
       PyErr_Clear(); // silently ignore errors
-      return  QVariant("");
-    } else {
-      emit_error(constructErrorMsg(), 0);
+      return QVariant("");
+    }
+    else
+    {
+      emit error(constructErrorMsg(), name(), 0);
       return QVariant();
     }
   }
@@ -270,87 +166,145 @@ QVariant PythonScript::eval()
   QVariant qret = QVariant();
   /* None */
   if (pyret == Py_None)
+  {
     qret = QVariant("");
+  }
   /* numeric types */
   else if (PyFloat_Check(pyret))
+  {
     qret = QVariant(PyFloat_AS_DOUBLE(pyret));
+  }
   else if (PyInt_Check(pyret))
+  {
     qret = QVariant((qlonglong)PyInt_AS_LONG(pyret));
+  }
   else if (PyLong_Check(pyret))
+  {
     qret = QVariant((qlonglong)PyLong_AsLongLong(pyret));
-  else if (PyNumber_Check(pyret)){
+  }
+  else if (PyNumber_Check(pyret))
+  {
     PyObject *number = PyNumber_Float(pyret);
-    if (number){
+    if (number)
+    {
       qret = QVariant(PyFloat_AS_DOUBLE(number));
       Py_DECREF(number);
     }
-    /* bool */
-  } else if (PyBool_Check(pyret))
+  }
+  /* bool */
+  else if (PyBool_Check(pyret))
+  {
     qret = QVariant(pyret==Py_True, 0);
+  }
   // could handle advanced types (such as PyList->QValueList) here if needed
   /* fallback: try to convert to (unicode) string */
-  if(!qret.isValid()) {
+  if(!qret.isValid())
+  {
     PyObject *pystring = PyObject_Unicode(pyret);
-    if (pystring) {
+    if (pystring)
+    {
       PyObject *asUTF8 = PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(pystring), (int)PyUnicode_GET_DATA_SIZE(pystring), NULL);
       Py_DECREF(pystring);
-      if (asUTF8) {
-  qret = QVariant(QString::fromUtf8(PyString_AS_STRING(asUTF8)));
-  Py_DECREF(asUTF8);
-      } else if ((pystring = PyObject_Str(pyret))) {
-  qret = QVariant(QString(PyString_AS_STRING(pystring)));
-  Py_DECREF(pystring);
+      if (asUTF8)
+      {
+        qret = QVariant(QString::fromUtf8(PyString_AS_STRING(asUTF8)));
+        Py_DECREF(asUTF8);
+      }
+      else if ((pystring = PyObject_Str(pyret)))
+      {
+        qret = QVariant(QString(PyString_AS_STRING(pystring)));
+        Py_DECREF(pystring);
       }
     }
   }
   
   Py_DECREF(pyret);
-  if (PyErr_Occurred()){
-    if (PyErr_ExceptionMatches(PyExc_ValueError) ||
-  PyErr_ExceptionMatches(PyExc_ZeroDivisionError)){
+  if (PyErr_Occurred())
+  {
+    if (PyErr_ExceptionMatches(PyExc_ValueError) || PyErr_ExceptionMatches(PyExc_ZeroDivisionError))
+    {
       PyErr_Clear(); // silently ignore errors
       return  QVariant("");
-  } else {
-      emit_error(constructErrorMsg(), 0);
-  return QVariant();
     }
-  } else
-    return qret;
-}
-
-namespace
-{
-  bool execScript(PyThreadState *mainThreadState, const QString & code)
-  {
-    PyEval_AcquireLock();
-    // get a reference to the PyInterpreterState
-    PyInterpreterState * mainInterpreterState = mainThreadState->interp;
-    // create a thread state object for this thread
-    PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState);
-    PyThreadState_Swap(myThreadState);
-
-    PyRun_SimpleString(code.toAscii());
-    if(PyErr_Occurred())
+    else
     {
-      PyErr_Clear();
-      return false;
+      emit error(constructErrorMsg(), name(), 0);
     }
-    // free the lock
-    PyThreadState_Swap(mainThreadState);
-    PyThreadState_Clear(myThreadState);
-    PyThreadState_Delete(myThreadState);
-    PyEval_ReleaseLock();
-    return true;
+    return QVariant();
   }
+  return qret;
 }
 
-bool PythonScript::exec()
+//    void execScript(const QString & code)
+//    {
+//      PyEval_AcquireLock();
+//      // get a reference to the PyInterpreterState
+//      PyInterpreterState * mainInterpreterState = mainThreadState->interp;
+//      // create a thread state object for this thread
+//      PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState);
+//      PyThreadState_Swap(myThreadState);
+//      try
+//      {
+//        PyRun_SimpleString(code.toAscii());
+//      }
+//      catch(...)
+//      {
+//        PyThreadState_Swap(myThreadState);
+//      }
+//      if(PyErr_Occurred())
+//      {
+//        PyErr_Clear();
+//        return false;
+//      }
+//      // free the lock
+//      PyThreadState_Swap(mainThreadState);
+//      PyThreadState_Clear(myThreadState);
+//      PyThreadState_Delete(myThreadState);
+//      PyEval_ReleaseLock();
+//      return true;
+//    }
+//}
+
+//class PythonCodeRunner : public QRunnable
+//{
+//
+//public:
+//  PythonCodeRunner(const QString & script):
+//    QRunnable(), m_script(script)
+//  {}
+//public:
+//  void run()
+//  {
+//    if( QThread::currentThread() != QCoreApplication::instance()->thread())
+//    {
+//      std::cerr << "Separate thread " << QThread::currentThread() << ". Python threadstate " << PyThreadState_Get() << "\n";
+//    }
+//    PyRun_SimpleString(m_script.toAscii());
+//    if(PyErr_Occurred())
+//    {
+//      PyErr_Clear();
+//    }
+//  }
+//private:
+//  QString m_script;
+//};
+
+bool PythonScript::execute(const QString & code)
 {
-  const QString myCode = Code;
-  QtConcurrent::run(execScript, env()->mainThreadState, myCode);
-  //PyRun_SimpleString(myCode.toAscii());
+  bool success(false);
+  beginStdoutRedirect();
+  emit started("Script execution started.");
+  QSharedPointer<PythonThreadState> pythonThreadState =  pythonEnv()->createPythonThread();
+  PyObject * result = PyRun_String(code.toAscii(), Py_file_input, localDict, localDict);
+  if(result)
+  {
+    emit finished("Script execution finished.");
+    success = true;
+  }
+  emit error(constructErrorMsg(), name(), 0);
+  endStdoutRedirect();
+  return success;
 
-  return true;
 //  // Cannot have two things executing at the same time
 //  if( env()->isRunning() ) return false;
 //
@@ -415,26 +369,9 @@ bool PythonScript::exec()
 //  return false;
 }
 
-/**
- * Update the current environment with the script's path
- */
-void PythonScript::updatePath(const QString & filename, bool append)
+QFuture<bool> PythonScript::executeAsync(const QString & code)
 {
-  if( filename.isEmpty() ) return;
-  QString scriptPath = QFileInfo(filename).absolutePath();
-  QString pyCode;
-  if( append )
-  {
-    pyCode = "if r'%1' not in sys.path:\n"
-      "    sys.path.append(r'%1')";
-  }
-  else
-  {
-    pyCode = "if r'%1' in sys.path:\n"
-      "    sys.path.remove(r'%1')";
-  }
-  pyCode = pyCode.arg(scriptPath);
-  PyRun_SimpleString(pyCode.toAscii());
+  return QtConcurrent::run(this, &PythonScript::execute, code);
 }
 
 /**
@@ -444,68 +381,68 @@ void PythonScript::updatePath(const QString & filename, bool append)
  */
 PyObject* PythonScript::executeScript(PyObject* return_tuple)
 {
-  // Before requested code is executed we want to "uninstall" the modules 
-  // containing Python algorithms so that a fresh import reloads them
-  //
-  env()->refreshAlgorithms(true);
-
-  PyObject* pyret(NULL);
-  //If an exception is thrown the thread state needs resetting so we need to save it
-  PyThreadState *saved_tstate = PyThreadState_GET();
-  try
-  {
-    if( return_tuple )
-    {
-      pyret = PyObject_Call(PyCode, return_tuple,localDict);
-    }
-    else
-    {
-      pyret = PyEval_EvalCode((PyCodeObject*)PyCode, localDict, localDict);
-    }
-  }
-  // Given that C++ has no mechanism to move through a code block first if an exception is thrown, some code needs to
-  // be repeated here 
-  catch(const std::bad_alloc&)
-  {
-    PyThreadState_Swap(saved_tstate);// VERY VERY important. Bad things happen if this state is not reset after a throw
-    pyret = NULL;
-    PyErr_NoMemory();
-  }
-  catch(const std::out_of_range& x)
-  {
-    PyThreadState_Swap(saved_tstate);
-    pyret = NULL;
-    PyErr_SetString(PyExc_IndexError, x.what());
-  }
-  catch(const std::invalid_argument& x)
-  {
-    PyThreadState_Swap(saved_tstate);
-    pyret = NULL;
-    PyErr_SetString(PyExc_ValueError, x.what());
-  }
-  catch(const std::exception& x)
-  {
-    PyThreadState_Swap(saved_tstate);
-    pyret = NULL;
-    PyErr_SetString(PyExc_RuntimeError, x.what());
-  }
-  catch(...)
-  {
-    PyThreadState_Swap(saved_tstate);
-    pyret = NULL;
-    PyErr_SetString(PyExc_RuntimeError, "unidentifiable C++ exception");
-  }
-  
-  // If we stole a reference, return it
-  if( return_tuple )
-  {
-    Py_DECREF(return_tuple);
-  }
-  if( m_interactive && pyret )
-  {
-    emit keywordsChanged(createAutoCompleteList());
-  }
-  return pyret;
+//  // Before requested code is executed we want to "uninstall" the modules
+//  // containing Python algorithms so that a fresh import reloads them
+//  //
+//  pythonEnv()->refreshAlgorithms(true);
+//
+//  PyObject* pyret(NULL);
+//  //If an exception is thrown the thread state needs resetting so we need to save it
+//  PyThreadState *saved_tstate = PyThreadState_GET();
+//  try
+//  {
+//    if( return_tuple )
+//    {
+//      pyret = PyObject_Call(PyCode, return_tuple,localDict);
+//    }
+//    else
+//    {
+//      pyret = PyEval_EvalCode((PyCodeObject*)PyCode, localDict, localDict);
+//    }
+//  }
+//  // Given that C++ has no mechanism to move through a code block first if an exception is thrown, some code needs to
+//  // be repeated here
+//  catch(const std::bad_alloc&)
+//  {
+//    PyThreadState_Swap(saved_tstate);// VERY VERY important. Bad things happen if this state is not reset after a throw
+//    pyret = NULL;
+//    PyErr_NoMemory();
+//  }
+//  catch(const std::out_of_range& x)
+//  {
+//    PyThreadState_Swap(saved_tstate);
+//    pyret = NULL;
+//    PyErr_SetString(PyExc_IndexError, x.what());
+//  }
+//  catch(const std::invalid_argument& x)
+//  {
+//    PyThreadState_Swap(saved_tstate);
+//    pyret = NULL;
+//    PyErr_SetString(PyExc_ValueError, x.what());
+//  }
+//  catch(const std::exception& x)
+//  {
+//    PyThreadState_Swap(saved_tstate);
+//    pyret = NULL;
+//    PyErr_SetString(PyExc_RuntimeError, x.what());
+//  }
+//  catch(...)
+//  {
+//    PyThreadState_Swap(saved_tstate);
+//    pyret = NULL;
+//    PyErr_SetString(PyExc_RuntimeError, "unidentifiable C++ exception");
+//  }
+//
+//  // If we stole a reference, return it
+//  if( return_tuple )
+//  {
+//    Py_DECREF(return_tuple);
+//  }
+//  if( m_interactive && pyret )
+//  {
+//    emit keywordsChanged(createAutoCompleteList());
+//  }
+//  return pyret;
 }
 
 QString PythonScript::constructErrorMsg()
@@ -543,7 +480,7 @@ QString PythonScript::constructErrorMsg()
   QString exception_details("");
   if( PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError) )
   {
-    msg_lineno = env()->toString(PyObject_GetAttrString(value, "lineno"),true).toInt();
+    msg_lineno = pythonEnv()->toString(PyObject_GetAttrString(value, "lineno"),true).toInt();
     if( traceback )
     {
       marker_lineno = endtrace_line;
@@ -555,7 +492,7 @@ QString PythonScript::constructErrorMsg()
     }
 
     message = "SyntaxError";
-    QString except_value(env()->toString(value));
+    QString except_value(pythonEnv()->toString(value));
     exception_details = except_value.section('(',0,0);
     filename = except_value.section('(',1).section(',',0,0);
   }
@@ -579,21 +516,12 @@ QString PythonScript::constructErrorMsg()
     {
       msg_lineno = endtrace_line;
     }
-    message = env()->toString(exception).section('.',1).remove("'>");
-    exception_details = env()->toString(value) + QString(' ');
-  }
-  if( filename.isEmpty() && getLineOffset() >= 0 ) 
-  {
-    
-    msg_lineno += getLineOffset();
+    message = pythonEnv()->toString(exception).section('.',1).remove("'>");
+    exception_details = pythonEnv()->toString(value) + QString(' ');
   }
-  if( getLineOffset() >= 0 && marker_lineno >= 0 )
-  {
-    marker_lineno += getLineOffset();
-    message += " on line " + QString::number(marker_lineno);
-  }
-  
+  message += " on line " + QString::number(marker_lineno);
   message += ": \"" + exception_details.trimmed() + "\" ";
+
   if( marker_lineno >=0 
       && !PyErr_GivenExceptionMatches(exception, PyExc_SystemExit) 
       && !filename.isEmpty() 
@@ -604,10 +532,7 @@ QString PythonScript::constructErrorMsg()
       + "' at line " + QString::number(msg_lineno);
   }
   
-  if( reportProgress() )
-  {
-    emit currentLineChanged(marker_lineno, false);
-  }
+  emit currentLineChanged(marker_lineno, false);
 
   // We're responsible for the reference count of these objects
   Py_XDECREF(traceback);
@@ -620,11 +545,9 @@ QString PythonScript::constructErrorMsg()
 
 bool PythonScript::setQObject(QObject *val, const char *name)
 {
-  if (localDict) // Avoid segfault for un-initialized object
+  if (localDict)
   {
-    if (!PyDict_Contains(localDict, PyString_FromString(name)))
-      compiled = notCompiled;
-    return env()->setQObject(val, name, localDict);
+    return pythonEnv()->setQObject(val, name, localDict);
   }
   else
     return false;
@@ -632,26 +555,41 @@ bool PythonScript::setQObject(QObject *val, const char *name)
 
 bool PythonScript::setInt(int val, const char *name)
 {
-
-  if (!PyDict_Contains(localDict, PyString_FromString(name)))
-    compiled = notCompiled;
-  return env()->setInt(val, name, localDict);
+  return pythonEnv()->setInt(val, name, localDict);
 }
 
 bool PythonScript::setDouble(double val, const char *name)
 {
-
-  if (!PyDict_Contains(localDict, PyString_FromString(name)))
-    compiled = notCompiled;
-  return env()->setDouble(val, name, localDict);
+  return pythonEnv()->setDouble(val, name, localDict);
 }
 
 void PythonScript::setContext(QObject *context)
 {
   Script::setContext(context);
-  setQObject(Context, "self");
+  setQObject(context, "self");
+}
+
+/**
+ * Sets the context for the script and if name points to a file then
+ * sets the __file__ variable
+ * @param name A string identifier for the script
+ * @param context A QObject defining the context
+ */
+void PythonScript::initialize(const QString & name, QObject *context)
+{
+  GlobalInterpreterLock pythonlock;
+  PyObject *pymodule = PyImport_AddModule("__main__");
+  localDict = PyDict_Copy(PyModule_GetDict(pymodule));
+  if( QFileInfo(name).exists() )
+  {
+    QString scriptPath = QFileInfo(name).absoluteFilePath();
+    // Make sure the __file__ variable is set
+    PyDict_SetItem(localDict,PyString_FromString("__file__"), PyString_FromString(scriptPath.toAscii().data()));
+  }
+  setContext(context);
 }
 
+
 /**
  * Create a list autocomplete keywords
  */
@@ -675,7 +613,7 @@ QStringList PythonScript::createAutoCompleteList() const
     return keyword_list;
   }
 
-  keyword_list = env()->toStringList(keywords);
+  keyword_list = pythonEnv()->toStringList(keywords);
   Py_DECREF(keywords);
   Py_DECREF(method);
   return keyword_list;
@@ -684,11 +622,6 @@ QStringList PythonScript::createAutoCompleteList() const
 //-------------------------------------------------------
 // Private
 //-------------------------------------------------------
-PythonScripting * PythonScript::env() const
-{ 
-  //Env is protected in the base class
-  return static_cast<PythonScripting*>(Env); 
-}
 
 
 /**
@@ -696,12 +629,12 @@ PythonScripting * PythonScript::env() const
  */
 void PythonScript::beginStdoutRedirect()
 {
-  stdoutSave = PyDict_GetItemString(env()->sysDict(), "stdout");
+  stdoutSave = PyDict_GetItemString(pythonEnv()->sysDict(), "stdout");
   Py_XINCREF(stdoutSave);
-  stderrSave = PyDict_GetItemString(env()->sysDict(), "stderr");
+  stderrSave = PyDict_GetItemString(pythonEnv()->sysDict(), "stderr");
   Py_XINCREF(stderrSave);
-  env()->setQObject(this, "stdout", env()->sysDict());
-  env()->setQObject(this, "stderr", env()->sysDict());
+  pythonEnv()->setQObject(this, "stdout", pythonEnv()->sysDict());
+  pythonEnv()->setQObject(this, "stderr", pythonEnv()->sysDict());
 }
 
 /**
@@ -710,14 +643,117 @@ void PythonScript::beginStdoutRedirect()
  */
 void PythonScript::endStdoutRedirect()
 {
-
-
-  PyDict_SetItemString(env()->sysDict(), "stdout", stdoutSave);
+  PyDict_SetItemString(pythonEnv()->sysDict(), "stdout", stdoutSave);
   Py_XDECREF(stdoutSave);
-  PyDict_SetItemString(env()->sysDict(), "stderr", stderrSave);
+  PyDict_SetItemString(pythonEnv()->sysDict(), "stderr", stderrSave);
   Py_XDECREF(stderrSave);
 }
 
+/**
+ * Compile the code
+ */
+PyObject *PythonScript::compileToByteCode(const QString & code, bool for_eval)
+{
+  // Support for the convenient col() and cell() functions.
+  // This can't be done anywhere else, because we need access to the local
+  // variables self, i and j.
+  if( context() )
+  {
+    if( context()->inherits("Table") )
+    {
+      // A bit of a hack, but we need either IndexError or len() from __builtins__.
+      PyDict_SetItemString(localDict, "__builtins__",
+          PyDict_GetItemString(pythonEnv()->globalDict(), "__builtins__"));
+      PyObject *ret = PyRun_String(
+          "def col(c,*arg):\n"
+          "\ttry: return self.cell(c,arg[0])\n"
+          "\texcept(IndexError): return self.cell(c,i)\n"
+          "def cell(c,r):\n"
+          "\treturn self.cell(c,r)\n"
+          "def tablecol(t,c):\n"
+          "\treturn self.folder().rootFolder().table(t,True).cell(c,i)\n"
+          "def _meth_table_col_(t,c):\n"
+          "\treturn t.cell(c,i)\n"
+          "self.__class__.col = _meth_table_col_",
+          Py_file_input, localDict, localDict);
+      if (ret)
+        Py_DECREF(ret);
+      else
+        PyErr_Print();
+    }
+    else if(context()->inherits("Matrix"))
+    {
+      // A bit of a hack, but we need either IndexError or len() from __builtins__.
+      PyDict_SetItemString(localDict, "__builtins__",
+          PyDict_GetItemString(pythonEnv()->globalDict(), "__builtins__"));
+      PyObject *ret = PyRun_String(
+          "def cell(*arg):\n"
+          "\ttry: return self.cell(arg[0],arg[1])\n"
+          "\texcept(IndexError): return self.cell(i,j)\n",
+          Py_file_input, localDict, localDict);
+      if (ret)
+        Py_DECREF(ret);
+      else
+        PyErr_Print();
+    }
+  }
+  bool success(false);
+  // Simplest case: Code is a single expression
+  PyObject *compiledCode = Py_CompileString(code, nameAsCStr(), Py_file_input);
+
+  if( compiledCode )
+  {
+    success = true;
+  }
+  else if (for_eval)
+  {
+    // Code contains statements (or errors) and we want to get a return
+    // value from it.
+    // So we wrap the code into a function definition,
+    // execute that (as Py_file_input) and store the function object in PyCode.
+    // See http://mail.python.org/pipermail/python-list/2001-June/046940.html
+    // for why there isn't an easier way to do this in Python.
+    PyErr_Clear(); // silently ignore errors
+    PyObject *key(NULL), *value(NULL);
+    Py_ssize_t i(0);
+    QString signature = "";
+    while(PyDict_Next(localDict, &i, &key, &value))
+    {
+      signature.append(PyString_AsString(key)).append(",");
+    }
+    signature.truncate(signature.length()-1);
+    QString fdef = "def __doit__("+signature+"):\n";
+    fdef.append(code);
+    fdef.replace('\n',"\n\t");
+    compiledCode = Py_CompileString(fdef, nameAsCStr(), Py_file_input);
+    if( compiledCode )
+    {
+      PyObject *tmp = PyDict_New();
+      Py_XDECREF(PyEval_EvalCode((PyCodeObject*)compiledCode, localDict, tmp));
+      Py_DECREF(compiledCode);
+      compiledCode = PyDict_GetItemString(tmp,"__doit__");
+      Py_XINCREF(compiledCode);
+      Py_DECREF(tmp);
+    }
+    success = (compiledCode != NULL);
+  }
+  else
+  {
+    // Code contains statements (or errors), but we do not need to get
+    // a return value.
+    PyErr_Clear(); // silently ignore errors
+    compiledCode = Py_CompileString(code, nameAsCStr(), Py_file_input);
+    success = (compiledCode != NULL);
+  }
+
+  if(!success)
+  {
+    emit error(constructErrorMsg(), name(), 0);
+    compiledCode = NULL;
+  }
+  return compiledCode;
+}
+
 /**
  * Listen to add notifications from the ADS and add a Python variable of the workspace name
  * to the current scope
diff --git a/Code/Mantid/MantidPlot/src/PythonScript.h b/Code/Mantid/MantidPlot/src/PythonScript.h
index bf50677e59a08b0aaebcdcbbc41e20cfffbd7da0..db2c8394f700093e395ddf2d467904af1a1078f9 100644
--- a/Code/Mantid/MantidPlot/src/PythonScript.h
+++ b/Code/Mantid/MantidPlot/src/PythonScript.h
@@ -30,11 +30,12 @@
 #define PYTHON_SCRIPT_H
 
 #include "PythonSystemHeader.h"
+#include "PythonThreading.h"
 #include "Script.h"
 #include "MantidQtAPI/WorkspaceObserver.h"
 
-class QObject;
-class QString;
+#include <QFileInfo>
+
 class ScriptingEnv;
 class PythonScripting;
 
@@ -44,36 +45,36 @@ class PythonScripting;
 class PythonScript : public Script, MantidQt::API::WorkspaceObserver
 {
   Q_OBJECT
-  public:
+public:
   /// Constructor
-  PythonScript(PythonScripting *env, const QString &code, QObject *context = 0, 
-         const QString &name="<input>", bool interactive = false, bool reportProgress = false);
-  ///Destructor
+  PythonScript(PythonScripting *env, const QString &name, const InteractionType interact,
+               QObject * context);
+  /// Destructor
   ~PythonScript();
-  /// A function to connect to the ouput stream of the running Python code
+
+  // -------------------------- Print/error message handling ------------------
+  /// Connects the python stdout to a Qt signal
   inline void write(const QString &text) 
   { 
     emit print(text); 
   }
   /// 'Fake' method needed for IPython import
-  void flush() {}
-
-  /// Emit a new line signal
-  inline void broadcastNewLineNumber(int lineno)
-  {
-    emit currentLineChanged(getLineOffset() + lineno, true);
-  }
-
+  inline void flush()
+  {}
  
 public slots:
-  /// Compile to bytecode
-  bool compile(bool for_eval=true);
-  /// Evaluate the current code
-  QVariant eval();
-  /// Excute the current code
-  bool exec();
+  /// Compile the code, returning true if it was successful, false otherwise
+  bool compile(const QString & code);
+  /// Evaluate the current code and return a result as a QVariant
+  QVariant evaluate(const QString & code);
+  /// Execute the current code and return a boolean indicating success/failure
+  bool execute(const QString &);
+  /// Execute the code asynchronously, returning immediately after the execution has started
+  QFuture<bool> executeAsync(const QString & code);
+
   /// Construct the error message from the stack trace (if one exists)
   QString constructErrorMsg();
+
   /// Set the name of the passed object so that Python can refer to it
   bool setQObject(QObject *val, const char *name);
   /// Set the name of the integer so that Python can refer to it
@@ -84,6 +85,50 @@ public slots:
   void setContext(QObject *context);
 
 private:
+  /// Helper class to ensure the sys.path variable is updated correctly
+  struct PythonPathHolder
+  {
+    /// Update the path with the given entry
+    PythonPathHolder(const QString & entry)
+      : m_path(entry)
+    {
+      if( QFileInfo(m_path).exists() )
+      {
+        appendPath(m_path);
+      }
+    }
+    /// Remove the entry from the path
+    ~PythonPathHolder()
+    {
+      removePath(m_path);
+    }
+    void appendPath(const QString & path)
+    {
+      GlobalInterpreterLock pythonLock;
+      QString code =
+        "if r'%1' not in sys.path:\n"
+        "    sys.path.append(r'%1')";
+      code = code.arg(path);
+      PyRun_SimpleString(code);
+    }
+    void removePath(const QString & path)
+    {
+      GlobalInterpreterLock pythonLock;
+      QString code =
+        "if r'%1' in sys.path:\n"
+        "    sys.path.remove(r'%1')";
+      code = code.arg(path);
+      PyRun_SimpleString(code.toAscii());
+    }
+  private:
+    const QString m_path;
+  };
+
+  inline PythonScripting * pythonEnv() const { return m_pythonEnv; }
+  void initialize(const QString & name, QObject *context);
+  void beginStdoutRedirect();
+  void endStdoutRedirect();
+
   /// Listen to add notifications from the ADS
   void addHandle(const std::string& wsName, const Mantid::API::Workspace_sptr ws);
   /// Listen to add/replace notifications from the ADS
@@ -97,22 +142,20 @@ private:
   /// Delete a Python reference to the given workspace name
   void deletePythonReference(const std::string& wsName);
 
-  // Append or remove a path from the Python sys.path
-  void updatePath(const QString & filename, bool append = true);
+  // --------------------------- Script compilation/execution  -----------------------------------
+  /// Compile to bytecode
+  PyObject * compileToByteCode(const QString &, bool for_eval=true);
   /// Perform a call to the Python eval function with the necessary wrapping
   PyObject* executeScript(PyObject* return_tuple);  
   /// Create a list of keywords for the code completion API
   QStringList createAutoCompleteList() const;
 
-private:
-  PythonScripting* env() const; 
-  void beginStdoutRedirect();
-  void endStdoutRedirect();
-
-  PyObject *PyCode, *localDict, *stdoutSave, *stderrSave;
+  PythonScripting * m_pythonEnv;
+  PyObject *localDict, *stdoutSave, *stderrSave;
   bool isFunction;
   QString fileName;
   bool m_isInitialized;
+  PythonPathHolder m_pathHolder;
   /// Set of current python variables that point to worksapce handles
   std::set<std::string> m_workspaceHandles;
 };
diff --git a/Code/Mantid/MantidPlot/src/PythonScripting.cpp b/Code/Mantid/MantidPlot/src/PythonScripting.cpp
index e52e33a3262dd9bc7484882f9ce4169f589ad750..f085b4c15d8bdf35f6387d30ee3113ab917db57e 100644
--- a/Code/Mantid/MantidPlot/src/PythonScripting.cpp
+++ b/Code/Mantid/MantidPlot/src/PythonScripting.cpp
@@ -53,9 +53,6 @@
 // so this is necessary
 extern "C" void init_qti();
 
-// Language name
-const char* PythonScripting::langName = "Python";
-
 // Factory function
 ScriptingEnv *PythonScripting::constructor(ApplicationWindow *parent) 
 { 
@@ -64,8 +61,8 @@ ScriptingEnv *PythonScripting::constructor(ApplicationWindow *parent)
 
 /** Constructor */
 PythonScripting::PythonScripting(ApplicationWindow *parent)
-  : ScriptingEnv(parent, langName), m_globals(NULL), m_math(NULL),
-    m_sys(NULL), refresh_allowed(0), mainThreadState(NULL)
+  : ScriptingEnv(parent, "Python"), m_globals(NULL), m_math(NULL),
+    m_sys(NULL), refresh_allowed(0), m_mainThreadState(NULL)
 {
   // MG (Russell actually found this for OS X): We ship SIP and PyQt4 with Mantid and we need to
   // ensure that the internal import that sip does of PyQt picks up the correct version.
@@ -97,9 +94,34 @@ PythonScripting::~PythonScripting()
   shutdown();
 }
 
+/**
+ * Create a new script object that can execute code within this environment
+ *
+ * @param name :: A identifier of the script, mainly used in error messages
+ * @param interact :: Whether the script is interactive defined by @see Script::InteractionType
+ * @param context :: An object that identifies the current context of the script (NULL is allowed)
+ * @return
+ */
+Script *PythonScripting::newScript(const QString &name, QObject * context,
+                                   const Script::InteractionType interact) const
+{
+  return new PythonScript(const_cast<PythonScripting*>(this), name, interact, context);
+}
+
+/**
+ * Returns a pointer to a new PythonThreadState object that creates
+ * a new thread context on construction. Note that this also locks the
+ * GIL
+ * @return
+ */
+QSharedPointer<PythonThreadState> PythonScripting::createPythonThread() const
+{
+  return QSharedPointer<PythonThreadState>(new PythonThreadState(m_mainThreadState));
+}
+
 bool PythonScripting::isRunning() const
 {
-  return (m_is_running || d_parent->mantidUI->runningAlgCount() > 0 );
+  return (m_is_running );
 }
 
 /**
@@ -120,7 +142,7 @@ bool PythonScripting::start()
     if( Py_IsInitialized() ) return true;
     Py_Initialize();
     PyEval_InitThreads();
-    mainThreadState = PyThreadState_Get();
+    m_mainThreadState = PyThreadState_Get();
 
     //Keep a hold of the globals, math and sys dictionary objects
     PyObject *pymodule = PyImport_AddModule("__main__");
@@ -217,7 +239,7 @@ void PythonScripting::shutdown()
 {
   // release the lock
   PyEval_AcquireLock();
-  PyThreadState_Swap(mainThreadState);
+  PyThreadState_Swap(m_mainThreadState);
   Py_XDECREF(m_math);
   Py_Finalize();
 }
diff --git a/Code/Mantid/MantidPlot/src/PythonScripting.h b/Code/Mantid/MantidPlot/src/PythonScripting.h
index 9e29e05020dfa8328322cb688f86da708d3eca67..bc48f0f016382f5fcc688a22859144968c1566ed 100644
--- a/Code/Mantid/MantidPlot/src/PythonScripting.h
+++ b/Code/Mantid/MantidPlot/src/PythonScripting.h
@@ -32,6 +32,8 @@
 #include "PythonScript.h"
 #include "ScriptingEnv.h"
 
+#include <QSharedPointer>
+
 class QObject;
 class QString;
 
@@ -56,22 +58,25 @@ public:
   void flush() {}
   /// 'Fake' method needed for IPython import
   void set_parent(PyObject*) {}
+
+  /// Create a new script object that can execute code within this enviroment
+  virtual Script *newScript(const QString &name, QObject * context, const Script::InteractionType interact) const;
+  /// Creates a new PythonThreadState object
+  QSharedPointer<PythonThreadState> createPythonThread() const;
+
   /// Create a new code lexer for Python
   QsciLexer * createCodeLexer() const;
   // Python supports progress monitoring
   virtual bool supportsProgressReporting() const { return true; }
+
   /// Return a string represenation of the given object
   QString toString(PyObject *object, bool decref = false);
   //Convert a Python list object to a Qt QStringList
   QStringList toStringList(PyObject *py_seq);
-  /// Create a new script object that can execute code within this enviroment
-  Script *newScript(const QString &code, QObject *context = NULL, const QString &name="<input>",
-        bool interactive = true, bool reportProgress = false)
-  {
-    return new PythonScript(this, code, context, name, interactive, reportProgress);
-  }
+
   ///Return a list of file extensions for Python
   const QStringList fileExtensions() const;
+
   /// Set a reference to a QObject in the given dictionary
   bool setQObject(QObject*, const char*, PyObject *dict);
   /// Set a reference to a QObject in the global dictionary
@@ -82,6 +87,7 @@ public:
   /// Set a reference to a double in the global dictionary
   bool setDouble(double, const char*);
   bool setDouble(double, const char*, PyObject *dict);
+
   /// Return a list of mathematical functions define by qtiplot
   const QStringList mathFunctions() const;
   /// Return a doc string for the given function
@@ -90,11 +96,7 @@ public:
   PyObject *globalDict() { return m_globals; }
   /// Return the sys dictionary for this environment
   PyObject *sysDict() { return m_sys; }
-  /// The language name
-  static const char * langName;
 
-  PyThreadState *mainThreadState;
-             
 public slots:
   /// Refresh Python algorithms state
   virtual void refreshAlgorithms(bool force = false);
@@ -120,25 +122,8 @@ private:
   PyObject *m_sys;
   /// Refresh protection
   int refresh_allowed;
-
-};
-
-//-----------------------------------------------------------------------------
-// Small struct to deal with acquiring/releasing GIL in an more OO way
-//-----------------------------------------------------------------------------
-struct GILHolder
-{
-  GILHolder() : m_state(PyGILState_Ensure())
-  {}
-
-  ~GILHolder()
-  {
-    PyGILState_Release(m_state);
-  }
-
-private:
-  /// Current GIL state
-  PyGILState_STATE m_state;
+  /// Pointer to the main threads state
+  PyThreadState *m_mainThreadState;
 };
 
 #endif
diff --git a/Code/Mantid/MantidPlot/src/PythonThreading.h b/Code/Mantid/MantidPlot/src/PythonThreading.h
new file mode 100644
index 0000000000000000000000000000000000000000..8cb753261a6fa4e361021452de729f5a42b62eb5
--- /dev/null
+++ b/Code/Mantid/MantidPlot/src/PythonThreading.h
@@ -0,0 +1,64 @@
+#ifndef PYTHONTHREADING_H_
+#define PYTHONTHREADING_H_
+
+#include "PythonSystemHeader.h"
+#include <QThread>
+#include <QCoreApplication>
+#include <iostream>
+
+/**
+ * Defines a structure for acquiring/releasing the Python GIL
+ * using the RAII pattern
+ */
+struct GlobalInterpreterLock
+{
+  GlobalInterpreterLock() : m_state(PyGILState_Ensure())
+  {}
+
+  ~GlobalInterpreterLock()
+  {
+    PyGILState_Release(m_state);
+  }
+private:
+  /// Current GIL state
+  PyGILState_STATE m_state;
+};
+
+/**
+ * Defines a structure for creating and destroying a
+ * Python thread state using the RAII pattern
+ */
+struct PythonThreadState
+{
+  PythonThreadState() : m_mainThreadState(NULL), m_thisThreadState(NULL)
+  {}
+
+  explicit PythonThreadState(PyThreadState * mainThreadState)
+    : m_mainThreadState(mainThreadState), m_thisThreadState(NULL)
+  {
+    if(QThread::currentThread() != QCoreApplication::instance()->thread())
+    {
+      std::cerr << "Creating new python thread from " << QThread::currentThread() << "\n";
+      PyEval_AcquireLock();
+      PyInterpreterState * mainInterpreterState = m_mainThreadState->interp;
+      m_thisThreadState = PyThreadState_New(mainInterpreterState);
+      PyThreadState_Swap(m_thisThreadState);
+    }
+  }
+
+  ~PythonThreadState()
+  {
+    if(m_thisThreadState)
+    {
+      PyThreadState_Swap(m_mainThreadState);
+      PyThreadState_Clear(m_thisThreadState);
+      PyThreadState_Delete(m_thisThreadState);
+      PyEval_ReleaseLock();
+    }
+  }
+private:
+  PyThreadState * m_mainThreadState;
+  PyThreadState * m_thisThreadState;
+};
+
+#endif /* PYTHONTHREADING_H_ */
diff --git a/Code/Mantid/MantidPlot/src/Script.cpp b/Code/Mantid/MantidPlot/src/Script.cpp
index 6d06316b9360384ff69f777cbed443ced6bdcd96..5aabff5a26a301cb4b3722241948936180ced6f3 100644
--- a/Code/Mantid/MantidPlot/src/Script.cpp
+++ b/Code/Mantid/MantidPlot/src/Script.cpp
@@ -26,59 +26,29 @@
  *   Boston, MA  02110-1301  USA                                           *
  *                                                                         *
  ***************************************************************************/
-#include "ScriptingEnv.h"
 #include "Script.h"
-
-#include <QMessageBox>
+#include "ScriptingEnv.h"
 #include <QRegExp>
 
-Script::Script(ScriptingEnv *env, const QString &code, QObject *context, 
-	       const QString &name, bool interactive, bool reportProgress)
-  : Env(env), Code(code), Name(name), m_interactive(interactive),
-    m_report_progress(reportProgress), compiled(notCompiled),
-    m_line_offset(-1), m_redirectOutput(true)
-{ 
-  Env->incref(); 
-  Context = context; 
-  EmitErrors=true; 
-}
-
-Script::~Script()
-{
-  Env->decref();
-}
-
-void Script::addCode(const QString &code) 
-{ 
-  Code.append(normaliseLineEndings(code));
-  compiled = notCompiled; 
-  emit codeChanged(); 
-}
-
-void Script::setCode(const QString &code) 
+Script::Script(ScriptingEnv *env, const QString &name,
+               const InteractionType interact, QObject * context)
+  : QObject(), m_env(env), m_name(name), m_interactMode(interact), m_context(context),
+    m_redirectOutput(true)
 {
-  Code = normaliseLineEndings(code);
-  compiled = notCompiled; 
-  emit codeChanged();
+  m_env->incref();
 }
 
-
-bool Script::compile(bool)
-{
-  emit_error("Script::compile called!", 0);
-  return false;
-}
-
-QVariant Script::eval()
+Script::~Script()
 {
-  emit_error("Script::eval called!",0);
-  return QVariant();
+  m_env->decref();
 }
 
-bool Script::exec()
+/**
+ * @return True if the script is running
+ */
+bool Script::scriptIsRunning()
 {
-  emit_error("Script::exec called!",0);
-  return false;
+  return m_env->isRunning();
 }
 
 /**
diff --git a/Code/Mantid/MantidPlot/src/Script.h b/Code/Mantid/MantidPlot/src/Script.h
index c4e1ee819da767bbeee5eb8bc1f8811ee28f1be0..fed403184b66603d3ddba216f23013faf11455c0 100644
--- a/Code/Mantid/MantidPlot/src/Script.h
+++ b/Code/Mantid/MantidPlot/src/Script.h
@@ -32,16 +32,14 @@
 #include <QVariant>
 #include <QString>
 #include <QStringList>
-#include <QObject>
-#include <QStringList>
 #include <QEvent>
-
-#include "ScriptingEnv.h"
+#include <QFuture>
 
 //-------------------------------------------
 // Forward declarations
 //-------------------------------------------
 class ApplicationWindow;
+class ScriptingEnv;
 
 /**
  * Script objects represent a chunk of code, possibly together with local
@@ -53,60 +51,55 @@ class Script : public QObject
   Q_OBJECT
 
   public:
+  /// Interaction type
+  enum InteractionType {Interactive, NonInteractive};
+
   /// Constructor
-  Script(ScriptingEnv *env, const QString &code, QObject *context=NULL, 
-	 const QString &name="<input>", bool interactive = true, bool reportProgress = false);
+  Script(ScriptingEnv *env, const QString &name, const InteractionType interact,
+         QObject * context = NULL);
   /// Destructor
-  virtual ~Script();
-  /// Return the code that will be executed when calling exec() or eval()
-  const QString code() const { return Code; }
-  /// Return the context in which the code is to be executed.
-  const QObject* context() const { return Context; }
-  /// Like QObject::name, but with unicode support.
-  const QString name() const { return Name; }
-  /// Return whether errors / exceptions are to be emitted or silently ignored
-  bool emitErrors() const { return EmitErrors; }
-  /// Append to the code that will be executed when calling exec() or eval()
-  virtual void addCode(const QString &code);
-  /// Set the code that will be executed when calling exec() or eval()
-  virtual void setCode(const QString &code);
+  ~Script();
+  /// Returns the envirnoment this script is tied to
+  inline ScriptingEnv *environment() { return m_env; }
+  /// Returns the identifier for the script.
+  inline const QString name() const { return m_name; }
+  /// Returns the identifier as a C string
+  inline const char * nameAsCStr() const { return m_name.toAscii(); }
+  /// Update the identifier for the object.
+  void setName(const QString &name) { m_name = name; }
+  /// Return the current context
+  const QObject * context() const { return m_context; }
   /// Set the context in which the code is to be executed.
-  virtual void setContext(QObject *context) { Context = context; compiled = notCompiled; }
-  /// Like QObject::setName, but with unicode support.
-  void setName(const QString &name) { Name = name; compiled = notCompiled; }
-  /// Set whether errors / exceptions are to be emitted or silently ignored
-  void setEmitErrors(bool yes) { EmitErrors = yes; }
-  /// Whether we should be reporting progress  
-  bool reportProgress() const { return (m_interactive && m_report_progress); }
-  //!Set whether we should be reporting progress
-  void reportProgress(bool on) 
-  { 
-    if( Env->supportsProgressReporting() && m_interactive ) m_report_progress = on; 
-    else m_report_progress = false;
-  }
+  virtual void setContext(QObject *context) { m_context = context; }
+  /// Is this an interactive script
+  bool isInteractive() { return m_interactMode == Interactive; }
+
   bool redirectStdOut() const { return m_redirectOutput; }
   void redirectStdOut(bool on) { m_redirectOutput = on; }
-  // Set the line offset of the current code
-  void setLineOffset(int offset) { m_line_offset = offset; } 
-  // The current line offset
-  int getLineOffset() const { return m_line_offset; } 
+
   // Is anything running
-  bool scriptIsRunning() { return Env->isRunning(); }
+  bool scriptIsRunning();
+
 public slots:
-  /// Compile the Code. Return true if the implementation doesn't support compilation.
-  virtual bool compile(bool for_eval=true);
+  /// Compile the code, returning true/false depending on the status
+  virtual bool compile(const QString & code) = 0;
   /// Evaluate the Code, returning QVariant() on an error / exception.
-  virtual QVariant eval();
+  virtual QVariant evaluate(const QString & code) = 0;
   /// Execute the Code, returning false on an error / exception.
-  virtual bool exec();
+  virtual bool execute(const QString & code) = 0;
+  /// Execute the code asynchronously, returning immediately after the execution has started
+  virtual QFuture<bool> executeAsync(const QString & code) = 0;
+
   // local variables
   virtual bool setQObject(QObject*, const char*) { return false; }
   virtual bool setInt(int, const char*) { return false; }
   virtual bool setDouble(double, const char*) { return false; }
   
 signals:
-  /// This is emitted whenever the code to be executed by exec() and eval() is changed.
-  void codeChanged();
+  /// A signal defining when this script has started executing
+  void started(const QString & message);
+  /// A signal defining when this script has completed successfully
+  void finished(const QString & message);
   /// signal an error condition / exception
   void error(const QString & message, const QString & scriptName, int lineNumber);
   /// output generated by the code
@@ -115,28 +108,16 @@ signals:
   void currentLineChanged(int lineno, bool error);
   // Signal that new keywords are available
   void keywordsChanged(const QStringList & keywords);
-
-protected:
-  ScriptingEnv *Env;
-  QString Code, Name;
-  QObject *Context;
-  /// Should this be an interactive environment?
-  bool m_interactive;
-  /// Is progress reporting on?
-  bool m_report_progress;
-  enum compileStatus { notCompiled, isCompiled, compileErr } compiled;
-  bool EmitErrors;
-
-  void emit_error(const QString & message, int lineNumber)
-  { if(EmitErrors) emit error(message, Name, lineNumber); }
   
 private:
   /// Normalise line endings for the given code. The Python C/API does not seem to like CRLF endings so normalise to just LF
   QString normaliseLineEndings(QString text) const;
 
-private:
-  int m_line_offset;
-  bool m_redirectOutput; // Should the output be redirected?
+  ScriptingEnv *m_env;
+  QString m_name;
+  InteractionType m_interactMode;
+  QObject *m_context;
+  bool m_redirectOutput;
 };
 
 
diff --git a/Code/Mantid/MantidPlot/src/ScriptEdit.cpp b/Code/Mantid/MantidPlot/src/ScriptEdit.cpp
index 638efa1deb1da36d65edbd2c6a9e7abda37f6a14..b073f8ba2b8bc79eadd0690425f076be54ba59ac 100644
--- a/Code/Mantid/MantidPlot/src/ScriptEdit.cpp
+++ b/Code/Mantid/MantidPlot/src/ScriptEdit.cpp
@@ -319,7 +319,7 @@ void ScriptEdit::evaluate()
   if( code.isEmpty() ) return;
  
   myScript->setCode(code);
-  QVariant res = myScript->eval();
+  QVariant res = myScript->evaluate();
 
   if (res.isValid())
     if (!res.isNull() && res.canConvert(QVariant::String)){
diff --git a/Code/Mantid/MantidPlot/src/ScriptFileInterpreter.cpp b/Code/Mantid/MantidPlot/src/ScriptFileInterpreter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..243a21f0663d08ac887da8892cda71530cb55cb6
--- /dev/null
+++ b/Code/Mantid/MantidPlot/src/ScriptFileInterpreter.cpp
@@ -0,0 +1,243 @@
+#include "ScriptFileInterpreter.h"
+#include "ScriptOutputDisplay.h"
+#include "ScriptingEnv.h"
+#include "MantidQtMantidWidgets/ScriptEditor.h"
+
+#include <QVBoxLayout>
+#include <QFileInfo>
+#include <QMessageBox>
+#include <QMenu>
+#include <QAction>
+#include <QPushButton>
+
+/**
+ * Construct a widget
+ * @param parent :: The parent widget
+ */
+ScriptFileInterpreter::ScriptFileInterpreter(QWidget *parent)
+  : QWidget(parent), m_editor(new ScriptEditor(this,false,NULL)),
+    m_messages(new ScriptOutputDisplay), m_runner(),
+    m_execAll(NULL), m_execSelect(NULL)
+{
+  setFocusProxy(m_editor);
+  m_editor->setFocus();
+
+  QVBoxLayout *mainLayout = new QVBoxLayout;
+  mainLayout->addWidget(m_editor);
+  mainLayout->addWidget(m_messages);
+  mainLayout->setContentsMargins(0,0,0,0);
+  setLayout(mainLayout);
+
+  initActions();
+
+  connect(m_editor, SIGNAL(textChanged()), this, SIGNAL(textChanged()));
+}
+
+/// Destroy the object
+ScriptFileInterpreter::~ScriptFileInterpreter()
+{
+}
+
+/**
+ * Make sure the widget is ready to be deleted, i.e. saved etc
+ */
+void ScriptFileInterpreter::prepareToClose()
+{
+  if( !isScriptModified() ) return;
+
+  QMessageBox msgBox(this);
+  msgBox.setModal(true);
+  msgBox.setWindowTitle("MantidPlot");
+  msgBox.setText(tr("The current script has been modified."));
+  msgBox.setInformativeText(tr("Save changes?"));
+  msgBox.addButton(QMessageBox::Save);
+  QPushButton *saveAsButton = msgBox.addButton("Save As...", QMessageBox::AcceptRole);
+  msgBox.addButton(QMessageBox::Discard);
+  int ret = msgBox.exec();
+  if( msgBox.clickedButton() == saveAsButton )
+  {
+    m_editor->saveAs();
+  }
+  else if( ret == QMessageBox::Save )
+  {
+    m_editor->saveToCurrentFile();
+  }
+  else
+  {
+    m_editor->setModified(false);
+  }
+}
+
+/**
+ * Set up the widget from a given scripting environment
+ * @param environ :: A pointer to the current scripting environment
+ * @param identifier :: A string identifier, used mainly in error messages to identify the
+ * current script
+ */
+void ScriptFileInterpreter::setup(const ScriptingEnv & environ, const QString & identifier)
+{
+  setupEditor(environ, identifier);
+  setupScriptRunner(environ, identifier);
+}
+
+/**
+ * @return The string containing the filename of the script
+ */
+QString ScriptFileInterpreter::filename() const
+{
+  return m_editor->fileName();
+}
+
+/**
+ * Has the script been modified
+ * @return True if the script has been modified
+ */
+bool ScriptFileInterpreter::isScriptModified() const
+{
+  return m_editor->isModified();
+}
+
+/**
+ * Populate a menu with editing items
+ * @param fileMenu A reference to a menu object that is to be populated
+ */
+void ScriptFileInterpreter::populateFileMenu(QMenu &fileMenu)
+{
+  m_editor->populateFileMenu(fileMenu);
+
+}
+
+/**
+ * Populate a menu with editing items
+ * @param editMenu A reference to a menu object that is to be populated
+ */
+void ScriptFileInterpreter::populateEditMenu(QMenu &editMenu)
+{
+  m_editor->populateEditMenu(editMenu);
+  editMenu.insertSeparator();
+  m_messages->populateEditMenu(editMenu);
+}
+
+/**
+ * Fill execute menu
+ */
+void ScriptFileInterpreter::populateExecMenu(QMenu &execMenu)
+{
+  execMenu.addAction(m_execSelect);
+  execMenu.addAction(m_execAll);
+}
+
+/**
+ * Execute the whole script in the editor. This is always asynchronous
+ */
+void ScriptFileInterpreter::executeAll()
+{
+  executeCode(m_editor->text());
+}
+
+/**
+ * Execute the current selection from the editor. This is always asynchronous
+ */
+void ScriptFileInterpreter::executeSelection()
+{
+  executeCode(m_editor->selectedText());
+}
+
+
+
+/**
+ * Save the current script in the editor to a file
+ * @param filename :: The filename to save the script in
+ */
+void ScriptFileInterpreter::saveScript(const QString & filename)
+{
+  m_editor->saveScript(filename);
+}
+
+/**
+ * Save the current output text to a file
+ * @param filename :: The filename to save the script in
+ */
+
+void ScriptFileInterpreter::saveOutput(const QString & filename)
+{
+  m_messages->saveToFile(filename);
+}
+
+//-----------------------------------------------------------------------------
+// Private members
+//-----------------------------------------------------------------------------
+/**
+ * Create action objects
+ */
+void ScriptFileInterpreter::initActions()
+{
+  m_execSelect = new QAction(tr("E&xecute"), this);
+  m_execSelect->setShortcut(tr("Ctrl+Return"));
+  connect(m_execSelect, SIGNAL(activated()), this, SLOT(executeSelection()));
+
+  m_execAll = new QAction(tr("Execute &All"), this);
+  m_execAll->setShortcut(tr("Ctrl+Shift+Return"));
+  connect(m_execAll, SIGNAL(activated()), this, SLOT(executeAll()));
+}
+
+/**
+ * @param environ :: A pointer to the current scripting environment
+ * @param identifier :: A string identifier, used mainly in error messages to identify the
+ * current script
+ */
+void ScriptFileInterpreter::setupEditor(const ScriptingEnv & environ, const QString & identifier)
+{
+  if(QFileInfo(identifier).exists())
+  {
+    readFileIntoEditor(identifier);
+    m_editor->setFileName(identifier);
+  }
+  m_editor->setLexer(environ.createCodeLexer());
+  m_editor->setCursorPosition(0,0);
+}
+
+/**
+ * @param environ :: A pointer to the current scripting environment
+ * @param identifier :: A string identifier, used mainly in error messages to identify the
+ * current script
+ */
+void ScriptFileInterpreter::setupScriptRunner(const ScriptingEnv & environ, const QString & identifier)
+{
+  m_runner = QSharedPointer<Script>(environ.newScript(identifier,this, Script::Interactive));
+  connect(m_runner.data(), SIGNAL(started(const QString &)), m_messages, SLOT(displayMessageWithTimestamp(const QString &)));
+  connect(m_runner.data(), SIGNAL(finished(const QString &)), m_messages, SLOT(displayMessageWithTimestamp(const QString &)));
+  connect(m_runner.data(), SIGNAL(print(const QString &)), m_messages, SLOT(displayMessage(const QString &)));
+}
+
+/**
+ * Replace the contents of the editor with the given file
+ * @param filename
+ * @return True if the read succeeded, false otherwise
+ */
+bool ScriptFileInterpreter::readFileIntoEditor(const QString & filename)
+{
+  m_editor->setFileName(filename);
+  QFile scriptFile(filename);
+  if(!scriptFile.open(QIODevice::ReadOnly|QIODevice::Text))
+  {
+    QMessageBox::critical(this, tr("MantidPlot - File error"),
+        tr("Could not open file \"%1\" for reading.").arg(filename));
+    return false;
+  }
+  m_editor->read(&scriptFile);
+  m_editor->setModified(false);
+  scriptFile.close();
+  return true;
+}
+
+/**
+ * Use the current Script object to execute the code asynchronously
+ * @param code :: The code string to run
+ */
+void ScriptFileInterpreter::executeCode(const QString & code)
+{
+  if( code.isEmpty() ) return;
+  m_runner->executeAsync(code);
+
+}
diff --git a/Code/Mantid/MantidPlot/src/ScriptFileInterpreter.h b/Code/Mantid/MantidPlot/src/ScriptFileInterpreter.h
new file mode 100644
index 0000000000000000000000000000000000000000..ac3403556b2fcf9d2133f6365f39a12b2528365a
--- /dev/null
+++ b/Code/Mantid/MantidPlot/src/ScriptFileInterpreter.h
@@ -0,0 +1,80 @@
+#ifndef SCRIPTRUNNERWIDGET_H_
+#define SCRIPTRUNNERWIDGET_H_
+
+#include <QWidget>
+#include <QTextEdit>
+
+//-----------------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------------
+class Script;
+class ScriptingEnv;
+class ScriptEditor;
+class ScriptOutputDisplay;
+class QAction;
+
+/**
+ * Defines a widget that uses a ScriptEditor, a Script object and a
+ * text display widget to give a single widget that can
+ * edit, execute and display script code
+ *
+ */
+class ScriptFileInterpreter : public QWidget
+{
+  Q_OBJECT
+
+public:
+  /// Construct the object
+  ScriptFileInterpreter(QWidget *parent = NULL);
+  /// Destroy the object
+  ~ScriptFileInterpreter();
+  /// Make sure we are in a safe state to delete the widget
+  void prepareToClose();
+  /// Setup from a script environment
+  void setup(const ScriptingEnv & environ, const QString & identifier);
+
+  /// Return the filename of the script in the editor
+  QString filename() const;
+  /// Has the script text been modified
+  bool isScriptModified() const;
+
+  /// Fill a edit menu
+  void populateFileMenu(QMenu &fileMenu);
+  /// Fill a edit menu
+  void populateEditMenu(QMenu &editMenu);
+  /// Fill exec menu
+  void populateExecMenu(QMenu &execMenu);
+
+public slots:
+  /// Execute the whole script.
+  void executeAll();
+  /// Execute the current selection
+  void executeSelection();
+
+  /// Save the current script in the editor
+  void saveScript(const QString & filename);
+  /// Save the current output
+  void saveOutput(const QString & filename);
+
+signals:
+  /// Emits a signal when any text in the editor changes
+  void textChanged();
+
+private:
+  Q_DISABLE_COPY(ScriptFileInterpreter);
+  void initActions();
+  void setupEditor(const ScriptingEnv & environ, const QString & identifier);
+  void setupScriptRunner(const ScriptingEnv & environ, const QString & identifier);
+
+  bool readFileIntoEditor(const QString & filename);
+  void executeCode(const QString & code);
+
+  ScriptEditor *m_editor;
+  ScriptOutputDisplay *m_messages;
+  QSharedPointer<Script> m_runner;
+
+  QAction *m_execAll;
+  QAction *m_execSelect;
+};
+
+#endif /* SCRIPTRUNNERWIDGET_H_ */
diff --git a/Code/Mantid/MantidPlot/src/ScriptManagerWidget.cpp b/Code/Mantid/MantidPlot/src/ScriptManagerWidget.cpp
index 278b6e738fdb811d5e9b49f349b4f4911d151d8f..e0dbb2c853c405924738408e17aadbc0af1e3e6f 100644
--- a/Code/Mantid/MantidPlot/src/ScriptManagerWidget.cpp
+++ b/Code/Mantid/MantidPlot/src/ScriptManagerWidget.cpp
@@ -2,11 +2,12 @@
 // Includes
 //-----------------------------------------------------
 #include "ApplicationWindow.h"
-#include "MantidQtMantidWidgets/ScriptEditor.h"
-#include "Script.h"
+#include "ScriptFileInterpreter.h"
+
 #include "ScriptingEnv.h"
 #include "ScriptingLangDialog.h"
 #include "ScriptManagerWidget.h"
+
 // Qt
 #include <QPoint>
 #include <QAction>
@@ -40,49 +41,38 @@
 /**
  * Constructor
  */
-ScriptManagerWidget::ScriptManagerWidget(ScriptingEnv *env, QWidget *parent, bool interpreter_mode, bool capturePrint)
-  : QTabWidget(parent), Scripted(env), m_last_dir(""), m_script_runners(),
-    m_cursor_pos(), m_findrep_dlg(NULL), 
-    m_interpreter_mode(interpreter_mode), m_recentScriptList(), m_capturePrint(capturePrint)
+ScriptManagerWidget::ScriptManagerWidget(ScriptingEnv *env, QWidget *parent)
+  : QTabWidget(parent), Scripted(env), m_last_dir(""),
+    m_cursor_pos(), m_interpreter_mode(false), m_recentScriptList()
 {
   //Create actions for this widget
   initActions();
-
-  // Execution state change
-  connect(this, SIGNAL(ScriptIsActive(bool)), this, SLOT(setScriptIsRunning(bool)));
   
   // Start with a blank tab
   newTab();
-  QString group;
-  if( interpreter_mode )
+  if( m_interpreter_mode )
   {
-    tabBar()->hide();
-    setContextMenuPolicy(Qt::NoContextMenu);
-    ScriptEditor *editor = currentEditor();
-   
-    connect(editor, SIGNAL(executeLine(const QString&)), this, SLOT(executeInterpreter(const QString &)));
-    connect(this, SIGNAL(MessageToPrint(const QString&, bool,bool)), editor, 
-	    SLOT(displayOutput(const QString&,bool)));
-     connect(editor, SIGNAL(compile(const QString&)), this, SLOT(compile(const QString &)));
-      connect(editor, SIGNAL(executeMultiLine()), this, SLOT(executeMultiLine()));
-    group = "ScriptInterpreter";
+//    tabBar()->hide();
+//    setContextMenuPolicy(Qt::NoContextMenu);
+//    ScriptEditor *editor = currentEditor();
+//
+//    connect(editor, SIGNAL(executeLine(const QString&)), this, SLOT(executeInterpreter(const QString &)));
+//    connect(this, SIGNAL(MessageToPrint(const QString&, bool,bool)), editor,
+//	    SLOT(displayOutput(const QString&,bool)));
+//     connect(editor, SIGNAL(compile(const QString&)), this, SLOT(compile(const QString &)));
+//      connect(editor, SIGNAL(executeMultiLine()), this, SLOT(executeMultiLine()));
  
   }
-  else
-  {
-    group = "ScriptWindow";
-  }
   
   // Settings
   QSettings settings;
-  settings.beginGroup(group);
+  settings.beginGroup("ScriptWindow");
   m_toggle_folding->setChecked(settings.value("CodeFolding", true).toBool());
   m_toggle_completion->setChecked(settings.value("CodeCompletion", true).toBool());
   m_toggle_calltips->setChecked(settings.value("CallTips", true).toBool());
   settings.endGroup();
 
-  setFocusPolicy(Qt::StrongFocus);
-  setFocus();
+  connect(this, SIGNAL(currentChanged(int)), this, SLOT(tabSelectionChanged(int)));
 }
 
 /**
@@ -90,19 +80,6 @@ ScriptManagerWidget::ScriptManagerWidget(ScriptingEnv *env, QWidget *parent, boo
  */
 ScriptManagerWidget::~ScriptManagerWidget()
 {
-  if( m_findrep_dlg )
-  {
-    delete m_findrep_dlg;
-  }
-  
-  QList<ScriptEditor*> script_keys = m_script_runners.uniqueKeys();
-  QListIterator<ScriptEditor*> iter(script_keys);
-  while( iter.hasNext() )
-  {
-    Script *code = m_script_runners.take(iter.next());
-    delete code;
-  }
-
 }
 
 /**
@@ -110,16 +87,7 @@ ScriptManagerWidget::~ScriptManagerWidget()
  */
 void ScriptManagerWidget::saveSettings()
 {
-  QString group;
-  if( m_interpreter_mode )
-  {
-    group = "ScriptInterpreter";
-  }
-  else
-  {
-    group = "ScriptWindow";
-  }
-    
+  QString group("ScriptWindow");
   QSettings settings;
   settings.beginGroup(group);
   settings.setValue("/CodeFolding", m_toggle_folding->isChecked());
@@ -128,216 +96,90 @@ void ScriptManagerWidget::saveSettings()
   settings.endGroup();
 }
 
-/**
- * Ask whether we should save and then perform the correct action
- * @index The tab index
- */
-void ScriptManagerWidget::askSave(int index)
+/// @return The current interpreter
+ScriptFileInterpreter * ScriptManagerWidget::currentInterpreter()
 {
-  ScriptEditor *editor = qobject_cast<ScriptEditor*>(widget(index));
-  if( !editor || !editor->isModified() ) return;
-  // Check we the editor can be seen
-  this->show();
-  this->raise();
-  QMessageBox msg_box(this);
-  msg_box.setModal(true);
-  msg_box.setWindowTitle("MantidPlot");
-  msg_box.setText(tr("The current script has been modified."));
-  msg_box.setInformativeText(tr("Save changes?"));
-  msg_box.addButton(QMessageBox::Save);
-  QPushButton *saveAsButton = msg_box.addButton("Save As...", QMessageBox::AcceptRole);
-  msg_box.addButton(QMessageBox::Discard);
-  int ret = msg_box.exec();
-  if( msg_box.clickedButton() == saveAsButton )
-  {
-    saveAs(index);
-  }
-  else if( ret == QMessageBox::Save )
-  {
-    save(index);
-  }
-  else 
-  { 
-    editor->setModified(false);
-  }
+  return interpreterAt(currentIndex());
 }
 
-/**
- * Opens a script
- * @param filename :: An filename to use 
- * @param ok :: Indicate if the file read went ok
- * @returns The contents of the script
- */
-QString ScriptManagerWidget::readScript(const QString& filename, bool *ok)
+/// @return Interpreter at given index
+ScriptFileInterpreter * ScriptManagerWidget::interpreterAt(int index)
 {
-  QFile file(filename);
-  QString script_txt;
-  if( !file.open(QIODevice::ReadOnly|QIODevice::Text) )
-  {
-    QMessageBox::critical(this, tr("MantidPlot - File error"), 
-			  tr("Could not open file \"%1\" for reading.").arg(filename));
-    *ok = false;
-    return script_txt;
-  }
-  
-  QTextStream reader(&file);
-  reader.setEncoding(QTextStream::UnicodeUTF8);
-  while( !reader.atEnd() )
-  {
-    // Read line trims off line endings automatically and we'll simply use '\n' throughout 
-    script_txt.append(reader.readLine() + "\n");
-  }
-  file.close();
-  *ok = true;
-  return script_txt;
+  return qobject_cast<ScriptFileInterpreter*>(widget(index));
 }
 
+// ----------------------- Menus --------------------------------------------
 /**
- * Is a script running in the environment
+ *  Add the required entries for the file menu in this context
+ * @param fileMenu A pointer to the menu object to fill
  */
-bool ScriptManagerWidget::isScriptRunning()
+void ScriptManagerWidget::populateFileMenu(QMenu &fileMenu)
 {
-  return scriptingEnv()->isRunning();
-}
+  fileMenu.addAction(m_new_tab);
+  fileMenu.addAction(m_open_curtab);
+  fileMenu.addAction(m_open_newtab);
 
-/**
- * Return the current editor
- */
-ScriptEditor* ScriptManagerWidget::currentEditor() const
-{
-  if( count() == 0 ) return NULL;
-  return qobject_cast<ScriptEditor*>(currentWidget());
-}
-
-/**
- * Return the current runner
- */
-Script* ScriptManagerWidget::currentRunner() const
-{
-  if( count() == 0 ) return NULL;
-  ScriptEditor *editor = currentEditor();
-  Script *runner(NULL);
-  if (m_script_runners.contains(editor))
-  {
-    runner = m_script_runners.value(editor);
-  }
-  else
-  {
-    // This should never happen but if it does the situation should still be recoverable
-    QMessageBox::critical(const_cast<ScriptManagerWidget*>(this),"MantidPlot","Error accessing Python. Please save your work, close all tabs and reopen script.");
-  }
-  return runner;
-}
+  fileMenu.insertSeparator();
 
-/**
- * Undo action for the current editor
- */
-QAction* ScriptManagerWidget::undoAction() const
-{
-  if( ScriptEditor *editor = currentEditor() )
+  if( count() > 0)
   {
-    return editor->undoAction();
+    ScriptFileInterpreter *current = currentInterpreter();
+    current->populateFileMenu(fileMenu);
   }
-  else return NULL;
-}
-/**
- * Redo action for the current editor
- */
-QAction* ScriptManagerWidget::redoAction() const
-{
-  if( ScriptEditor *editor = currentEditor() )
-  {
-    return editor->redoAction();
-  }
-  else return NULL;
-}
 
-/**
- * Cut action for the current editor
- */
-QAction* ScriptManagerWidget::cutAction() const
-{
-  if( ScriptEditor *editor = currentEditor() )
-  {
-    return editor->cutAction();
-  }
-  else return NULL;
-}
+  fileMenu.insertSeparator();
+  fileMenu.addMenu(m_recent_scripts);
+  updateRecentScriptList();
 
-/** 
- * Copy action for the current editor
- */
-QAction* ScriptManagerWidget::copyAction() const
-{
-  if( ScriptEditor *editor = currentEditor() )
+  if( count() > 0)
   {
-    return editor->copyAction();
+    fileMenu.insertSeparator();
+    fileMenu.addAction(m_close_tab);
   }
-  else return NULL;
 }
-
 /**
- * Paste action for the current editor
+ *  Add the required entries for the edit menu in this context
+ * @param editMenu A pointer to the menu object to fill
  */
-QAction* ScriptManagerWidget::pasteAction() const
+void ScriptManagerWidget::populateEditMenu(QMenu &editMenu)
 {
-  if( ScriptEditor *editor = currentEditor() )
+  if( count() > 0 )
   {
-    return editor->pasteAction();
+    ScriptFileInterpreter *current = currentInterpreter();
+    current->populateEditMenu(editMenu);
   }
-  else return NULL;
 }
-
 /**
- * Print action for the current editor
+ *  Add the required entries for the execute menu in this context
+ * @param editMenu A pointer to the menu object to fill
  */
-QAction* ScriptManagerWidget::printAction() const
+void ScriptManagerWidget::populateExecMenu(QMenu &execMenu)
 {
-  if( ScriptEditor *editor = currentEditor() )
+  if( count() > 0 )
   {
-    return editor->printAction();
+    ScriptFileInterpreter *current = currentInterpreter();
+    current->populateExecMenu(execMenu);
   }
-  else return NULL;
 }
 
 /**
- * Print action for the current editor
+ * Is a script running in the environment
  */
-QAction* ScriptManagerWidget::zoomInAction() const
+bool ScriptManagerWidget::isScriptRunning()
 {
-  if( ScriptEditor *editor = currentEditor() )
-  {
-    return editor->zoomInAction();
-  }
-  else return NULL;
+  return scriptingEnv()->isRunning();
 }
 
-/**
- * Print action for the current editor
- */
-QAction* ScriptManagerWidget::zoomOutAction() const
-{
-  if( ScriptEditor *editor = currentEditor() )
-  {
-    return editor->zoomOutAction();
-  }
-  else return NULL;
-}
+
 /// copy method
 void ScriptManagerWidget::copy()
 {
-  if( ScriptEditor *editor = currentEditor() )
-  {
-    editor->copy();
-  }
+  QMessageBox::warning(this, "", "Copy not implemented");
 }
   ///paste method
 void ScriptManagerWidget::paste()
 {
-  if( ScriptEditor *editor = currentEditor() )
-  {
-    editor->paste();
-  }
+  QMessageBox::warning(this, "", "Paste not implemented");
   
 }
 //-------------------------------------------
@@ -348,43 +190,47 @@ void ScriptManagerWidget::paste()
  * @param index :: The index to give the new tab. If this is invalid the tab is simply appended
  * @param filename :: An optional filename
  */
-ScriptEditor* ScriptManagerWidget::newTab(int index, const QString & filename)
+void ScriptManagerWidget::newTab(int index, const QString & filename)
 {
-  ScriptEditor *editor = new ScriptEditor(this, m_interpreter_mode, scriptingEnv()->createCodeLexer());
-  editor->setFileName(filename);
-  if( !m_interpreter_mode )
-  {
-    connect(editor, SIGNAL(textChanged()), this, SLOT(markCurrentAsChanged()));
-  }
-  editor->setContextMenuPolicy(Qt::CustomContextMenu);
-  connect(editor, SIGNAL(customContextMenuRequested(const QPoint&)), 
-	  this, SLOT(editorContextMenu(const QPoint&)));
-  QString tab_title;
+  QString tabTitle;
   if( filename.isEmpty() )
   {
-    tab_title = "New script";
+    tabTitle = "New script";
   }
   else
   {
-    tab_title = QFileInfo(filename).fileName();
+    tabTitle = QFileInfo(filename).fileName();
   }
-  index = insertTab(index, editor, tab_title);
+//  if( m_interpreter_mode )
+//  {
+//    ScriptEditor *editor = new ScriptEditor(this, m_interpreter_mode, scriptingEnv()->createCodeLexer());
+//    editor->setFileName(filename);
+//    editor->setContextMenuPolicy(Qt::CustomContextMenu);
+//    connect(editor, SIGNAL(customContextMenuRequested(const QPoint&)),
+//      this, SLOT(editorContextMenu(const QPoint&)));
+//    index = insertTab(index, editor, tabTitle);
+//
+//    // Store a script runner
+//    Script * runner = createScriptRunner(editor);
+//    m_script_runners.insert(editor, runner);
+//
+//    // Completion etc
+//    setCodeCompletionBehaviour(editor, m_toggle_completion->isChecked());
+//    setCallTipsBehaviour(editor, m_toggle_calltips->isChecked());
+//    setCodeFoldingBehaviour(editor, m_toggle_folding->isChecked());
+//    // Set the current editor to focus
+//    setFocusProxy(editor);
+//    editor->setFocus();
+//    editor->setCursorPosition(0,0);
+//    return editor;
+//  }
+  ScriptFileInterpreter *scriptRunner = new ScriptFileInterpreter(this);
+  scriptRunner->setup(*scriptingEnv(), filename);
+  connect(scriptRunner, SIGNAL(textChanged()), this, SLOT(markCurrentAsChanged()));
+  index = insertTab(index, scriptRunner, tabTitle);
   setCurrentIndex(index);
-
-  // Store a script runner
-  Script * runner = createScriptRunner(editor);
-  m_script_runners.insert(editor, runner);
-
-  // Completion etc
-  setCodeCompletionBehaviour(editor, m_toggle_completion->isChecked());
-  setCallTipsBehaviour(editor, m_toggle_calltips->isChecked());
-  setCodeFoldingBehaviour(editor, m_toggle_folding->isChecked());
-  // Set the current editor to focus
-  setFocusProxy(editor);
-  editor->setFocus();
-  editor->setCursorPosition(0,0);
+  scriptRunner->setFocus();
   m_last_active_tab = index;
-  return editor;
 }
 
 /**
@@ -393,7 +239,6 @@ ScriptEditor* ScriptManagerWidget::newTab(int index, const QString & filename)
  */
 void ScriptManagerWidget::openInCurrentTab(const QString & filename)
 {
-  // Redirect work
   open(false, filename);
 }
 
@@ -403,56 +248,9 @@ void ScriptManagerWidget::openInCurrentTab(const QString & filename)
  */
 void ScriptManagerWidget::openInNewTab(const QString & filename)
 {
-  // Redirect work
   open(true, filename);
 }
 
-/**
- * Save script under a different file name
- * @param The :: index of the tab to save
- */
-QString ScriptManagerWidget::saveAs(int index)
-{
-  QString filter = scriptingEnv()->fileFilter();
-  filter += tr("Text") + " (*.txt *.TXT);;";
-  filter += tr("All Files")+" (*)";
-  QString selected_filter;
-  QString file_to_save = QFileDialog::getSaveFileName(this, tr("MantidPlot - Save script"), 
-						      m_last_dir, filter, &selected_filter);
-  if( file_to_save.isEmpty() ) return QString();
-
-  // Set last directory
-  m_last_dir = QFileInfo(file_to_save).absolutePath();
-  if( index == -1 ) index = currentIndex();
-  ScriptEditor *editor = qobject_cast<ScriptEditor*>(widget(index));
-  editor->setFileName(file_to_save);
-  doSave(editor);
-  return file_to_save;
-}
-
-/**
- * Save the tab text given by the index
- * @param The :: index of the tab to save
- */
-void ScriptManagerWidget::save(int index)
-{
-  if( index == -1 ) index = currentIndex();    
-  ScriptEditor *editor = qobject_cast<ScriptEditor*>(widget(index));
-  if( editor && editor->isModified() )
-  {
-    QString filename = editor->fileName();
-    //Open dialog if necessary
-    if( filename.isEmpty() )
-    {
-      saveAs(index);
-    }
-    else
-    {
-      doSave(editor);
-    }
-  }
-}
-
 /**
  * Close all tabs
  */
@@ -472,61 +270,41 @@ void ScriptManagerWidget::closeAllTabs()
 */
 QString ScriptManagerWidget::saveToString()
 {
-	QString fileNames;
-	fileNames="<scriptwindow>\n";
-	fileNames+="ScriptNames\t";
-	 int ntabs = count();
-	 //get the number of tabs and append  the script file name for each tab
-	 //to a string
-	 for( int index = 0; index < ntabs; ++index )
+  QString fileNames;
+  fileNames="<scriptwindow>\n";
+  fileNames+="ScriptNames\t";
+  int ntabs = count();
+  //get the number of tabs and append  the script file name for each tab
+  //to a string
+  for( int index = 0; index < ntabs; ++index )
+  {
+    ScriptFileInterpreter *interpreter = interpreterAt(index);
+    QString s = interpreter->filename();
+    if(!s.isEmpty())
     {
-      ScriptEditor *editor = static_cast<ScriptEditor*>(widget(index));
-      QString s = editor->fileName();
-	  if(!s.isEmpty())
-	  {fileNames+=s;
-	   fileNames+="\t";
-	  }
-	 }
-	 fileNames+="\n</scriptwindow>\n";
-	return fileNames;
+      fileNames+=s;
+      fileNames+="\t";
+    }
+  }
+  fileNames+="\n</scriptwindow>\n";
+  return fileNames;
 }
 /**
  * Execute the highlighted code from the current tab
  */
-void ScriptManagerWidget::execute()
+void ScriptManagerWidget::executeAll()
 {
-  if( isScriptRunning() ) return;
-  //Current editor
-  ScriptEditor *editor = currentEditor();
-  if( !editor ) return;
-
-  QString code = editor->selectedText();
-  if( code.isEmpty() )
-  {
-    executeAll();
-    return;
-  }
-  int lineFrom(0), indexFrom(0), lineTo(0), indexTo(0);
-  //Qscintilla function
-  editor->getSelection(&lineFrom, &indexFrom, &lineTo, &indexTo);
-  runScriptCode(code, lineFrom);
+  ScriptFileInterpreter *currentTab = qobject_cast<ScriptFileInterpreter*>(widget(currentIndex()));
+  currentTab->executeAll();
 }
 
 /**
  * Execute the whole script
  */
-void ScriptManagerWidget::executeAll()
+void ScriptManagerWidget::executeSelection()
 {
-  if( isScriptRunning() ) return;
-  //Current editor
-  ScriptEditor *editor = currentEditor();
-  if( !editor ) return;
-
-  QString script_txt = editor->text();
-  if( script_txt.isEmpty() ) return;
-  
-  //Run the code
-  runScriptCode(script_txt, 0);
+  ScriptFileInterpreter *currentTab = qobject_cast<ScriptFileInterpreter*>(widget(currentIndex()));
+  currentTab->executeSelection();
 }
 
 /**
@@ -543,16 +321,16 @@ void ScriptManagerWidget::evaluate()
  */
 void ScriptManagerWidget::executeInterpreter(const QString & code)
 {
-  if( isScriptRunning() ) return;
-  ScriptEditor *editor = currentEditor();
-  if( !editor ) return;
-  
-  int lineno,index;
-  editor->getCursorPosition(&lineno, &index);
-  runScriptCode(code,lineno);
-  
-  editor->newInputLine();
-  setFocus();  
+//  if( isScriptRunning() ) return;
+//  ScriptEditor *editor = currentEditor();
+//  if( !editor ) return;
+//
+//  int lineno,index;
+//  editor->getCursorPosition(&lineno, &index);
+//  runScriptCode(code,lineno);
+//
+//  editor->newInputLine();
+//  setFocus();
 }
 
 /** 
@@ -560,64 +338,19 @@ void ScriptManagerWidget::executeInterpreter(const QString & code)
  */
 void ScriptManagerWidget::executeMultiLine()
 {
-  ScriptEditor *editor = currentEditor();
-  if(!editor)
-  {
-    return;
-  }
-  int lineno,index;
-  editor->getCursorPosition(&lineno, &index);
-  runMultiLineCode(lineno);
-  editor->append("\n");
-  int marker_handle= editor->markerDefine(QsciScintilla::ThreeRightArrows);
-  editor->setMarkerHandle(marker_handle);
-  editor->newInputLine();
-  setFocus(); 
-}
-
-/**
- * Run a piece of code in the current environment
- * @param code :: The chunk of code to execute
- * @param line_offset :: If this is a chunk of code from an editor, give offset from the start
- */
-bool ScriptManagerWidget::runScriptCode(const QString & code, const int line_offset)
-{
-  if( isScriptRunning() ) return false;
-
-  Script * runner = currentRunner();
-  if( !runner ) return false;
-  runner->setLineOffset(line_offset);
-  ScriptEditor *editor = currentEditor();
-  if( editor ) 
-  {
-    connect(runner, SIGNAL(currentLineChanged(int, bool)), editor, SLOT(updateMarker(int, bool)));
-  }
-  runner->setCode(code);
-  QString filename = "<input>";
-  if( editor && !editor->fileName().isEmpty() )
-  {
-    filename = editor->fileName();
-  }
-  runner->setName(filename);
-  emit ScriptIsActive(true);
-
-  if( !m_interpreter_mode ) 
-  {
-    displayOutput("Script execution started.", true);
-  }
-
-  bool success = runner->exec();
-  emit ScriptIsActive(false);
-  if( !m_interpreter_mode && success )
-  {
-    displayOutput("Script execution completed successfully.", true);
-  }
-  if( editor )
-  {
-    disconnect(runner, SIGNAL(currentLineChanged(int, bool)), editor, 
-	       SLOT(updateMarker(int, bool)));
-  }
-  return success;
+//  ScriptEditor *editor = currentEditor();
+//  if(!editor)
+//  {
+//    return;
+//  }
+//  int lineno,index;
+//  editor->getCursorPosition(&lineno, &index);
+//  runMultiLineCode(lineno);
+//  editor->append("\n");
+//  int marker_handle= editor->markerDefine(QsciScintilla::ThreeRightArrows);
+//  editor->setMarkerHandle(marker_handle);
+//  editor->newInputLine();
+//  setFocus();
 }
 
 /**
@@ -626,29 +359,29 @@ bool ScriptManagerWidget::runScriptCode(const QString & code, const int line_off
  */
 void ScriptManagerWidget::compile(const QString & code)
 {
-  ScriptEditor *editor = currentEditor();
-  if(!editor)
-  {
-    return ;
-  }// Get the correct script runner
-  Script * runner = currentRunner();
-  int lineno,index;
-  editor->getCursorPosition(&lineno, &index);
-  runner->setLineOffset(lineno);
-  runner->setCode(code);
-  emit ScriptIsActive(true);
-   
-  bool success = runner->compile(true);
-  emit ScriptIsActive(false);
- 
-  if(success)
-  {
-    editor->setCompilationStatus(true);
-  }
-  else
-  { 
-    editor->setCompilationStatus(false);
-  }
+//  ScriptEditor *editor = currentEditor();
+//  if(!editor)
+//  {
+//    return ;
+//  }// Get the correct script runner
+//  Script * runner = currentRunner();
+//  int lineno,index;
+//  editor->getCursorPosition(&lineno, &index);
+//  runner->setLineOffset(lineno);
+//  runner->setCode(code);
+//  emit ScriptIsActive(true);
+//
+//  bool success = runner->compile(true);
+//  emit ScriptIsActive(false);
+//
+//  if(success)
+//  {
+//    editor->setCompilationStatus(true);
+//  }
+//  else
+//  {
+//    editor->setCompilationStatus(false);
+//  }
  
 }
 /**Run the multi line code set to runner
@@ -657,34 +390,15 @@ void ScriptManagerWidget::compile(const QString & code)
  */
 bool ScriptManagerWidget::runMultiLineCode(int line_offset)
 {
-  // Get the correct script runner
-  Script * runner = currentRunner();
-  emit ScriptIsActive(true);
-  runner->setLineOffset(line_offset);
-  bool success = runner->exec();
-  emit ScriptIsActive(false);
-  return success;
-}
-/** 
- * Display an output message
- * @param msg :: The message string
- * @param timestamp :: Whether to display a timestamp
- */
-void ScriptManagerWidget::displayOutput(const QString & msg, bool timestamp)
-{  
-  //Forward to helper
-  emit MessageToPrint(msg, false, timestamp);
-}
-
-/**
- * Display an error message
- * @param msg :: The message string
- * @param timestamp :: Whether to display a timestamp
- */
-void ScriptManagerWidget::displayError(const QString & msg, bool timestamp)
-{ 
-  //Forward to helper
-  emit MessageToPrint(msg, true, timestamp);
+//  // Get the correct script runner
+//  Script * runner = currentRunner();
+//  emit ScriptIsActive(true);
+//
+//  runner->setLineOffset(line_offset);
+//  bool success = runner->exec();
+//
+//  emit ScriptIsActive(false);
+//  return success;
 }
 
 /**
@@ -694,15 +408,17 @@ void ScriptManagerWidget::displayError(const QString & msg, bool timestamp)
 void ScriptManagerWidget::showFindDialog(bool replace)
 {
   if( count() == 0 ) return;
-  if( !m_findrep_dlg )
-  {
-    m_findrep_dlg = new FindReplaceDialog(this, replace, this);
-    connect(this, SIGNAL(currentChanged(int)), m_findrep_dlg, SLOT(resetSearchFlag()));
-  }
-  if( !m_findrep_dlg->isVisible() )
-  {
-    m_findrep_dlg->show();
-  }
+//  if( !m_findrep_dlg )
+//  {
+//    m_findrep_dlg = new FindReplaceDialog(this, replace, this);
+//    connect(this, SIGNAL(currentChanged(int)), m_findrep_dlg, SLOT(resetSearchFlag()));
+//  }
+//  if( !m_findrep_dlg->isVisible() )
+//  {
+//    m_findrep_dlg->show();
+//  }
+
+  QMessageBox::information(this, "MantidPlot", "Find not implemented");
 }
 
 
@@ -714,44 +430,43 @@ void ScriptManagerWidget::showFindDialog(bool replace)
  */
 void ScriptManagerWidget::editorContextMenu(const QPoint &)
 {
-  QMenu context(this);
-
-  if( !m_interpreter_mode ) 
-  {
-    //File actions
-    context.addAction(m_open_curtab);
-    context.addAction(m_save);
-    context.addAction(printAction());
-    
-    
-    
-    context.insertSeparator();
-    
-    //Evaluate and execute
-    context.addAction(m_exec);
-    context.addAction(m_exec_all);
-    if( scriptingEnv()->supportsEvaluation() )
-    {
-      context.addAction(m_eval);
-    }
-  }
-   
-  // Edit actions
-   context.insertSeparator();
-   context.addAction(copyAction());
-   context.addAction(cutAction());
-   context.addAction(pasteAction());
- 
-   context.insertSeparator();
-
-   context.addAction(zoomInAction());
-   context.addAction(zoomOutAction());
-
-   context.insertSeparator();
-
-  context.addAction(m_toggle_completion);
-  context.addAction(m_toggle_calltips);
-  context.exec(QCursor::pos());
+//  QMenu context(this);
+//
+//  if( !m_interpreter_mode )
+//  {
+//    //File actions
+//    context.addAction(m_open_curtab);
+//    context.addAction(m_save);
+//    context.addAction(printAction());
+//
+//
+//    context.insertSeparator();
+//
+//    //Evaluate and execute
+//    context.addAction(m_exec);
+//    context.addAction(m_exec_all);
+//    if( scriptingEnv()->supportsEvaluation() )
+//    {
+//      context.addAction(m_eval);
+//    }
+//  }
+//
+//  // Edit actions
+//   context.insertSeparator();
+//   context.addAction(copyAction());
+//   context.addAction(cutAction());
+//   context.addAction(pasteAction());
+//
+//   context.insertSeparator();
+//
+//   context.addAction(zoomInAction());
+//   context.addAction(zoomOutAction());
+//
+//   context.insertSeparator();
+//
+//  context.addAction(m_toggle_completion);
+//  context.addAction(m_toggle_calltips);
+//  context.exec(QCursor::pos());
 }
 
 /**
@@ -759,9 +474,13 @@ void ScriptManagerWidget::editorContextMenu(const QPoint &)
  */
 int ScriptManagerWidget::closeCurrentTab()
 {
-  int index = currentIndex();
-  closeTabAtIndex(index);
-  return index;
+  if( count() > 0 )
+  {
+    int index = currentIndex();
+    closeTabAtIndex(index);
+    return index;
+  }
+  return -1;
 }
 
 /**
@@ -774,14 +493,30 @@ void ScriptManagerWidget::closeClickedTab()
 }
 
 /**
- * Mark the current tab as changed
+ * Mark the current tab as changed. The signal is disconnected
+ * from the emitting widget so that multiple calls are not performed
  */
 void ScriptManagerWidget::markCurrentAsChanged()
 {
   int index = currentIndex();
   setTabText(index, tabText(index) + "*");
-  //Disconnect signal so that this doesn't get run in the future
-  disconnect( currentEditor(), SIGNAL(textChanged()), this, SLOT(markCurrentAsChanged()));
+  // Disconnect signal so that this doesn't get run in the future
+  ScriptFileInterpreter *currentWidget = qobject_cast<ScriptFileInterpreter*>(widget(index));
+  disconnect(currentWidget, SIGNAL(textChanged()), this, SLOT(markCurrentAsChanged()));
+}
+
+/**
+ * The current selection has changed
+ * @param index The index of the new selection
+ */
+void ScriptManagerWidget::tabSelectionChanged(int index)
+{
+  if( count() > 0 )
+  {
+    ScriptFileInterpreter *currentWidget = qobject_cast<ScriptFileInterpreter*>(widget(index));
+    setFocusProxy(currentWidget);
+    currentWidget->setFocus();
+  }
 }
 
 /**
@@ -790,10 +525,6 @@ void ScriptManagerWidget::markCurrentAsChanged()
  */
 void ScriptManagerWidget::setScriptIsRunning(bool running)
 {
-  // Enable/disable execute actions
-  m_exec->setEnabled(!running);
-  m_exec_all->setEnabled(!running);
-  if( scriptingEnv()->supportsEvaluation() ) m_eval->setEnabled(!running);
 }
 
 /**
@@ -805,10 +536,7 @@ void ScriptManagerWidget::toggleProgressArrow(bool state)
   int index_end = count() - 1;
   for( int index = index_end; index >= 0; --index )
   {
-    ScriptEditor *editor = static_cast<ScriptEditor*>(widget(index));
-    if( editor ) editor->setMarkerState(state);
-    Script *script = m_script_runners.value(editor);
-    if( script ) script->reportProgress(state);
+    QMessageBox::warning(this, "", "Implement progress arrow");
   }
 }
 
@@ -821,10 +549,7 @@ void ScriptManagerWidget::toggleCodeFolding(bool state)
   int index_end = count() - 1;
   for( int index = index_end; index >= 0; --index )
   {
-    if( ScriptEditor *editor = qobject_cast<ScriptEditor*>(this->widget(index)) )
-    { 
-      setCodeFoldingBehaviour(editor, state);
-    }
+    QMessageBox::warning(this, "", "Implement code folding");
   }
 }
 /**
@@ -836,10 +561,7 @@ void ScriptManagerWidget::toggleCodeCompletion(bool state)
   int index_end = count() - 1;
   for( int index = index_end; index >= 0; --index )
   {
-    if( ScriptEditor *editor = qobject_cast<ScriptEditor*>(this->widget(index)) )
-    {
-      setCodeCompletionBehaviour(editor, state);
-    }
+    QMessageBox::warning(this, "", "Implement code completion");
   }
 }
 
@@ -852,10 +574,7 @@ void ScriptManagerWidget::toggleCallTips(bool state)
   int index_end = count() - 1;
   for( int index = index_end; index >= 0; --index )
   {
-    if( ScriptEditor *editor = qobject_cast<ScriptEditor*>(this->widget(index)) )
-    {
-      setCallTipsBehaviour(editor, state);
-    }
+    QMessageBox::warning(this, "", "Implement call tips");
   }
 }
 
@@ -880,14 +599,8 @@ void ScriptManagerWidget::initActions()
   m_open_newtab = new QAction(tr("&Open in New Tab"), this);
   m_open_newtab->setShortcut(tr("Ctrl+Shift+O"));
   connect(m_open_newtab, SIGNAL(activated()), this, SLOT(openInNewTab()));
-  //Save a script
-  m_save = new QAction(tr("&Save"), this);
-  m_save->setShortcut(tr("Ctrl+S"));
-  connect(m_save, SIGNAL(activated()), this , SLOT(save()));
-  //Save a script under a new file name
-  m_saveas = new QAction(tr("&Save As"), this);
-  connect(m_saveas, SIGNAL(activated()), this , SLOT(saveAs()));
-  m_saveas->setShortcut(tr("Ctrl+Shift+S"));
+
+
   //Close the current tab
   m_close_tab = new QAction(tr("&Close Tab"), this);
   m_close_tab->setShortcut(tr("Ctrl+W"));
@@ -902,18 +615,6 @@ void ScriptManagerWidget::initActions()
   m_find->setShortcut(tr("Ctrl+F"));
   connect(m_find, SIGNAL(activated()), this, SLOT(showFindDialog()));
 
-  // **Execute** actions
-  m_exec = new QAction(tr("E&xecute"), this);
-  m_exec->setShortcut(tr("Ctrl+Return"));
-  connect(m_exec, SIGNAL(activated()), this, SLOT(execute()));
-  m_exec_all = new QAction(tr("Execute &All"), this);
-  m_exec_all->setShortcut(tr("Ctrl+Shift+Return"));
-  connect(m_exec_all, SIGNAL(activated()), this, SLOT(executeAll()));
-  m_eval = new QAction(tr("&Evaluate Expression"), this);
-  m_eval->setShortcut( tr("Ctrl+E") );
-  connect(m_eval, SIGNAL(activated()), this, SLOT(evaluate()));
-  m_eval->setEnabled(scriptingEnv()->supportsEvaluation());
-
   // Toggle the progress arrow
   m_toggle_progress = new QAction(tr("Show &Progress Marker"), this);
   m_toggle_progress->setCheckable(true);
@@ -989,14 +690,7 @@ void ScriptManagerWidget::customEvent(QEvent *event)
     // This handles reference counting of the scripting environment
     Scripted::scriptingChangeEvent(sce);
 
-    // Update the code lexers for each tab
-    int ntabs = count();
-    for( int index = 0; index < ntabs; ++index )
-    {
-      ScriptEditor *editor = static_cast<ScriptEditor*>(widget(index));
-      editor->setLexer(scriptingEnv()->createCodeLexer());
-      m_script_runners[editor] = createScriptRunner(editor);
-    }
+    QMessageBox::warning(this, "", "Implement script changing");
   }
 }
 
@@ -1007,87 +701,32 @@ void ScriptManagerWidget::customEvent(QEvent *event)
  */
 void ScriptManagerWidget::open(bool newtab, const QString & filename)
 {
-  if( !newtab ) askSave(currentIndex());
-  QString file_to_open = filename;
-  if( filename.isEmpty() )
+  QString fileToOpen = filename;
+  if( fileToOpen.isEmpty() )
   {
     QString filter = scriptingEnv()->fileFilter();
     filter += tr("Text") + " (*.txt *.TXT);;";
     filter += tr("All Files")+" (*)";
-    file_to_open = QFileDialog::getOpenFileName(this, tr("MantidPlot - Open a script from a file"), 
-						m_last_dir, filter);
-    if( file_to_open.isEmpty() ) 
+    fileToOpen = QFileDialog::getOpenFileName(this, tr("MantidPlot - Open a script from a file"),
+        m_last_dir, filter);
+    if( fileToOpen.isEmpty() )
     {
       return;
     }
   }
   /// remove the file name from script list
-  m_recentScriptList.remove(file_to_open); 
+  m_recentScriptList.remove(fileToOpen);
   //add the script file to recent scripts list 
-  m_recentScriptList.push_front(file_to_open); 
+  m_recentScriptList.push_front(fileToOpen);
   //update the recent scripts menu 
   updateRecentScriptList();
  
   //Save last directory
-  m_last_dir = QFileInfo(file_to_open).absolutePath();
-  
-  bool ok(false);
-  QString script_txt = readScript(file_to_open, &ok);
-  if( !ok ) return;
+  m_last_dir = QFileInfo(fileToOpen).absolutePath();
 
   int index(-1);
-  if( !newtab )
-  {
-    // This asks about saving again but since it's already taken care of
-    // then it'll be quick
-    index = closeCurrentTab();
-  }
-  
-  ScriptEditor *editor = newTab(index, file_to_open);
-  editor->blockSignals(true);
-  editor->append(script_txt);
-  editor->update();
-  editor->blockSignals(false);
-
-  editor->setCursorPosition(0,0);
-  
-  // Set last directory
-  m_last_dir = QFileInfo(file_to_open).absolutePath();
-}
-
-/**
- * Create and return a new Script object, connecting up the relevant signals.
- * @param An :: optional ScriptEditor object
- */
-Script * ScriptManagerWidget::createScriptRunner(ScriptEditor *editor)
-{
-  QString filename("");
-  if( editor ) filename = editor->fileName();
-  Script *script = scriptingEnv()->newScript("", this, filename, true,
-                                             m_toggle_progress->isChecked());
-  if( m_capturePrint )
-  {
-    // Connect the signals that print output and error messages to the formatting functions
-    connect(script, SIGNAL(print(const QString &)), this, SLOT(displayOutput(const QString &)));
-    connect(script, SIGNAL(error(const QString &, const QString&, int)), this,
-            SLOT(displayError(const QString &)));
-  }
-  else
-  {
-    script->redirectStdOut(false);
-  }
-  if( editor )
-  {
-    connect(script, SIGNAL(keywordsChanged(const QStringList&)), editor, 
-      SLOT(updateCompletionAPI(const QStringList &)));
-    /// Initialize the auto complete by evaluating some completely trivial code
-    if( !scriptingEnv()->isRunning() )
-    {
-      script->setCode("1");
-      script->exec();
-    }
-  }
-  return script;
+  if( !newtab ) index = closeCurrentTab();
+  newTab(index, fileToOpen);
 }
 
 /**
@@ -1096,24 +735,8 @@ Script * ScriptManagerWidget::createScriptRunner(ScriptEditor *editor)
  */ 
 void ScriptManagerWidget::closeTabAtIndex(int index)
 {
-  ScriptEditor *editor = qobject_cast<ScriptEditor*>(widget(index));
-  if( !editor ) return;
-  //Check if we need to save
-  askSave(index);
-  editor->disconnect();
-  // Remove the path from the script runner
-  Script *runner = m_script_runners.take(editor);
-  runner->disconnect();
-  //Get the widget attached to the tab first as this is not deleted
-  //when remove is called
-  editor->deleteLater();
-  runner->deleteLater();
-
-  //  If we are removing the final tab, close the find replace dialog if it exists and is visible
-  if( m_findrep_dlg && m_findrep_dlg->isVisible() && count() == 1 )
-  {
-    m_findrep_dlg->close();
-  }
+  ScriptFileInterpreter *interpreter = qobject_cast<ScriptFileInterpreter*>(widget(index));
+  interpreter->prepareToClose();
   removeTab(index);
 }
 
@@ -1129,85 +752,73 @@ void ScriptManagerWidget::closeTabAtPosition(const QPoint & pos)
   closeTabAtIndex(index);
 }
 
-/** Writes the file to disk
- *  @param The :: editor tab to be saved
- */
-void ScriptManagerWidget::doSave(ScriptEditor * editor)
-{
-  QString filename = editor->fileName();
-  editor->saveScript(filename);
-  setTabText(currentIndex(), QFileInfo(filename).fileName());
-  editor->setModified(false);
-  connect(editor, SIGNAL(textChanged()), this, SLOT(markCurrentAsChanged()));
-}
-
-/** 
- * Set auto complete behaviour for the given editor
- * @param editor :: The editor widget to set the behaviour on
- * @param state :: The state required
- */
-void ScriptManagerWidget::setCodeCompletionBehaviour(ScriptEditor *editor, bool state)
-{
-  QsciScintilla::AutoCompletionSource api_source;
-  int threshold(-1);
-  if( state )
-  {
-    api_source = QsciScintilla::AcsAPIs;
-    threshold = 2;
-  }
-  else
-  {
-    api_source = QsciScintilla::AcsNone;
-    threshold = -1;
-  }
-  
-  editor->setAutoCompletionThreshold(threshold);  // threshold characters before autocomplete kicks in
-  editor->setAutoCompletionSource(api_source);
-}
-
-/** 
- * Set call tips behaviour for the given editor
- * @param editor :: The editor widget to set the behaviour on
- * @param state :: The state required
- */
-void ScriptManagerWidget::setCallTipsBehaviour(ScriptEditor *editor, bool state)
-{
-  QsciScintilla::CallTipsStyle tip_style;
-  int nvisible(-1);
-  if( state )
-  {
-    tip_style = QsciScintilla::CallTipsNoAutoCompletionContext;
-    nvisible = 0; // This actually makes all of them visible at the same time
-  }
-  else
-  {
-    tip_style = QsciScintilla::CallTipsNone;
-    nvisible = -1;
-  }
-
-  editor->setCallTipsVisible(nvisible);
-  editor->setCallTipsStyle(tip_style);
-}
-
-/** 
- * Set code folding behaviour for the given editor
- * @param editor :: The editor widget to set the behaviour on
- * @param state :: The state required
- */
-void ScriptManagerWidget::setCodeFoldingBehaviour(ScriptEditor *editor, bool state)
-{
-  QsciScintilla::FoldStyle fold_option;
-  if( state && !m_interpreter_mode )
-  {
-    fold_option = QsciScintilla::BoxedTreeFoldStyle;
-  }
-  else
-  {
-    fold_option = QsciScintilla::NoFoldStyle;
-  }
-  
-  editor->setFolding(fold_option);
-}
+///**
+// * Set auto complete behaviour for the given editor
+// * @param editor :: The editor widget to set the behaviour on
+// * @param state :: The state required
+// */
+//void ScriptManagerWidget::setCodeCompletionBehaviour(ScriptEditor *editor, bool state)
+//{
+//  QsciScintilla::AutoCompletionSource api_source;
+//  int threshold(-1);
+//  if( state )
+//  {
+//    api_source = QsciScintilla::AcsAPIs;
+//    threshold = 2;
+//  }
+//  else
+//  {
+//    api_source = QsciScintilla::AcsNone;
+//    threshold = -1;
+//  }
+//
+//  editor->setAutoCompletionThreshold(threshold);  // threshold characters before autocomplete kicks in
+//  editor->setAutoCompletionSource(api_source);
+//}
+//
+///**
+// * Set call tips behaviour for the given editor
+// * @param editor :: The editor widget to set the behaviour on
+// * @param state :: The state required
+// */
+//void ScriptManagerWidget::setCallTipsBehaviour(ScriptEditor *editor, bool state)
+//{
+//  QsciScintilla::CallTipsStyle tip_style;
+//  int nvisible(-1);
+//  if( state )
+//  {
+//    tip_style = QsciScintilla::CallTipsNoAutoCompletionContext;
+//    nvisible = 0; // This actually makes all of them visible at the same time
+//  }
+//  else
+//  {
+//    tip_style = QsciScintilla::CallTipsNone;
+//    nvisible = -1;
+//  }
+//
+//  editor->setCallTipsVisible(nvisible);
+//  editor->setCallTipsStyle(tip_style);
+//}
+//
+///**
+// * Set code folding behaviour for the given editor
+// * @param editor :: The editor widget to set the behaviour on
+// * @param state :: The state required
+// */
+//void ScriptManagerWidget::setCodeFoldingBehaviour(ScriptEditor *editor, bool state)
+//{
+//  QsciScintilla::FoldStyle fold_option;
+//  if( state && !m_interpreter_mode )
+//  {
+//    fold_option = QsciScintilla::BoxedTreeFoldStyle;
+//  }
+//  else
+//  {
+//    fold_option = QsciScintilla::NoFoldStyle;
+//  }
+//
+//  editor->setFolding(fold_option);
+//}
 
 /** 
  * open the selected script from the File->Recent Scripts  in a new tab
@@ -1215,7 +826,7 @@ void ScriptManagerWidget::setCodeFoldingBehaviour(ScriptEditor *editor, bool sta
  */
 void ScriptManagerWidget::openRecentScript(int index)
 {
-  QString scriptname=m_recent_scripts->text(index);
+  QString scriptname = m_recent_scripts->text(index);
   scriptname.remove(0,3);
   scriptname.trimmed();
   openInNewTab(scriptname); 
@@ -1235,7 +846,9 @@ void ScriptManagerWidget::updateRecentScriptList()
 
   m_recent_scripts->clear();
   for (int i = 0; i<m_recentScriptList.size(); i++ )
+  {
     m_recent_scripts->insertItem("&" + QString::number(i+1) + " " + m_recentScriptList[i]);
+  }
 
 }
 
@@ -1256,6 +869,7 @@ void ScriptManagerWidget::setRecentScripts(const QStringList& rslist)
 {
   m_recentScriptList=rslist;
 }
+
 //***************************************************************************
 //
 // FindReplaceDialog class
@@ -1264,257 +878,257 @@ void ScriptManagerWidget::setRecentScripts(const QStringList& rslist)
 //------------------------------------------------------
 // Public member functions
 //------------------------------------------------------
-/**
- * Constructor
- */
-FindReplaceDialog::FindReplaceDialog(ScriptManagerWidget *manager, bool replace, QWidget* parent, Qt::WFlags fl )
-  : QDialog( parent, fl ), m_manager(manager), m_find_inprogress(false)
-{
-  setWindowTitle (tr("MantidPlot") + " - " + tr("Find"));
-  setSizeGripEnabled( true );
-
-  QGroupBox *gb1 = new QGroupBox();
-  QGridLayout *topLayout = new QGridLayout(gb1);
-
-  topLayout->addWidget( new QLabel(tr( "Find" )), 0, 0);
-  boxFind = new QComboBox();
-  boxFind->setEditable(true);
-  boxFind->setDuplicatesEnabled(false);
-  boxFind->setInsertPolicy( QComboBox::InsertAtTop );
-  boxFind->setAutoCompletion(true);
-  boxFind->setMaxCount ( 10 );
-  boxFind->setMaxVisibleItems ( 10 );
-  boxFind->setMinimumWidth(250);
-  boxFind->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
-  connect(boxFind, SIGNAL(editTextChanged(const QString &)), this, SLOT(resetSearchFlag()));
-
-  ScriptEditor *editor = m_manager->currentEditor();
-  if( editor->hasSelectedText() )
-  {
-    QString text = editor->selectedText();
-    boxFind->setEditText(text);
-    boxFind->addItem(text);
-  }
-
-  topLayout->addWidget(boxFind, 0, 1);
-
-  if( replace )
-  {
-    setWindowTitle (tr("MantidPlot") + " - " + tr("Find and Replace"));
-    topLayout->addWidget(new QLabel(tr( "Replace with" )), 1, 0);
-    boxReplace = new QComboBox();
-    boxReplace->setEditable(true);
-    boxReplace->setDuplicatesEnabled(false);
-    boxReplace->setInsertPolicy( QComboBox::InsertAtTop );
-    boxReplace->setAutoCompletion(true);
-    boxReplace->setMaxCount ( 10 );
-    boxReplace->setMaxVisibleItems ( 10 );
-    boxReplace->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
-    topLayout->addWidget( boxReplace, 1, 1);
-    topLayout->setColumnStretch(1, 10);
-  }
-
-  QGroupBox *gb2 = new QGroupBox();
-  QGridLayout * bottomLayout = new QGridLayout(gb2);
-  QButtonGroup *find_options = new QButtonGroup(this);
-  find_options->setExclusive(false);
-
-  boxCaseSensitive = new QCheckBox(tr("&Match case"));
-  boxCaseSensitive->setChecked(false);
-  bottomLayout->addWidget( boxCaseSensitive, 0, 0);
-  find_options->addButton(boxCaseSensitive);
-
-  boxWholeWords = new QCheckBox(tr("&Whole word"));
-  boxWholeWords->setChecked(false);
-  bottomLayout->addWidget(boxWholeWords, 1, 0);
-  find_options->addButton(boxWholeWords);
-
-  boxRegex = new QCheckBox(tr("&Regular expression"));
-  boxRegex->setChecked(false);
-  bottomLayout->addWidget(boxRegex, 2, 0);
-  find_options->addButton(boxRegex);
- 
-  boxSearchBackwards = new QCheckBox(tr("&Search backwards"));
-  boxSearchBackwards->setChecked(false);
-  bottomLayout->addWidget(boxSearchBackwards, 0, 1);
-  find_options->addButton(boxSearchBackwards);
-
-  boxWrapAround = new QCheckBox(tr("&Wrap around"));
-  boxWrapAround->setChecked(true);
-  bottomLayout->addWidget(boxWrapAround, 1, 1);
-  find_options->addButton(boxWrapAround);
-
-  connect(find_options, SIGNAL(buttonClicked(int)), this, SLOT(resetSearchFlag()));
-
-  QVBoxLayout *vb1 = new QVBoxLayout();
-  vb1->addWidget(gb1);
-  vb1->addWidget(gb2);
-
-  QVBoxLayout *vb2 = new QVBoxLayout();
-
-  buttonNext = new QPushButton(tr("&Next"));
-  buttonNext->setShortcut(tr("Ctrl+F"));
-  buttonNext->setDefault(true);
-  vb2->addWidget(buttonNext);
-
-  if( replace )
-  {
-    buttonReplace = new QPushButton(tr("&Replace"));
-    connect(buttonReplace, SIGNAL(clicked()), this, SLOT(replace()));
-    vb2->addWidget(buttonReplace);
-
-    buttonReplaceAll = new QPushButton(tr("Replace &all"));
-    connect(buttonReplaceAll, SIGNAL(clicked()), this, SLOT(replaceAll()));
-    vb2->addWidget(buttonReplaceAll);
-  }
-
-  buttonCancel = new QPushButton(tr("&Close"));
-  vb2->addWidget(buttonCancel);
-  vb2->addStretch();
-
-  QHBoxLayout *hb = new QHBoxLayout(this);
-  hb->addLayout(vb1);
-  hb->addLayout(vb2);
-
-  connect(buttonNext, SIGNAL(clicked()), this, SLOT(findClicked()));
-  connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
-}
-
-//------------------------------------------------------
-// Protected slot member functions
-//------------------------------------------------------
-/**
- * Find the current search term
- * @param backwards :: If true then the search procedes backwards from the cursor's current position
- * @returns A boolean indicating success/failure
- */
-bool FindReplaceDialog::find(bool backwards)
-{
-  QString searchString = boxFind->currentText();
-  if (searchString.isEmpty()){
-    QMessageBox::warning(this, tr("Empty Search Field"),
-			 tr("The search field is empty. Please enter some text and try again."));
-    boxFind->setFocus();
-    return false;
-  }
-
-  if(boxFind->findText(searchString) == -1)
-  {
-    boxFind->addItem(searchString);
-  }
-
-  if( m_find_inprogress )
-  {
-    m_find_inprogress = m_manager->currentEditor()->findNext();
-  }
-  else
-  {
-    bool cs = boxCaseSensitive->isChecked();
-    bool whole = boxWholeWords->isChecked();
-    bool wrap = boxWrapAround->isChecked();
-    bool regex = boxRegex->isChecked();
-    m_find_inprogress = m_manager->currentEditor()->findFirst(searchString, regex, cs, whole, wrap, !backwards);
-  }
-  return m_find_inprogress;
-}
-
-/**
- * Replace the next occurrence of the search term with the replacement text
- */
-void FindReplaceDialog::replace()
-{
-  QString searchString = boxFind->currentText();
-  if (searchString.isEmpty()){
-    QMessageBox::warning(this, tr("Empty Search Field"),
-			 tr("The search field is empty. Please enter some text and try again."));
-    boxFind->setFocus();
-    return;
-  }
-
-  if (!m_manager->currentEditor()->hasSelectedText() || m_manager->currentEditor()->selectedText() != searchString){
-    find();//find and select next match
-    return;
-  }
-
-  QString replaceString = boxReplace->currentText();
-  m_manager->currentEditor()->replace(replaceString);
-  find();//find and select next match
-
-  if(boxReplace->findText(replaceString) == -1)
-    boxReplace->addItem(replaceString);
-}
-
-/**
- * Replace all occurrences of the current search term with the replacement text
- */
-void FindReplaceDialog::replaceAll()
-{
-  QString searchString = boxFind->currentText();
-  if (searchString.isEmpty()){
-    QMessageBox::warning(this, tr("Empty Search Field"),
-			 tr("The search field is empty. Please enter some text and try again."));
-    boxFind->setFocus();
-    return;
-  }
-
-  if(boxFind->findText(searchString) == -1)
-  {
-    boxFind->addItem (searchString);
-  }
-
-  QString replaceString = boxReplace->currentText();
-  if(boxReplace->findText(replaceString) == -1)
-  {
-    boxReplace->addItem(replaceString);
-  }
-
-  ScriptEditor *editor =  m_manager->currentEditor();
-  int line(-1), index(-1), prevLine(-1), prevIndex(-1);
-  bool regex = boxRegex->isChecked();
-  bool cs = boxCaseSensitive->isChecked();
-  bool whole = boxWholeWords->isChecked();
-  bool wrap = boxWrapAround->isChecked();
-  bool backward = boxSearchBackwards->isChecked();
-  // Mark this as a set of actions that can be undone as one
-  editor->beginUndoAction();
-  bool found = editor->findFirst(searchString, regex, cs, whole, wrap, !backward, 0, 0);
-  // If find first fails then there is nothing to replace
-  if( !found )
-  {
-    QMessageBox::information(this, "MantidPlot - Find and Replace", "No matches found in current document.");
-  }
-
-  while( found )
-  {
-    editor->replace(replaceString);
-    editor->getCursorPosition(&prevLine, &prevIndex);
-    found = editor->findNext();
-    editor->getCursorPosition(&line, &index);
-    if( line < prevLine || ( line == prevLine && index <= prevIndex ) )
-    {
-      break;
-    }
-  }
-  editor->endUndoAction();
-}
-
-/**
- * Find button clicked slot
- */
-void FindReplaceDialog::findClicked()
-{
-  // Forward to worker function
-  find(boxSearchBackwards->isChecked());
-}
-
-/**
- * Flip the in-progress flag
- */
-void FindReplaceDialog::resetSearchFlag()
-{
-  if( ScriptEditor *editor = m_manager->currentEditor() )
-  {
-    m_find_inprogress = false;
-    editor->setSelection(-1, -1, -1, -1);
-  }
-}
+///**
+// * Constructor
+// */
+//FindReplaceDialog::FindReplaceDialog(ScriptManagerWidget *manager, bool replace, QWidget* parent, Qt::WFlags fl )
+//  : QDialog( parent, fl ), m_manager(manager), m_find_inprogress(false)
+//{
+//  setWindowTitle (tr("MantidPlot") + " - " + tr("Find"));
+//  setSizeGripEnabled( true );
+//
+//  QGroupBox *gb1 = new QGroupBox();
+//  QGridLayout *topLayout = new QGridLayout(gb1);
+//
+//  topLayout->addWidget( new QLabel(tr( "Find" )), 0, 0);
+//  boxFind = new QComboBox();
+//  boxFind->setEditable(true);
+//  boxFind->setDuplicatesEnabled(false);
+//  boxFind->setInsertPolicy( QComboBox::InsertAtTop );
+//  boxFind->setAutoCompletion(true);
+//  boxFind->setMaxCount ( 10 );
+//  boxFind->setMaxVisibleItems ( 10 );
+//  boxFind->setMinimumWidth(250);
+//  boxFind->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+//  connect(boxFind, SIGNAL(editTextChanged(const QString &)), this, SLOT(resetSearchFlag()));
+//
+//  ScriptEditor *editor = m_manager->currentEditor();
+//  if( editor->hasSelectedText() )
+//  {
+//    QString text = editor->selectedText();
+//    boxFind->setEditText(text);
+//    boxFind->addItem(text);
+//  }
+//
+//  topLayout->addWidget(boxFind, 0, 1);
+//
+//  if( replace )
+//  {
+//    setWindowTitle (tr("MantidPlot") + " - " + tr("Find and Replace"));
+//    topLayout->addWidget(new QLabel(tr( "Replace with" )), 1, 0);
+//    boxReplace = new QComboBox();
+//    boxReplace->setEditable(true);
+//    boxReplace->setDuplicatesEnabled(false);
+//    boxReplace->setInsertPolicy( QComboBox::InsertAtTop );
+//    boxReplace->setAutoCompletion(true);
+//    boxReplace->setMaxCount ( 10 );
+//    boxReplace->setMaxVisibleItems ( 10 );
+//    boxReplace->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+//    topLayout->addWidget( boxReplace, 1, 1);
+//    topLayout->setColumnStretch(1, 10);
+//  }
+//
+//  QGroupBox *gb2 = new QGroupBox();
+//  QGridLayout * bottomLayout = new QGridLayout(gb2);
+//  QButtonGroup *find_options = new QButtonGroup(this);
+//  find_options->setExclusive(false);
+//
+//  boxCaseSensitive = new QCheckBox(tr("&Match case"));
+//  boxCaseSensitive->setChecked(false);
+//  bottomLayout->addWidget( boxCaseSensitive, 0, 0);
+//  find_options->addButton(boxCaseSensitive);
+//
+//  boxWholeWords = new QCheckBox(tr("&Whole word"));
+//  boxWholeWords->setChecked(false);
+//  bottomLayout->addWidget(boxWholeWords, 1, 0);
+//  find_options->addButton(boxWholeWords);
+//
+//  boxRegex = new QCheckBox(tr("&Regular expression"));
+//  boxRegex->setChecked(false);
+//  bottomLayout->addWidget(boxRegex, 2, 0);
+//  find_options->addButton(boxRegex);
+//
+//  boxSearchBackwards = new QCheckBox(tr("&Search backwards"));
+//  boxSearchBackwards->setChecked(false);
+//  bottomLayout->addWidget(boxSearchBackwards, 0, 1);
+//  find_options->addButton(boxSearchBackwards);
+//
+//  boxWrapAround = new QCheckBox(tr("&Wrap around"));
+//  boxWrapAround->setChecked(true);
+//  bottomLayout->addWidget(boxWrapAround, 1, 1);
+//  find_options->addButton(boxWrapAround);
+//
+//  connect(find_options, SIGNAL(buttonClicked(int)), this, SLOT(resetSearchFlag()));
+//
+//  QVBoxLayout *vb1 = new QVBoxLayout();
+//  vb1->addWidget(gb1);
+//  vb1->addWidget(gb2);
+//
+//  QVBoxLayout *vb2 = new QVBoxLayout();
+//
+//  buttonNext = new QPushButton(tr("&Next"));
+//  buttonNext->setShortcut(tr("Ctrl+F"));
+//  buttonNext->setDefault(true);
+//  vb2->addWidget(buttonNext);
+//
+//  if( replace )
+//  {
+//    buttonReplace = new QPushButton(tr("&Replace"));
+//    connect(buttonReplace, SIGNAL(clicked()), this, SLOT(replace()));
+//    vb2->addWidget(buttonReplace);
+//
+//    buttonReplaceAll = new QPushButton(tr("Replace &all"));
+//    connect(buttonReplaceAll, SIGNAL(clicked()), this, SLOT(replaceAll()));
+//    vb2->addWidget(buttonReplaceAll);
+//  }
+//
+//  buttonCancel = new QPushButton(tr("&Close"));
+//  vb2->addWidget(buttonCancel);
+//  vb2->addStretch();
+//
+//  QHBoxLayout *hb = new QHBoxLayout(this);
+//  hb->addLayout(vb1);
+//  hb->addLayout(vb2);
+//
+//  connect(buttonNext, SIGNAL(clicked()), this, SLOT(findClicked()));
+//  connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
+//}
+//
+////------------------------------------------------------
+//// Protected slot member functions
+////------------------------------------------------------
+///**
+// * Find the current search term
+// * @param backwards :: If true then the search procedes backwards from the cursor's current position
+// * @returns A boolean indicating success/failure
+// */
+//bool FindReplaceDialog::find(bool backwards)
+//{
+//  QString searchString = boxFind->currentText();
+//  if (searchString.isEmpty()){
+//    QMessageBox::warning(this, tr("Empty Search Field"),
+//			 tr("The search field is empty. Please enter some text and try again."));
+//    boxFind->setFocus();
+//    return false;
+//  }
+//
+//  if(boxFind->findText(searchString) == -1)
+//  {
+//    boxFind->addItem(searchString);
+//  }
+//
+//  if( m_find_inprogress )
+//  {
+//    m_find_inprogress = m_manager->currentEditor()->findNext();
+//  }
+//  else
+//  {
+//    bool cs = boxCaseSensitive->isChecked();
+//    bool whole = boxWholeWords->isChecked();
+//    bool wrap = boxWrapAround->isChecked();
+//    bool regex = boxRegex->isChecked();
+//    m_find_inprogress = m_manager->currentEditor()->findFirst(searchString, regex, cs, whole, wrap, !backwards);
+//  }
+//  return m_find_inprogress;
+//}
+//
+///**
+// * Replace the next occurrence of the search term with the replacement text
+// */
+//void FindReplaceDialog::replace()
+//{
+//  QString searchString = boxFind->currentText();
+//  if (searchString.isEmpty()){
+//    QMessageBox::warning(this, tr("Empty Search Field"),
+//			 tr("The search field is empty. Please enter some text and try again."));
+//    boxFind->setFocus();
+//    return;
+//  }
+//
+//  if (!m_manager->currentEditor()->hasSelectedText() || m_manager->currentEditor()->selectedText() != searchString){
+//    find();//find and select next match
+//    return;
+//  }
+//
+//  QString replaceString = boxReplace->currentText();
+//  m_manager->currentEditor()->replace(replaceString);
+//  find();//find and select next match
+//
+//  if(boxReplace->findText(replaceString) == -1)
+//    boxReplace->addItem(replaceString);
+//}
+//
+///**
+// * Replace all occurrences of the current search term with the replacement text
+// */
+//void FindReplaceDialog::replaceAll()
+//{
+//  QString searchString = boxFind->currentText();
+//  if (searchString.isEmpty()){
+//    QMessageBox::warning(this, tr("Empty Search Field"),
+//			 tr("The search field is empty. Please enter some text and try again."));
+//    boxFind->setFocus();
+//    return;
+//  }
+//
+//  if(boxFind->findText(searchString) == -1)
+//  {
+//    boxFind->addItem (searchString);
+//  }
+//
+//  QString replaceString = boxReplace->currentText();
+//  if(boxReplace->findText(replaceString) == -1)
+//  {
+//    boxReplace->addItem(replaceString);
+//  }
+//
+//  ScriptEditor *editor =  m_manager->currentEditor();
+//  int line(-1), index(-1), prevLine(-1), prevIndex(-1);
+//  bool regex = boxRegex->isChecked();
+//  bool cs = boxCaseSensitive->isChecked();
+//  bool whole = boxWholeWords->isChecked();
+//  bool wrap = boxWrapAround->isChecked();
+//  bool backward = boxSearchBackwards->isChecked();
+//  // Mark this as a set of actions that can be undone as one
+//  editor->beginUndoAction();
+//  bool found = editor->findFirst(searchString, regex, cs, whole, wrap, !backward, 0, 0);
+//  // If find first fails then there is nothing to replace
+//  if( !found )
+//  {
+//    QMessageBox::information(this, "MantidPlot - Find and Replace", "No matches found in current document.");
+//  }
+//
+//  while( found )
+//  {
+//    editor->replace(replaceString);
+//    editor->getCursorPosition(&prevLine, &prevIndex);
+//    found = editor->findNext();
+//    editor->getCursorPosition(&line, &index);
+//    if( line < prevLine || ( line == prevLine && index <= prevIndex ) )
+//    {
+//      break;
+//    }
+//  }
+//  editor->endUndoAction();
+//}
+//
+///**
+// * Find button clicked slot
+// */
+//void FindReplaceDialog::findClicked()
+//{
+//  // Forward to worker function
+//  find(boxSearchBackwards->isChecked());
+//}
+//
+///**
+// * Flip the in-progress flag
+// */
+//void FindReplaceDialog::resetSearchFlag()
+//{
+//  if( ScriptEditor *editor = m_manager->currentEditor() )
+//  {
+//    m_find_inprogress = false;
+//    editor->setSelection(-1, -1, -1, -1);
+//  }
+//}
diff --git a/Code/Mantid/MantidPlot/src/ScriptManagerWidget.h b/Code/Mantid/MantidPlot/src/ScriptManagerWidget.h
index 6ba0f58745dddba1bb7f68889108c1103577f6a5..55f612d90c04ebce84e5b1e5559c1879cfe629ad 100644
--- a/Code/Mantid/MantidPlot/src/ScriptManagerWidget.h
+++ b/Code/Mantid/MantidPlot/src/ScriptManagerWidget.h
@@ -6,7 +6,6 @@
 //---------------------------------------------------------
 #include <QTabWidget>
 #include <QDialog>
-#include <QHash>
 #include "Scripted.h"
 
 //---------------------------------------------------------
@@ -14,19 +13,19 @@
 //--------------------------------------------------------
 class QTabWidget;
 class QPoint;
-class ScriptingWindow;
-class ScriptOutputDock;
-class ScriptEditor;
-class Script;
 class QAction;
 class QPushButton;
 class QCheckBox;
 class QComboBox;
+class ScriptFileInterpreter;
 
 class FindReplaceDialog;
 class QMenu;
 class QStringList;
 
+class ScriptingWindow;
+
+
 /** 
     This class manages ScriptEditor objects and displays them in a series
     of tabs. It is also the single point of entry for executing scripts
@@ -57,48 +56,38 @@ class QStringList;
 */
 class ScriptManagerWidget : public QTabWidget, Scripted
 {
-  /// Qt macro so that we can use the signal/slot 
   Q_OBJECT
 
 public:
   /// Constructor
-  ScriptManagerWidget(ScriptingEnv *env, QWidget *parent, bool interpreter_mode = false, bool capturePrint = true);
+  ScriptManagerWidget(ScriptingEnv *env, QWidget *parent);
   ///Destructor
   ~ScriptManagerWidget();
+
   ///Save settings applicable to the manager
-  void saveSettings();  
-  /// Ask if we should save
-  void askSave(int index);
-  /// Open a script from a file and read the file into a QString. 
-  /// QStrings are implicity shared so the return, seemingly by value, is not expensive
-  QString readScript(const QString& filename, bool *ok);
+  void saveSettings();
+
+  /// Current interpreter
+  ScriptFileInterpreter * currentInterpreter();
+  /// Interpreter at given index
+  ScriptFileInterpreter * interpreterAt(int index);
+
+  // ----------------------- Menus --------------------------------------------
+  /// Add the required entries for the file menu in this context
+  void populateFileMenu(QMenu &fileMenu);
+  /// Add the required entries for the edit menu in this context
+  void populateEditMenu(QMenu &editMenu);
+  /// Add the required entries for the execute menu in this context
+  void populateExecMenu(QMenu &execMenu);
+
   /// Is a script running in the environment
   bool isScriptRunning();
-  /// Return the current editor
-  ScriptEditor *currentEditor() const;
-  /// Return the current runner
-  Script * currentRunner() const;
-  /// Undo action for the current editor
-  QAction* undoAction() const;
-  /// Redo action for the current editor
-  QAction* redoAction() const;
-  /// Cut action for the current editor
-  QAction* cutAction() const;
-  /// Copy action for the current editor
-  QAction* copyAction() const;
-  /// Paste action for the current editor
-  QAction* pasteAction() const;
-  /// Print action for the current editor
-  QAction* printAction() const;
-  /// Zoom in action for the current editor
-  QAction* zoomInAction() const;
-  /// Zoom out action for the current editor
-  QAction* zoomOutAction() const;
- /// this method appens the file names of scripts
+
+ /// this method appends the file names of scripts
  ///in different tabs to a string and returns 
   QString saveToString();
   ///this method returns a list containing  recent scripts
-  QStringList recentScripts() ;
+  QStringList recentScripts();
   /// update the Recent Scripts menu items
   void updateRecentScriptList();
   ///set the recent script list
@@ -110,51 +99,40 @@ public:
 
 signals:
   ///A message is ready to be printed
-  void MessageToPrint(const QString & msg, bool error, bool timestamp = false);    
+  void MessageToPrint(const QString & msg, bool error, bool timestamp = false);
   ///A script has changed execution state
   void ScriptIsActive(bool running);
 
 public slots:
-  /// Create a new tab for script editing with the text within the file imported
-  ScriptEditor* newTab(int index = -1, const QString & filename = "");
+  /// Create a new tab for script editing with the text within the file imported and insert it at the index
+  void newTab(int index = -1, const QString & filename = "");
   /// Open a file in the current tab
   void openInCurrentTab(const QString & filename = QString());
   /// Open a file in a new tab
   void openInNewTab(const QString & filename = QString());
-  ///Save file to different file name
-  QString saveAs(int index = -1);
-  /// Save file
-  void save(int index = -1);
   /// Close all tabs
   void closeAllTabs();
   /// Show the find dialog
   void showFindDialog(bool replace = true);
 
-  /// comiple the code
+  /// compile the code
   void compile(const QString &);
 
   /** @name Execute members.*/
   //@{
   /// Execute
-  void execute();
-  ///Execute all
   void executeAll();
+  ///Execute all
+  void executeSelection();
   /// Evaluate
   void evaluate();
   ///Execute an interpreter line
   void executeInterpreter(const QString & code);
   //@}
-  ///Run script code
-  bool runScriptCode(const QString & code, const int line_offset = 0);
 
   /// run mutli line code
   bool runMultiLineCode(int line_offset);
 
-  ///Format an output message with an optional timestamp
-  void displayOutput(const QString & msg, bool timestamp = false);
-  ///Format an output message with an optional timestamp
-  void displayError(const QString & msg, bool timestamp = false);
-					
 private slots:
   /// Context menu handler
   void editorContextMenu(const QPoint & pos);
@@ -162,8 +140,10 @@ private slots:
   int closeCurrentTab();
   /// Close clicked tab
   void closeClickedTab();
-  /// Mark as changed
+  /// Mark the current tab
   void markCurrentAsChanged();
+  /// Current tab has changed
+  void tabSelectionChanged(int index);
   /// Enable/disable the relevant actions based on the execution state of the script
   void setScriptIsRunning(bool running);
   /// Toggle the progress reporting arrow
@@ -188,44 +168,36 @@ private:
   void customEvent(QEvent *event);
   ///Open a script
   void open(bool newtab, const QString & filename = QString());
-  /// Create a new Script object and connect up the relevant signals.
-  Script * createScriptRunner(ScriptEditor *editor);
   ///Close a tab with a given index
   void closeTabAtIndex(int index);
   ///Close a tab at a given position
   void closeTabAtPosition(const QPoint & pos);
-  ///Does the actual saving of a file
-  void doSave(ScriptEditor * editor);
-  ///Set auto complete behaviour for the given editor
-  void setCodeCompletionBehaviour(ScriptEditor *editor, bool state);
-  ///Set auto complete behaviour for the given editor
-  void setCallTipsBehaviour(ScriptEditor *editor, bool state);
-  ///Set auto complete behaviour for the given editor
-  void setCodeFoldingBehaviour(ScriptEditor *editor, bool state);
 
-  
+//  ///Set auto complete behaviour for the given editor
+//  void setCodeCompletionBehaviour(ScriptEditor *editor, bool state);
+//  ///Set auto complete behaviour for the given editor
+//  void setCallTipsBehaviour(ScriptEditor *editor, bool state);
+//  ///Set auto complete behaviour for the given editor
+//  void setCodeFoldingBehaviour(ScriptEditor *editor, bool state);
 
  private:
-  /// So that the window can access the actions that are relevant
   friend class ScriptingWindow;
-  friend class ScriptOutputDock;
 
-  /// The last directory visted with a file dialog
+  /// The last directory visited with a file dialog
   QString m_last_dir;
-  /// The script objects for each tab that will execute the code
-  QHash<ScriptEditor*, Script *> m_script_runners;
   // The cursor position within the tab bar when the right-mouse button was last clicked
   // I need this to ensure that the position of a call to tabBar()->tabAt() is accurate
   // as Qt doesn't provide an action signal parameterized on a position
   QPoint m_cursor_pos;
   /// The index of the last active tab 
   int m_last_active_tab;
+
   /// File actions
   QAction *m_new_tab, *m_open_curtab, *m_open_newtab, *m_save, *m_saveas, *m_close_tab;
+
   ///Edit actions that are necessary for the manager
   QAction *m_find;
-  /// Script execute actions
-  QAction *m_exec, *m_exec_all, *m_eval;
+
   ///Toggle progress
   QAction *m_toggle_progress;
   /// Toggle code folding
@@ -234,12 +206,10 @@ private:
   QAction *m_toggle_completion;
   /// Toggle code folding
   QAction *m_toggle_calltips;
+
   /// Recent scripts option
   QMenu* m_recent_scripts;
 
-  /// The find replace dialog
-  FindReplaceDialog *m_findrep_dlg;
-
   ///Display mode boolean
   bool m_interpreter_mode;
   ///list storing the recent scripts
@@ -257,66 +227,66 @@ private:
    This class raises a dialog to find and optionally replace text within in a text edit. 
    Note: It came from the main qtiplot repository at r1341 and it has been modified to
    work with our script window (also added comments). Since it's keyed to work only with Script editing
-   classes, it's definition may aswell just go here
+   classes, it's definition may as well just go here
  */
-class FindReplaceDialog : public QDialog
-{
-  // Qt macro
-  Q_OBJECT
-
-public:
-  ///Constructor
-  FindReplaceDialog(ScriptManagerWidget *manager, bool replace = false, 
-		    QWidget* parent = 0, Qt::WindowFlags fl = 0 );
-
-public slots:
-  /// An option has been toggled or the manager has some update that is necessary
-  void resetSearchFlag();
-
-protected slots:
-  /// Find 
-  bool find(bool backwards = false);
-  /// Replace slot
-  void replace();
-  /// Replace all slot
-  void replaceAll();
-
-private slots:
-  /// A slot for the findClicked button
-  void findClicked();
-
-private:
-  ///The current text editor we are working on
-  ScriptManagerWidget *m_manager;
-  
-  ///Find next match button
-  QPushButton* buttonNext;
-  /// Replace text button
-  QPushButton* buttonReplace;
-  /// Replace all text button
-  QPushButton* buttonReplaceAll;
-  /// Cancel dialog button
-  QPushButton* buttonCancel;
-  
-  /// Find box
-  QComboBox* boxFind;
-  /// Replace box
-  QComboBox* boxReplace;
-  
-  /// Case-sensitive check box
-  QCheckBox *boxCaseSensitive;
-  /// Whole words check box
-  QCheckBox *boxWholeWords;
-  /// Search backwards
-  QCheckBox *boxSearchBackwards;
-  /// Wrap around
-  QCheckBox *boxWrapAround;
-  /// Treat as regular expressions
-  QCheckBox *boxRegex;
-
-  /// If a find is in progress
-  bool m_find_inprogress;
-};
+//class FindReplaceDialog : public QDialog
+//{
+//  // Qt macro
+//  Q_OBJECT
+//
+//public:
+//  ///Constructor
+//  FindReplaceDialog(ScriptManagerWidget *manager, bool replace = false,
+//		    QWidget* parent = 0, Qt::WindowFlags fl = 0 );
+//
+//public slots:
+//  /// An option has been toggled or the manager has some update that is necessary
+//  void resetSearchFlag();
+//
+//protected slots:
+//  /// Find
+//  bool find(bool backwards = false);
+//  /// Replace slot
+//  void replace();
+//  /// Replace all slot
+//  void replaceAll();
+//
+//private slots:
+//  /// A slot for the findClicked button
+//  void findClicked();
+//
+//private:
+//  ///The current text editor we are working on
+//  ScriptManagerWidget *m_manager;
+//
+//  ///Find next match button
+//  QPushButton* buttonNext;
+//  /// Replace text button
+//  QPushButton* buttonReplace;
+//  /// Replace all text button
+//  QPushButton* buttonReplaceAll;
+//  /// Cancel dialog button
+//  QPushButton* buttonCancel;
+//
+//  /// Find box
+//  QComboBox* boxFind;
+//  /// Replace box
+//  QComboBox* boxReplace;
+//
+//  /// Case-sensitive check box
+//  QCheckBox *boxCaseSensitive;
+//  /// Whole words check box
+//  QCheckBox *boxWholeWords;
+//  /// Search backwards
+//  QCheckBox *boxSearchBackwards;
+//  /// Wrap around
+//  QCheckBox *boxWrapAround;
+//  /// Treat as regular expressions
+//  QCheckBox *boxRegex;
+//
+//  /// If a find is in progress
+//  bool m_find_inprogress;
+//};
 
 
 #endif
diff --git a/Code/Mantid/MantidPlot/src/ScriptOutputDisplay.cpp b/Code/Mantid/MantidPlot/src/ScriptOutputDisplay.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2373e29f6528ee40bcdfebefdde0b8b49f186ce4
--- /dev/null
+++ b/Code/Mantid/MantidPlot/src/ScriptOutputDisplay.cpp
@@ -0,0 +1,243 @@
+#include "ScriptOutputDisplay.h"
+#include "TextFileIO.h"
+
+#include "pixmaps.h"
+
+#include <QDateTime>
+#include <QMenu>
+#include <QFileDialog>
+#include <QPrinter>
+#include <QPrintDialog>
+#include <QMessageBox>
+#include <QTextStream>
+#include <QApplication>
+
+/**
+ * Constructor
+ * @param title :: The title
+ * @param parent :: The parent widget
+ * @param flags :: Window flags
+ */
+ScriptOutputDisplay::ScriptOutputDisplay(QWidget * parent) :
+  QTextEdit(parent), m_copy(NULL), m_clear(NULL), m_save(NULL)
+{
+  setReadOnly(true);
+  setLineWrapMode(QTextEdit::FixedColumnWidth);
+  setLineWrapColumnOrWidth(105);
+  setAutoFormatting(QTextEdit::AutoNone);
+  // Change to fix width font so that table formatting isn't screwed up
+  resetFont();
+
+  setContextMenuPolicy(Qt::CustomContextMenu);
+  connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this,
+    SLOT(showContextMenu(const QPoint&)));
+
+  initActions();
+}
+
+/**
+ * Is there anything here
+ */
+bool ScriptOutputDisplay::isEmpty() const
+{
+  return document()->isEmpty();
+}
+
+/**
+ * Populate a menu with editing actions
+ * @param editMenu A new menu
+ */
+void ScriptOutputDisplay::populateEditMenu(QMenu &editMenu)
+{
+  editMenu.addAction(m_clear);
+}
+
+/**
+ * Clear the text area
+ */
+void ScriptOutputDisplay::clear()
+{
+  clear();
+}
+
+/**
+ * Change the title based on the script's execution state
+ * @param running :: The current state of the script environment
+ */
+void ScriptOutputDisplay::setScriptIsRunning(bool running)
+{
+//  QString title("Script Output - Status: ");
+//  if( running )
+//  {
+//    title += "Running ...";
+//  }
+//  else
+//  {
+//    title += "Stopped";
+//  }
+//  setWindowTitle(title);
+}
+
+/**
+ *  Display an output message that is not an error
+ *  @param msg :: The string message
+ */
+void ScriptOutputDisplay::displayMessage(const QString & msg)
+{
+  prepareForNewMessage(ScriptOutputDisplay::Standard);
+  appendText(msg);
+}
+
+/**
+ *  Display an output message with a timestamp & border
+ *  @param msg :: The string message
+ */
+void ScriptOutputDisplay::displayMessageWithTimestamp(const QString & msg)
+{
+  prepareForNewMessage(ScriptOutputDisplay::Standard);
+  QString timestamped = addTimestamp(msg);
+  appendText(timestamped);
+}
+
+/**
+ *  Display an error message
+ *  @param msg :: The string message
+ */
+void ScriptOutputDisplay::displayError(const QString & msg)
+{
+  prepareForNewMessage(ScriptOutputDisplay::Error);
+  appendText(msg);
+}
+
+
+//-------------------------------------------
+// Private slot member functions
+//-------------------------------------------
+/**
+ * Display a context menu
+ */
+void ScriptOutputDisplay::showContextMenu(const QPoint & pos)
+{
+  QMenu menu(this);
+  menu.addAction(m_clear);
+  menu.addAction(m_copy);
+  menu.addAction(m_save);
+
+  if( !isEmpty() )
+  {
+    QAction* print = new QAction(getQPixmap("fileprint_xpm"), "&Print", this);
+    connect(print, SIGNAL(activated()), this, SLOT(print()));
+    menu.addAction(print);
+  }
+
+  menu.exec(mapToGlobal(pos));
+}
+
+/**
+ * Print the window output
+ */
+void ScriptOutputDisplay::print()
+{
+  QPrinter printer;
+  QPrintDialog *print_dlg = new QPrintDialog(&printer, this);
+  print_dlg->setWindowTitle(tr("Print Output"));
+  if (print_dlg->exec() != QDialog::Accepted)
+    return;
+  QTextDocument document(text());
+  document.print(&printer);
+}
+
+/**
+ * Save script output to a file
+ * @param filename :: The file name to save the output, if empty (default) then a dialog is raised
+ */
+void ScriptOutputDisplay::saveToFile(const QString & filename)
+{
+  QStringList filters;
+  filters.append(tr("Text") + " (*.txt *.TXT)");
+  filters.append(tr("All Files") + " (*)");
+  TextFileIO fileIO(filters);
+  fileIO.save(this->toPlainText(), filename);
+}
+
+//-------------------------------------------
+// Private non-slot member functions
+//-------------------------------------------
+/**
+ * Prepares the display for the next message
+ * @param msgType :: One of the predefined message types
+ */
+void ScriptOutputDisplay::prepareForNewMessage(const MessageType msgType)
+{
+  if(msgType == ScriptOutputDisplay::Error)
+  {
+    setTextColor(Qt::red);
+  }
+  else
+  {
+    setTextColor(Qt::black);
+  }
+  // Ensure the cursor is in the correct position. This affects the font unfortunately
+  moveCursor(QTextCursor::End);
+  resetFont();
+}
+
+/**
+ * Adds a border & timestamp to the message
+ * @param msg
+ * @return A new string with the required formatting
+ */
+QString ScriptOutputDisplay::addTimestamp(const QString & msg)
+{
+  QString separator(75, '-');
+  QString timestamped =
+      "%1\n"
+      "%2: %3\n"
+      "%4\n";
+  timestamped = timestamped.arg(separator, QDateTime::currentDateTime().toString(),
+                                msg.trimmed(), separator);
+  return timestamped;
+}
+
+/**
+ * Append new text
+ * @param txt :: The text to append
+ */
+void ScriptOutputDisplay::appendText(const QString & txt)
+{
+  textCursor().insertText(txt);
+  moveCursor(QTextCursor::End);
+}
+
+/**
+ * Create the actions associated with this widget
+ */
+void ScriptOutputDisplay::initActions()
+{
+  // Copy action
+  m_copy = new QAction(getQPixmap("copy_xpm"), "Copy", this);
+  m_copy->setShortcut(tr("Ctrl+C"));
+  connect(m_copy, SIGNAL(activated()), this, SLOT(copy()));
+
+  // Clear action
+  m_clear = new QAction("Clear Output", this);
+  connect(m_clear, SIGNAL(activated()), this, SLOT(clear()));
+
+  // Save  action
+  m_save = new QAction("Save Output", this);
+  connect(m_save, SIGNAL(activated()), this, SLOT(saveToFile()));
+}
+
+/**
+ * Rest the font to default
+ */
+void ScriptOutputDisplay::resetFont()
+{
+  QFont f("Andale Mono");
+  f.setFixedPitch(true);
+  f.setPointSize(8);
+  setCurrentFont(f);
+  setMinimumWidth(5);
+  setMinimumHeight(5);
+}
+
diff --git a/Code/Mantid/MantidPlot/src/ScriptOutputDisplay.h b/Code/Mantid/MantidPlot/src/ScriptOutputDisplay.h
new file mode 100644
index 0000000000000000000000000000000000000000..5b2d4c8923cc416d8de44e8d836d0d68e9d850a7
--- /dev/null
+++ b/Code/Mantid/MantidPlot/src/ScriptOutputDisplay.h
@@ -0,0 +1,66 @@
+#ifndef SCRIPTOUTPUTDISPLAY_H_
+#define SCRIPTOUTPUTDISPLAY_H_
+
+#include <QTextEdit>
+
+/**
+ * Defines a read-only text area that can be used
+ * to output messages
+ */
+class ScriptOutputDisplay : public QTextEdit
+{
+  Q_OBJECT
+
+public:
+  /// Constructor
+  ScriptOutputDisplay(QWidget *parent = NULL);
+
+  /// Is there anything here
+  bool isEmpty() const;
+
+  /// Add actions applicable to an edit menu
+  void populateEditMenu(QMenu &editMenu);
+
+public slots:
+  /// Clear the text
+  void clear();
+  /// Print the text within the window
+  void print();
+  /// Save the output to a file
+  void saveToFile(const QString & filename = "");
+  /// Change the title based on the script's execution state
+  void setScriptIsRunning(bool running);
+  /// Display an output message that is not an error
+  void displayMessage(const QString & msg);
+  /// Disply an output message with a timestamp & border
+  void displayMessageWithTimestamp(const QString & msg);
+  /// Display an error message
+  void displayError(const QString & msg);
+
+private slots:
+  /// Context menu slot
+  void showContextMenu(const QPoint & pos);
+
+private:
+  enum MessageType { Standard, Error };
+  /// Setup the cursor for a new message
+  void prepareForNewMessage(const MessageType msgType);
+  /// Add the timestamp formatting
+  QString addTimestamp(const QString &);
+  /// Append new text
+  void appendText(const QString & txt);
+  /// Create the action pointers
+  void initActions();
+  /// Reset the default font
+  void resetFont();
+
+private:
+  /// Copy action
+  QAction *m_copy;
+  /// Clear action
+  QAction *m_clear;
+  /// Save action
+  QAction *m_save;
+};
+
+#endif /* SCRIPTOUTPUTDISPLAY_H_ */
diff --git a/Code/Mantid/MantidPlot/src/Scripted.cpp b/Code/Mantid/MantidPlot/src/Scripted.cpp
index 01e17c32038acf7b6e9751c8244f5480a66a0261..f1068bb48f7bc1a75e53cd21650547a0ea8226e9 100644
--- a/Code/Mantid/MantidPlot/src/Scripted.cpp
+++ b/Code/Mantid/MantidPlot/src/Scripted.cpp
@@ -8,10 +8,9 @@
  * Constructor
  * @param env :: A pointer to a scripting environment
  */
-Scripted::Scripted(ScriptingEnv *env)
+Scripted::Scripted(ScriptingEnv *env) :  m_scriptEnv(env)
 {
-  env->incref();
-  m_scriptEnv = env;
+  m_scriptEnv->incref();
 }
 
 /**
diff --git a/Code/Mantid/MantidPlot/src/Scripted.h b/Code/Mantid/MantidPlot/src/Scripted.h
index 383d94fc6e0d3cb7de6e9dcc9ad9b76e8c51ed33..89e2c450d73c4b7f4c50b469bd98f171b00fb8c0 100644
--- a/Code/Mantid/MantidPlot/src/Scripted.h
+++ b/Code/Mantid/MantidPlot/src/Scripted.h
@@ -36,15 +36,16 @@ class Scripted
 {
   public:
   /// Constructor
-  Scripted(ScriptingEnv* env);
+  explicit Scripted(ScriptingEnv* env);
   /// Destructor
   ~Scripted();
-  /// Called when the scripting environent changes
+  /// Called when the scripting environment changes
   void scriptingChangeEvent(ScriptingChangeEvent*);
   /// Access the current environment
   ScriptingEnv *scriptingEnv(){return m_scriptEnv;}
   
   private:
+  Scripted();
   /// A pointer to the current environment
   ScriptingEnv *m_scriptEnv;
 };
diff --git a/Code/Mantid/MantidPlot/src/ScriptingEnv.cpp b/Code/Mantid/MantidPlot/src/ScriptingEnv.cpp
index 268391f819184c2f8f049d5e3ff634a2b14c0caf..c6407ea236e9b7d7a72c460b9c89c10b5061614e 100644
--- a/Code/Mantid/MantidPlot/src/ScriptingEnv.cpp
+++ b/Code/Mantid/MantidPlot/src/ScriptingEnv.cpp
@@ -41,16 +41,16 @@
 #include "ScriptingEnv.h"
 #include "Script.h"
 
-#include <string.h>
+#include <cstring>
 
 #include <QDir>
 #include <QDateTime>
 #include "MantidKernel/ConfigService.h"
 
 
-ScriptingEnv::ScriptingEnv(ApplicationWindow *parent, const char *langName)
+ScriptingEnv::ScriptingEnv(ApplicationWindow *parent, const QString & langName)
   : QObject(0, langName), d_initialized(false), d_parent(parent), m_is_running(false), d_refcount(0),
-    languageName(langName) 
+    m_languageName(langName)
 {
 }
 
@@ -69,9 +69,9 @@ bool ScriptingEnv::initialize()
   return isInitialized();
 }
 
-const QString ScriptingEnv::scriptingLanguage() const
+const QString ScriptingEnv::languageName() const
 {
-  return QString(languageName);
+  return m_languageName;
 }
 
 const QString ScriptingEnv::fileFilter() const
@@ -103,12 +103,8 @@ void ScriptingEnv::decref()
  */
 ScriptingLangManager::ScriptingLang ScriptingLangManager::g_langs[] = 
   {
-#ifdef SCRIPTING_MUPARSER
-    { muParserScripting::langName, muParserScripting::constructor },
-#endif
-#ifdef SCRIPTING_PYTHON
-    { PythonScripting::langName, PythonScripting::constructor },
-#endif
+    { "muParser", muParserScripting::constructor },
+    { "Python", PythonScripting::constructor },
     // Sentinel defining the end of the list
     { NULL, NULL }
 };
@@ -125,11 +121,11 @@ ScriptingEnv *ScriptingLangManager::newEnv(ApplicationWindow *parent)
   }
 }
 
-ScriptingEnv *ScriptingLangManager::newEnv(const char *name, ApplicationWindow *parent)
+ScriptingEnv *ScriptingLangManager::newEnv(const QString & name, ApplicationWindow *parent)
 {
   for(ScriptingLang *l = g_langs; l->constructor; l++)
-  {	
-    if( QString(name) == QString(l->name) )
+  {
+    if( name == QString(l->name) )
     {
       return l->constructor(parent);
     }
diff --git a/Code/Mantid/MantidPlot/src/ScriptingEnv.h b/Code/Mantid/MantidPlot/src/ScriptingEnv.h
index 48258085b20bfa6779c347bae2f323c2e3f34117..41ae81b700a6f445e078c07e4297adc1da5832b2 100644
--- a/Code/Mantid/MantidPlot/src/ScriptingEnv.h
+++ b/Code/Mantid/MantidPlot/src/ScriptingEnv.h
@@ -31,23 +31,21 @@
 #ifndef SCRIPTINGENV_H
 #define SCRIPTINGENV_H
 
+#include "Script.h"
+
 #include <QVariant>
-#include <QString>
 #include <QStringList>
 #include <QObject>
-#include <QStringList>
 #include <QEvent>
 
 #include "customevents.h"
 
 class ApplicationWindow;
-class Script;
 class QsciLexer;
 
 /**
- * A ScriptingEnv object represents a running interpreter, possibly with global
- * variables, and is responsible for generating Script objects that perform
- * the actual evaluation of code.
+ * A ScriptingEnv object represents a running interpreter. It can create
+ * script objects that execute arbitrary strings of code.
  */
 class ScriptingEnv : public QObject
 {
@@ -55,7 +53,7 @@ class ScriptingEnv : public QObject
 
   public:
   ///Constructor
-  ScriptingEnv(ApplicationWindow *parent, const char *langName);
+  ScriptingEnv(ApplicationWindow *parent, const QString & langName);
   /// Destructor
   ~ScriptingEnv();
   /// Initialize the environment
@@ -66,18 +64,10 @@ class ScriptingEnv : public QObject
   virtual bool isRunning() const { return m_is_running; }
   /// Set that a script is being executed
   void setIsRunning(bool running) { m_is_running = running; }
+
   /// Create a script object that is responsible for executing actual code
-  virtual Script *newScript(const QString& code = "", QObject* context = NULL, 
-			    const QString &name="<input>", bool interactive = true,
-			    bool reportProgress = false)
-  {
-    Q_UNUSED(code);
-    Q_UNUSED(context);
-    Q_UNUSED(name);
-    Q_UNUSED(interactive);
-    Q_UNUSED(reportProgress);
-    return NULL;
-  }
+  virtual Script *newScript(const QString &name, QObject * context, const Script::InteractionType interact) const = 0;
+
   //! If an exception / error occured, return a nicely formated stack backtrace.
   virtual QString stackTraceString() { return QString::null; }
   /// Return a list of supported mathematical functions. These should be imported into the global namespace.
@@ -89,7 +79,7 @@ class ScriptingEnv : public QObject
   /// Construct a filter expression from fileExtension(), suitable for QFileDialog.
   const QString fileFilter() const;
   /// Return the name of the scripting language supported by this environment
-  const QString scriptingLanguage() const;
+  const QString languageName() const;
   /// If the environment supports evaluation as well as execution then override and return true
   virtual bool supportsEvaluation() { return false; }
   ///  Is progress reporting supported
@@ -138,11 +128,8 @@ private:
   virtual void shutdown() {}
 
 private:
-  /// the reference counter
   int d_refcount;
-  ///Mantid - Store the language name of the concrete implementation so that
-  /// the script window title can be set appropriately
-  const char * languageName;
+  QString m_languageName;
 };
 
 /**
@@ -154,7 +141,7 @@ public:
   /// Return an instance of the first implementation we can find.
   static ScriptingEnv *newEnv(ApplicationWindow *parent);
   /// Return an instance of the implementation specified by name, NULL on failure.
-  static ScriptingEnv *newEnv(const char *name, ApplicationWindow *parent);
+  static ScriptingEnv *newEnv(const QString &name, ApplicationWindow *parent);
   /// Return the names of available implementations.
   static QStringList languages();
   /// Return the number of available implementations.
diff --git a/Code/Mantid/MantidPlot/src/ScriptingWindow.cpp b/Code/Mantid/MantidPlot/src/ScriptingWindow.cpp
index 3fec164e2f09a2e467913004fbd53df51d8c1ac0..e3b67b7ace258e6bc4b8ebb25db16fb32a233718 100755
--- a/Code/Mantid/MantidPlot/src/ScriptingWindow.cpp
+++ b/Code/Mantid/MantidPlot/src/ScriptingWindow.cpp
@@ -23,231 +23,6 @@
 #include <QApplication>
 #include <QTextStream>
 
-//***************************************************************************
-//
-// ScriptOutputDock class
-//
-//***************************************************************************
-/**
- * Constructor 
- * @param title :: The title
- * @param parent :: The parent widget
- * @param flags :: Window flags
- */
-ScriptOutputDock::ScriptOutputDock(const QString & title, ScriptManagerWidget* manager, 
-				   QWidget * parent, Qt::WindowFlags flags ) : 
-  QDockWidget(title, parent, flags), m_manager(manager)
-{
-  setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable);
-  
-  // The text display
-  m_text_display = new QTextEdit(this);
-  m_text_display->setReadOnly(true);
-  m_text_display->setLineWrapMode(QTextEdit::FixedColumnWidth);
-  m_text_display->setLineWrapColumnOrWidth(105);
-  m_text_display->setAutoFormatting(QTextEdit::AutoNone);
-  // Change to fix width font so that table formatting isn't screwed up
-  resetFont();
-  
-  m_text_display->setContextMenuPolicy(Qt::CustomContextMenu);
-  connect(m_text_display, SIGNAL(customContextMenuRequested(const QPoint&)), this, 
-	  SLOT(showContextMenu(const QPoint&)));
-
-  initActions();
-
-  setWidget(m_text_display);
-}
-
-/**
- * Is there anything here
- */
-bool ScriptOutputDock::isEmpty() const
-{
-  return m_text_display->document()->isEmpty();
-}
-
-/**
- * Clear the text area
- */
-void ScriptOutputDock::clear()
-{
-  m_text_display->clear();
-}
-
-/**
- * Change the title based on the script's execution state
- * @param running :: The current state of the script environment
- */
-void ScriptOutputDock::setScriptIsRunning(bool running)
-{
-  QString title("Script Output - Status: ");
-  if( running )
-  {
-    title += "Running ...";
-  }
-  else
-  {
-    title += "Stopped";
-  }
-  setWindowTitle(title);
-}
-
-//-------------------------------------------
-// Private slot member functions
-//-------------------------------------------
-/**
- * Display an output message in the output dock
- * @param msg :: The msg
- * @param error :: Indicate that this is an error
- * @param timestamp :: Indicates if the message has a timestamp attached to it. In this case the 
- * message will appear on a new line regardless of the last cursor position
- */
-void ScriptOutputDock::displayOutputMessage(const QString &msg, bool error, bool timestamp)
-{
-  // Ensure the cursor is in the correct position. This affects the font unfortunately
-  m_text_display->moveCursor(QTextCursor::End);
-  resetFont();
-
-  if( error )
-  {
-    m_text_display->setTextColor(Qt::red);
-  }
-  else
-  {
-    m_text_display->setTextColor(Qt::black);
-  }
-  QString msg_to_print = msg;
-
-  if( error || timestamp )
-  {
-    if( timestamp )
-    {
-      QString separator(75, '-'); 
-      msg_to_print  = separator + "\n" + QDateTime::currentDateTime().toString() 
-	+ ": " + msg.trimmed() + "\n" + separator + '\n';
-    }
-
-    // Check for last character being a new line character unless we are at the start of the 
-    // scroll area
-    if( !m_text_display->text().endsWith('\n') && m_text_display->textCursor().position() != 0 )
-    {
-      m_text_display->textCursor().insertText("\n");    
-    }
-  }
-
-  m_text_display->textCursor().insertText(msg_to_print);    
-  m_text_display->moveCursor(QTextCursor::End);
-}
-
-/**
- * Display a context menu
- */
-void ScriptOutputDock::showContextMenu(const QPoint & pos)
-{
-  QMenu menu(this);
-  
-  QAction* clear = new QAction("Clear", this);
-  connect(clear, SIGNAL(activated()), this, SLOT(clear()));
-  menu.addAction(clear);
-
-  //Copy action
-  menu.addAction(m_copy);
-
-  //Save to file
-  QAction* save_to_file = new QAction("Save to file", this);
-  connect(save_to_file, SIGNAL(activated()), this, SLOT(saveToFile()));
-  menu.addAction(save_to_file);
-
-  if( !m_text_display->document()->isEmpty() )
-  {
-    QAction* print = new QAction(getQPixmap("fileprint_xpm"), "&Print", this);
-    connect(print, SIGNAL(activated()), this, SLOT(print()));
-    menu.addAction(print);
-  }
-  
-  menu.exec(m_text_display->mapToGlobal(pos));
-}
-
-/**
- * Print the window output
- */
-void ScriptOutputDock::print()
-{
-  QPrinter printer;
-  QPrintDialog *print_dlg = new QPrintDialog(&printer, this);
-  print_dlg->setWindowTitle(tr("Print Output"));
-  if (print_dlg->exec() != QDialog::Accepted)
-    return;
-  QTextDocument document(m_text_display->text());
-  document.print(&printer);
-}
-
-/**
- * Save script output to a file
- */
-void ScriptOutputDock::saveToFile()
-{
-  QString filter = tr("Text") + " (*.txt *.TXT);;";
-  filter += tr("All Files")+" (*)";
-  QString selected_filter;
-  QString filename = QFileDialog::getSaveFileName(this, tr("MantidPlot - Save script"), 
-						  m_manager->m_last_dir, filter, &selected_filter);
-  if( filename.isEmpty() ) return;
-
-  if( QFileInfo(filename).suffix().isEmpty() )
-  {
-    QString ext = selected_filter.section('(',1).section(' ', 0, 0);
-    ext.remove(0,1);
-    if( ext != ")" ) filename += ext;
-  }
-
-  QFile file(filename);
-  if( !file.open(QIODevice::WriteOnly) )
-  {
-    QMessageBox::critical(this, tr("MantidPlot - File error"), 
-			  tr("Could not open file \"%1\" for writing.").arg(filename));
-    return;
-  }
-
-  QTextStream writer(&file);
-  QApplication::setOverrideCursor(Qt::WaitCursor);
-  writer << m_text_display->toPlainText();
-  QApplication::restoreOverrideCursor();
-  file.close();
-}
-
-//-------------------------------------------
-// Private non-slot member functions
-//-------------------------------------------
-/**
- * Create the actions associated with this widget
- */
-void ScriptOutputDock::initActions()
-{
-  // Copy action
-  m_copy = new QAction(getQPixmap("copy_xpm"), "Copy", this);
-  m_copy->setShortcut(tr("Ctrl+C"));
-  connect(m_copy, SIGNAL(activated()), m_text_display, SLOT(copy()));
-}
-
-/**
- * Rest the font to default
- */
-void ScriptOutputDock::resetFont()
-{
-  QFont f("Andale Mono");
-  f.setFixedPitch(true);
-  f.setPointSize(8);
-  m_text_display->setCurrentFont(f);
-  m_text_display->setMinimumWidth(5);
-  m_text_display->setMinimumHeight(5);
-}
-
-//***************************************************************************
-//
-// ScriptingWindow class
-//
-//***************************************************************************
 //-------------------------------------------
 // Public member functions
 //-------------------------------------------
@@ -260,22 +35,11 @@ void ScriptOutputDock::resetFont()
 ScriptingWindow::ScriptingWindow(ScriptingEnv *env, bool capturePrint, QWidget *parent, Qt::WindowFlags flags) :
   QMainWindow(parent, flags), m_acceptClose(false)
 {
+  Q_UNUSED(capturePrint);
   setObjectName("MantidScriptWindow");
   // Sub-widgets
-  const bool interpreterMode(false);
-  m_manager = new ScriptManagerWidget(env, this, interpreterMode, capturePrint);
+  m_manager = new ScriptManagerWidget(env, this);
   setCentralWidget(m_manager);
-  m_output_dock = new ScriptOutputDock(QString(), m_manager, this);
-  m_output_dock->setScriptIsRunning(false);
-  //Set the height to 10% of the height of the window
-  addDockWidget(Qt::BottomDockWidgetArea, m_output_dock);
-  int dock_width = m_output_dock->geometry().width();
-  m_output_dock->resize(dock_width, int(this->geometry().height() * 0.01));
-  
-  connect(m_manager, SIGNAL(MessageToPrint(const QString&,bool,bool)), m_output_dock, 
-	  SLOT(displayOutputMessage(const QString&, bool,bool)));
-  connect(m_manager, SIGNAL(ScriptIsActive(bool)), m_output_dock, SLOT(setScriptIsRunning(bool)));
-
 
   QSettings settings;
   settings.beginGroup("/ScriptWindow");
@@ -300,17 +64,13 @@ ScriptingWindow::ScriptingWindow(ScriptingEnv *env, bool capturePrint, QWidget *
 
   // Create menus and actions
   initMenus();
-  fileAboutToShow();
-  editAboutToShow();
-  windowAboutToShow();
 
   // This connection must occur after the objects have been created and initialized
   connect(m_manager, SIGNAL(currentChanged(int)), this, SLOT(tabSelectionChanged()));
 
   setWindowIcon(QIcon(":/MantidPlot_Icon_32offset.png"));
-  setWindowTitle("MantidPlot: " + env->scriptingLanguage() + " Window");
+  setWindowTitle("MantidPlot: " + env->languageName() + " Window");
 
-  setFocusPolicy(Qt::StrongFocus);
   setFocusProxy(m_manager);
 }
 
@@ -320,7 +80,6 @@ ScriptingWindow::ScriptingWindow(ScriptingEnv *env, bool capturePrint, QWidget *
 ScriptingWindow::~ScriptingWindow()
 {
   delete m_manager;
-  delete m_output_dock;
 }
 
 /**
@@ -409,113 +168,62 @@ void ScriptingWindow::customEvent(QEvent *event)
   if( !m_manager->isScriptRunning() && event->type() == SCRIPTING_CHANGE_EVENT )
   {
     ScriptingChangeEvent *sce = static_cast<ScriptingChangeEvent*>(event);
-    setWindowTitle("MantidPlot: " + sce->scriptingEnv()->scriptingLanguage() + " Window");
+    setWindowTitle("MantidPlot: " + sce->scriptingEnv()->languageName() + " Window");
   }
 }
 
 /**
  * Construct the file menu
  */
-void ScriptingWindow::fileAboutToShow()
+void ScriptingWindow::fileMenuAboutToShow()
 {
   m_file_menu->clear();
-
-  // New tab
-  m_file_menu->addAction(m_manager->m_new_tab);
-  // Open a file in current tab
-  m_file_menu->addAction(m_manager->m_open_curtab);
-  //Open in new tab
-  m_file_menu->addAction(m_manager->m_open_newtab);
-
-  // Save a script
-  m_file_menu->insertSeparator();
-  m_file_menu->addAction(m_manager->m_save);
-  // Save a script under a new file name
-  m_file_menu->addAction(m_manager->m_saveas);
-
-  //Print
-  if( m_manager->count() > 0 )
-  {
-    m_file_menu->addAction(m_manager->printAction());
-  }
-  if( !m_output_dock->isEmpty() )
-  {
-    m_file_menu->addAction(m_print_output);
-  }
-
-  // Scripting language
-  //m_file_menu->insertSeparator();
-  //m_file_menu->addAction(m_scripting_lang);
-
-  m_file_menu->insertSeparator();
-  m_file_menu->addMenu(m_manager->m_recent_scripts);
-  m_manager->updateRecentScriptList();
-
-  // Close current tab
-  m_file_menu->insertSeparator();
-  m_file_menu->addAction(m_manager->m_close_tab);
-
+  m_manager->populateFileMenu(*m_file_menu);
 }
 
 /**
  * Construct the edit menu
  */
-void ScriptingWindow::editAboutToShow()
+void ScriptingWindow::editMenuAboutToShow()
 {
   m_edit_menu->clear();
+  m_manager->populateEditMenu(*m_edit_menu);
+}
 
-  if( m_manager->count() > 0 )
-  {
-    // Undo
-    m_edit_menu->addAction(m_manager->undoAction());
-    //Redo 
-    m_edit_menu->addAction(m_manager->redoAction());
-    //Cut
-    m_edit_menu->addAction(m_manager->cutAction());
-    //Copy
-    m_edit_menu->addAction(m_manager->copyAction());
-    //Paste
-    m_edit_menu->addAction(m_manager->pasteAction());
-
-    //Find and replace
-    m_edit_menu->insertSeparator();
-    m_edit_menu->addAction(m_manager->m_find);
-    m_edit_menu->insertSeparator();
-  
-  }
-  //Clear output
-  m_edit_menu->addAction(m_clear_output);  
+/**
+ * Construct the exec menu for the current context
+ */
+void ScriptingWindow::execMenuAboutToShow()
+{
+  m_run_menu->clear();
+  m_manager->populateExecMenu(*m_run_menu);
 }
 
-void ScriptingWindow::windowAboutToShow()
+void ScriptingWindow::windowMenuAboutToShow()
 {
   m_window_menu->clear();
 
-  m_window_menu->addAction(m_always_on_top);
-  m_window_menu->addAction(m_hide);
-
-  if( m_manager->count() > 0 )
-  {
-    m_window_menu->insertSeparator();
-    m_window_menu->addAction(m_manager->zoomInAction());
-    m_window_menu->addAction(m_manager->zoomOutAction());
-    m_window_menu->insertSeparator();
-    //Toggle output dock
-    m_toggle_output = m_output_dock->toggleViewAction();
-    m_toggle_output->setText("&Show Output");
-    m_toggle_output->setChecked(true);
-    m_window_menu->addAction(m_toggle_output);
-    //Toggle progress
-    m_window_menu->addAction(m_manager->m_toggle_progress);
-
-    m_window_menu->insertSeparator();
-    //Toggle folding
-    m_window_menu->addAction(m_manager->m_toggle_folding);
-    //Toggle code completion
-    m_window_menu->addAction(m_manager->m_toggle_completion);
-    //Toggle call tips
-    m_window_menu->addAction(m_manager->m_toggle_calltips);
-  }
+//  m_window_menu->addAction(m_always_on_top);
+//  m_window_menu->addAction(m_hide);
+//
+//  if( m_manager->count() > 0 )
+//  {
+//    m_window_menu->insertSeparator();
+//    m_window_menu->addAction(m_manager->zoomInAction());
+//    m_window_menu->addAction(m_manager->zoomOutAction());
+//    m_window_menu->insertSeparator();
+//
+//    //Toggle progress
+//    m_window_menu->addAction(m_manager->m_toggle_progress);
+//
+//    m_window_menu->insertSeparator();
+//    //Toggle folding
+//    m_window_menu->addAction(m_manager->m_toggle_folding);
+//    //Toggle code completion
+//    m_window_menu->addAction(m_manager->m_toggle_completion);
+//    //Toggle call tips
+//    m_window_menu->addAction(m_manager->m_toggle_calltips);
+//  }
 }
 
 /**
@@ -536,10 +244,7 @@ void ScriptingWindow::updateWindowFlags()
 
 void ScriptingWindow::tabSelectionChanged()
 {
-  // Ensure that the shortcuts are active
-  fileAboutToShow();
-  editAboutToShow();
-  windowAboutToShow();
+
 }
 
 //-------------------------------------------
@@ -552,40 +257,34 @@ void ScriptingWindow::initMenus()
 {
   //************* File menu *************
   m_file_menu = menuBar()->addMenu(tr("&File"));
-
 #ifdef SCRIPTING_DIALOG
   m_scripting_lang = new QAction(tr("Scripting &language"), this);
   connect(m_scripting_lang, SIGNAL(activated()), this, SIGNAL(chooseScriptingLanguage()));
 #endif
-
-  connect(m_file_menu, SIGNAL(aboutToShow()), this, SLOT(fileAboutToShow()));
-
-  m_print_output = new QAction(tr("Print &Output"), this);
-  connect(m_print_output, SIGNAL(activated()), m_output_dock, SLOT(print()));
+  connect(m_file_menu, SIGNAL(aboutToShow()), this, SLOT(fileMenuAboutToShow()));
 
   //************* Edit menu *************
   m_edit_menu = menuBar()->addMenu(tr("&Edit"));
-  connect(m_edit_menu, SIGNAL(aboutToShow()), this, SLOT(editAboutToShow()));
-   // Clear output
-  m_clear_output = new QAction(tr("&Clear Output"), this);
-  connect(m_clear_output, SIGNAL(activated()), m_output_dock, SLOT(clear()));
+  connect(m_edit_menu, SIGNAL(aboutToShow()), this, SLOT(editMenuAboutToShow()));
   
   //************* Run menu *************
   m_run_menu = menuBar()->addMenu(tr("E&xecute"));
-  // Execute script
-  m_run_menu->addAction(m_manager->m_exec);
-  // Execute everything from a script
-  m_run_menu->addAction(m_manager->m_exec_all);
-  //Evaluate function for those environments that support one
-  //  m_run_menu->addAction(m_manager->m_eval);
+  connect(m_run_menu, SIGNAL(aboutToShow()), this, SLOT(execMenuAboutToShow()));
 
   //************* Window menu *************
   m_window_menu = menuBar()->addMenu(tr("&Window"));
-  //Always on top
+  initWindowActions();
+}
+
+/**
+ * Create window actions
+ */
+void ScriptingWindow::initWindowActions()
+{
   m_always_on_top = new QAction(tr("Always on &Top"), this);
   m_always_on_top->setCheckable(true);
   connect(m_always_on_top, SIGNAL(toggled(bool)), this, SLOT(updateWindowFlags()));
-  //Hide
+
   m_hide = new QAction(tr("&Hide"), this);
 #ifdef __APPLE__
   m_hide->setShortcut(tr("Ctrl+3")); // F3 is used by the window manager on Mac
@@ -594,7 +293,9 @@ void ScriptingWindow::initMenus()
 #endif
   // Note that we channel the hide through the parent so that we can save the geometry state
   connect(m_hide, SIGNAL(activated()), this, SIGNAL(hideMe()));
+
 }
+
 /**
  * calls ScriptManagerWidget saveToString and  
  *  saves the currently opened script file names to a string
diff --git a/Code/Mantid/MantidPlot/src/ScriptingWindow.h b/Code/Mantid/MantidPlot/src/ScriptingWindow.h
index 454279341aba33ced79ec47381cea7d202a405b7..4d6d6412d65187906aa59cff51ccfa3ab7e5f472 100755
--- a/Code/Mantid/MantidPlot/src/ScriptingWindow.h
+++ b/Code/Mantid/MantidPlot/src/ScriptingWindow.h
@@ -5,7 +5,6 @@
 // Includes
 //----------------------------------
 #include <QMainWindow>
-#include <QDockWidget>
 
 //----------------------------------------------------------
 // Forward declarations
@@ -20,82 +19,6 @@ class QCloseEvent;
 class QShowEvent;
 class QHideEvent;
 
-/** @class ScriptOutputDock
-    
-   This class holds any output from executed scripts. It defines a custom context menu
-   that allows the text to be cleared, copied and printed. Note: Ideally this would be
-   nested inside ScriptWindow as it is not needed anywhere else, but the Qt SIGNAL/SLOTS
-   mechanism doesn't work with nested classes.
-   
-   This class displays a window for editing and executing scripts.
-   
-   @author Martyn Gigg, Tessella Support Services plc
-   @date 19/08/2009
-   
-   Copyright &copy; 2009 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
-   
-   This file is part of Mantid.
-   
-   Mantid is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-   
-   Mantid 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, see <http://www.gnu.org/licenses/>.
-   
-   File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>
-   Code Documentation is available at: <http://doxygen.mantidproject.org>    
-*/
-class ScriptOutputDock : public QDockWidget
-{
-  /// Qt macro
-  Q_OBJECT
-  
-public:
-  /// Constructor
-  ScriptOutputDock(const QString & title, ScriptManagerWidget *manager, QWidget *parent = 0, 
-		   Qt::WindowFlags flags = 0);
-
-  /// Is there anything here
-  bool isEmpty() const;
-
-public slots:
-  /// Clear the text
-  void clear();
-  /// Print the text within the window
-  void print();
-  /// Save the output to a file
-  void saveToFile();
-  /// Change the title based on the script's execution state
-  void setScriptIsRunning(bool running);    
-	      
-private slots:
-  /// Context menu slot
-  void showContextMenu(const QPoint & pos);
-  /// A slot to pass messages to the output dock
-  void displayOutputMessage(const QString &, bool error, bool timestamp);
-
-private:
-  /// Create the action pointers
-  void initActions();
-  /// Reset the default font
-  void resetFont();
-
-private:
-  /// The script manager
-  ScriptManagerWidget *m_manager;
-  /// The actually widget that displays the text
-  QTextEdit *m_text_display;
-  /// Copy action
-  QAction *m_copy;
-};
-
 
 /** @class ScriptingWindow    
     This class displays a seperate window for editing and executing scripts
@@ -136,20 +59,27 @@ signals:
   void closeMe();
   /// Tell others we are hiding
   void hideMe();
+
   
 private:
   /// Create menu bar and menu actions
   void initMenus();
+  /// Create window actions
+  void initWindowActions();
+
   /// Accept a custom defined event
   void customEvent(QEvent * event);
 
 private slots:
   /// File menu is about to show
-  void fileAboutToShow();
+  void fileMenuAboutToShow();
   /// Edit menu is about to show
-  void editAboutToShow();
+  void editMenuAboutToShow();
+  /// Exec menu about to show
+  void execMenuAboutToShow();
   /// Window menu is about to show
-  void windowAboutToShow();
+  void windowMenuAboutToShow();
+
   /// Update window flags
   void updateWindowFlags();
   /// Update based on tab changes
@@ -158,21 +88,17 @@ private slots:
 private:
   /// The script editors' manager
   ScriptManagerWidget *m_manager;
-  /// Output display dock
-  ScriptOutputDock *m_output_dock;
 
-  /// File menu (actions are stored in ScriptManagerWidget)
+  /// File menu
   QMenu *m_file_menu;
   /// Edit menu
   QMenu *m_edit_menu;
-  /// Specific window edit actions
-  QAction *m_clear_output;
-  /// Run menu (actions are stored in ScriptManagerWidget)
+  /// Run menu
   QMenu *m_run_menu;
   /// Window menu
   QMenu *m_window_menu;
   /// Window actions
-  QAction *m_always_on_top, *m_hide, *m_toggle_output, *m_print_output;
+  QAction *m_always_on_top, *m_hide;
   /// Change scripting language
   QAction *m_scripting_lang;
   /// Flag to define whether we should accept a close event
diff --git a/Code/Mantid/MantidPlot/src/SetColValuesDialog.cpp b/Code/Mantid/MantidPlot/src/SetColValuesDialog.cpp
index ce0f95759b553bd87fc629fc8f32a01763a85c77..317fffaa691cd727a0d1fc03f74069c1905119f6 100644
--- a/Code/Mantid/MantidPlot/src/SetColValuesDialog.cpp
+++ b/Code/Mantid/MantidPlot/src/SetColValuesDialog.cpp
@@ -31,7 +31,7 @@
  ***************************************************************************/
 #include "SetColValuesDialog.h"
 #include "Table.h"
-#include "ScriptEdit.h"
+#include "MantidQtMantidWidgets/ScriptEditor.h"
 
 #include <QTableWidget>
 #include <QTableWidgetSelectionRange>
@@ -44,6 +44,7 @@
 #include <QComboBox>
 #include <QTextEdit>
 #include <QTextCursor>
+#include <QMessageBox>
 #ifdef SCRIPTING_PYTHON
 #include <QCheckBox>
 #endif
@@ -116,7 +117,7 @@ SetColValuesDialog::SetColValuesDialog( ScriptingEnv *env, Table* t, Qt::WFlags
 	hbox2->addWidget(explain);
 	hbox2->addWidget(gb);
 
-	commands = new ScriptEdit( scriptingEnv());
+	commands = new ScriptEditor(this, false, scriptingEnv()->createCodeLexer());
 
 	QVBoxLayout *vbox2 = new QVBoxLayout();
 	btnApply = new QPushButton(tr( "&Apply" ));
@@ -243,7 +244,7 @@ void SetColValuesDialog::insertExplain(int index)
 
 void SetColValuesDialog::insertFunction()
 {
-  commands->insertFunction(functions->currentText());
+  QMessageBox::warning(this, "", "Deprepcated functionality");
 }
 
 void SetColValuesDialog::insertCol()
@@ -280,5 +281,4 @@ void SetColValuesDialog::setTable(Table* w)
 	}
 
 	updateColumn(w->selectedColumn());
-	commands->setContext(w);
 }
diff --git a/Code/Mantid/MantidPlot/src/SetColValuesDialog.h b/Code/Mantid/MantidPlot/src/SetColValuesDialog.h
index 2341f9013a3ff84ef2ab49cd566f0bf2dafb1976..d7ab9a04546872913f1f6b516083fd70816e7b72 100644
--- a/Code/Mantid/MantidPlot/src/SetColValuesDialog.h
+++ b/Code/Mantid/MantidPlot/src/SetColValuesDialog.h
@@ -46,7 +46,7 @@ class QCheckBox;
 #endif
 class Table;
 class ScriptingEnv;
-class ScriptEdit;
+class ScriptEditor;
 
 
 //! Set column values dialog
@@ -83,7 +83,7 @@ private:
     QPushButton *buttonNext;
     QPushButton *addCellButton;
     QPushButton *btnApply;
-    ScriptEdit* commands;
+    ScriptEditor* commands;
     QTextEdit* explain;
 	QSpinBox* start, *end;
 	QLabel *colNameLabel;
diff --git a/Code/Mantid/MantidPlot/src/Table.cpp b/Code/Mantid/MantidPlot/src/Table.cpp
index c2e17bfc94645df0dd0df4aa1b19747480c6add2..fcfdd10247e76a16ce0deb0d5090b6a668f5740f 100644
--- a/Code/Mantid/MantidPlot/src/Table.cpp
+++ b/Code/Mantid/MantidPlot/src/Table.cpp
@@ -308,12 +308,12 @@ void Table::cellEdited(int row, int col)
     d_table->setText(row, col, locale().toString(res, f, precision));
   else
   {
-    Script *script = scriptingEnv()->newScript(d_table->text(row,col),this,QString("<%1_%2_%3>").arg(objectName()).arg(row+1).arg(col+1), false);
+    Script *script = scriptingEnv()->newScript(QString("<%1_%2_%3>").arg(objectName()).arg(row+1).arg(col+1), this, Script::NonInteractive);
     connect(script, SIGNAL(error(const QString&,const QString&,int)), scriptingEnv(), SIGNAL(error(const QString&,const QString&,int)));
 
     script->setInt(row+1, "i");
     script->setInt(col+1, "j");
-    QVariant ret = script->eval();
+    QVariant ret = script->evaluate(d_table->text(row,col));
     if(ret.type()==QVariant::Int || ret.type()==QVariant::UInt || ret.type()==QVariant::LongLong || ret.type()==QVariant::ULongLong)
       d_table->setText(row, col, ret.toString());
     else if(ret.canCast(QVariant::Double))
@@ -561,7 +561,7 @@ bool Table::muParserCalculate(int col, int startRow, int endRow, bool notifyChan
 
   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
 
-  muParserScript *mup = new muParserScript(scriptingEnv(), cmd, this,  QString("<%1>").arg(colName(col)));
+  muParserScript *mup = new muParserScript(scriptingEnv(), QString("<%1>").arg(colName(col)), this, true);
   connect(mup, SIGNAL(error(const QString&,const QString&,int)), scriptingEnv(), SIGNAL(error(const QString&,const QString&,int)));
   connect(mup, SIGNAL(print(const QString&)), scriptingEnv(), SIGNAL(print(const QString&)));
 
@@ -570,9 +570,9 @@ bool Table::muParserCalculate(int col, int startRow, int endRow, bool notifyChan
   mup->defineVariable("sr", startRow + 1.0);
   mup->defineVariable("er", endRow + 1.0);
 
-  if (!mup->compile()){
-    QApplication::restoreOverrideCursor();
-    return false;
+  if (!mup->compile(cmd)){
+      QApplication::restoreOverrideCursor();
+      return false;
   }
 
   QLocale loc = locale();
@@ -589,7 +589,7 @@ bool Table::muParserCalculate(int col, int startRow, int endRow, bool notifyChan
     QVariant ret;
     for (int i = startRow; i <= endRow; i++){
       *r = i + 1.0;
-      ret = mup->eval();
+      ret = mup->evaluate(cmd);
       if(ret.type() == QVariant::Double) {
         d_table->setText(i, col, loc.toString(ret.toDouble(), f, prec));
       } else if(ret.canConvert(QVariant::String))
@@ -638,13 +638,13 @@ bool Table::calculate(int col, int startRow, int endRow, bool forceMuParser, boo
 
   QApplication::setOverrideCursor(Qt::WaitCursor);
 
-  Script *colscript = scriptingEnv()->newScript(cmd, this, QString("<%1>").arg(colName(col)), false);
+  Script *colscript = scriptingEnv()->newScript(QString("<%1>").arg(colName(col)), this, Script::NonInteractive);
   connect(colscript, SIGNAL(error(const QString&,const QString&,int)), scriptingEnv(), SIGNAL(error(const QString&,const QString&,int)));
   connect(colscript, SIGNAL(print(const QString&)), scriptingEnv(), SIGNAL(print(const QString&)));
 
-  if (!colscript->compile()){
-    QApplication::restoreOverrideCursor();
-    return false;
+  if (!colscript->compile(cmd)){
+      QApplication::restoreOverrideCursor();
+      return false;
   }
 
   QLocale loc = locale();
@@ -658,7 +658,7 @@ bool Table::calculate(int col, int startRow, int endRow, bool forceMuParser, boo
   QVariant ret;
   for (int i = startRow; i <= endRow; i++){
     colscript->setDouble(i + 1.0, "i");
-    ret = colscript->eval();
+    ret = colscript->evaluate(cmd);
     if(ret.type() == QVariant::Double)
       d_table->setText(i, col, loc.toString(ret.toDouble(), f, prec));
     else if(ret.canConvert(QVariant::String))
diff --git a/Code/Mantid/MantidPlot/src/TextFileIO.cpp b/Code/Mantid/MantidPlot/src/TextFileIO.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d65e9ef51ab8fdb58d3ef354ceb110e0eae4d5f3
--- /dev/null
+++ b/Code/Mantid/MantidPlot/src/TextFileIO.cpp
@@ -0,0 +1,63 @@
+#include "TextFileIO.h"
+
+#include <QFile>
+#include <QFileDialog>
+#include <QFileInfo>
+#include <QMessageBox>
+#include <QTextStream>
+#include <QApplication>
+
+/**
+ * Construct an object with a list of file filters
+ */
+TextFileIO::TextFileIO(QStringList fileFilters) : m_filters(fileFilters)
+{
+
+}
+
+/**
+ * Save to a file
+ * @param filename An optional filename
+ * @return True if the save was successful, false otherwise
+ */
+bool TextFileIO::save(const QString & txt, const QString & filename) const
+{
+  QString saved = filename;
+  if(saved.isEmpty())
+  {
+    saved = askWhereToSave();
+  }
+  if(saved.isEmpty()) return true; //cancelled
+
+  QFile file(saved);
+  if( !file.open(QIODevice::WriteOnly) )
+  {
+    QMessageBox::critical(NULL, "MantidPlot - File error",
+        QString("Could not open file \"%1\" for writing.").arg(saved));
+    return false;
+  }
+
+  QTextStream writer(&file);
+  QApplication::setOverrideCursor(Qt::WaitCursor);
+  writer << txt;
+  QApplication::restoreOverrideCursor();
+  file.close();
+  return true;
+}
+
+/// Open a save dialog
+QString TextFileIO::askWhereToSave() const
+{
+  QString selectedFilter;
+  QString filter = m_filters.join(";;");
+  QString filename = QFileDialog::getSaveFileName(NULL, "MantidPlot - Save", "",filter, &selectedFilter);
+  if( filename.isEmpty() ) return QString();
+  if( QFileInfo(filename).suffix().isEmpty() )
+  {
+    QString ext = selectedFilter.section('(',1).section(' ', 0, 0);
+    ext.remove(0,1);
+    if( ext != ")" ) filename += ext;
+  }
+  return filename;
+
+}
diff --git a/Code/Mantid/MantidPlot/src/TextFileIO.h b/Code/Mantid/MantidPlot/src/TextFileIO.h
new file mode 100644
index 0000000000000000000000000000000000000000..76fd805a3234953b8323955cdbdd44ac6ac0c5d9
--- /dev/null
+++ b/Code/Mantid/MantidPlot/src/TextFileIO.h
@@ -0,0 +1,28 @@
+#ifndef TEXTFILEIO_H_
+#define TEXTFILEIO_H_
+
+#include <QString>
+#include <QStringList>
+
+/**
+ * Defines a static class for simple text file
+ * I/O.
+ */
+class TextFileIO
+{
+public:
+  /// Construct the object with a list of file filters
+  TextFileIO(QStringList fileFilters = QStringList());
+
+  /// Save to a file
+  bool save(const QString & txt, const QString & filename) const;
+
+private:
+  /// Open a save dialog
+  QString askWhereToSave() const;
+
+  const QStringList m_filters;
+};
+
+
+#endif /* TEXTFILEIO_H_ */
diff --git a/Code/Mantid/MantidPlot/src/ThreadAdapter.cpp b/Code/Mantid/MantidPlot/src/ThreadAdapter.cpp
index 076684d5e6f18d26f36b228589df664ec3538e8b..40afc78763b811813b1787daca5c2613710e44dc 100644
--- a/Code/Mantid/MantidPlot/src/ThreadAdapter.cpp
+++ b/Code/Mantid/MantidPlot/src/ThreadAdapter.cpp
@@ -5,6 +5,27 @@
 #include <QCoreApplication>
 #include <QThread>
 
+#define BEGIN_THREAD_CHECK(ReturnType, DefaultValue) \
+  ReturnType result(DefaultValue);\
+  if( QThread::currentThread() != QCoreApplication::instance()->thread() )\
+  {
+
+#define END_THREAD_CHECK(ReturnType) \
+   if(!methodSuccess)\
+   {\
+     throw std::runtime_error("Error invoking method from separate thread.");\
+   }\
+   result = qobject_cast<ReturnType>(m_lastWidget);\
+   m_lastWidget = NULL;\
+  }
+
+#define DO_GUI_THREAD_CALL(GuiFunctionCall) \
+  else\
+  {\
+    m_lastWidget = static_cast<QWidget*>(GuiFunctionCall);\
+  }\
+  return result;
+
 /**
  * Contructor
  * @param appWindow :: A reference to the ApplicationWindow
@@ -22,27 +43,32 @@ ThreadAdapter::ThreadAdapter(ApplicationWindow & appWindow, MantidUI & mantidUI)
 MultiLayer * ThreadAdapter::plotSpectraList(const QStringList& wsNames, const QList<int>& spectrumList,
                                             bool errs, Graph::CurveType style)
 {
-  if( QThread::currentThread() != QCoreApplication::instance()->thread() )
-  {
-    bool methodSuccess = QMetaObject::invokeMethod(this, "plotSpectraListGUIThread", Qt::BlockingQueuedConnection,
-                                            Q_ARG(const QStringList&, wsNames), Q_ARG(const QList<int>&, spectrumList),
-                                            Q_ARG(bool, errs), Q_ARG(Graph::CurveType, style));
-    if(!methodSuccess)
-    {
-      throw std::runtime_error("Error invoking plotSpectraList from separate thread.");
-    }
-    MultiLayer *result = qobject_cast<MultiLayer*>(m_lastWidget);
-    m_lastWidget = NULL;
-    return result;
-    }
-  else
-  {
-    return m_mantidUI.plotSpectraList(wsNames, spectrumList, errs, style);
-  }
+  BEGIN_THREAD_CHECK(MultiLayer*, NULL)
+  bool methodSuccess = QMetaObject::invokeMethod(this, "plotSpectraList", Qt::BlockingQueuedConnection,
+                                                 Q_ARG(const QStringList&, wsNames), Q_ARG(const QList<int>&, spectrumList),
+                                                 Q_ARG(bool, errs), Q_ARG(Graph::CurveType, style));
+  END_THREAD_CHECK(MultiLayer*)
+  DO_GUI_THREAD_CALL(m_mantidUI.plotSpectraList(wsNames, spectrumList, errs, style))
+}
+
+MultiLayer* ThreadAdapter::plotBin(const QString& wsName,int index,bool errs, Graph::CurveType style)
+{
+  BEGIN_THREAD_CHECK(MultiLayer*, NULL)
+  bool methodSuccess = QMetaObject::invokeMethod(this, "plotBin", Qt::BlockingQueuedConnection,
+                                                 Q_ARG(const QString&, wsName), Q_ARG(int, index),
+                                                 Q_ARG(bool, errs), Q_ARG(Graph::CurveType, style));
+  END_THREAD_CHECK(MultiLayer*)
+  DO_GUI_THREAD_CALL(m_mantidUI.plotBin(wsName, index, errs, style))
 }
 
-void ThreadAdapter::plotSpectraListGUIThread(const QStringList& wsNames, const QList<int>& spectrumList,
-                                             bool errs, Graph::CurveType style)
+MultiLayer* ThreadAdapter::mergePlots(MultiLayer *plotOne, MultiLayer *plotTwo)
 {
-  m_lastWidget = static_cast<QWidget*>(m_mantidUI.plotSpectraList(wsNames, spectrumList, errs, style));
+  BEGIN_THREAD_CHECK(MultiLayer*, NULL)
+  bool methodSuccess = QMetaObject::invokeMethod(this, "plotBin", Qt::BlockingQueuedConnection,
+                                                 Q_ARG(MultiLayer*, plotOne), Q_ARG(MultiLayer*, plotTwo));
+  END_THREAD_CHECK(MultiLayer*)
+  DO_GUI_THREAD_CALL(m_mantidUI.mergePlots(plotOne, plotTwo))
 }
+
+//void convertToWaterfall(MultiLayer *simplePlot);
+
diff --git a/Code/Mantid/MantidPlot/src/ThreadAdapter.h b/Code/Mantid/MantidPlot/src/ThreadAdapter.h
index 657c24d652007547c7d3c2f93f88a84d83787c8e..2b447a180dec55f2a89ec685274f522e02f0a599 100644
--- a/Code/Mantid/MantidPlot/src/ThreadAdapter.h
+++ b/Code/Mantid/MantidPlot/src/ThreadAdapter.h
@@ -7,10 +7,11 @@
 //-----------------------------------------------------------------------------
 // Forward declarations
 //-----------------------------------------------------------------------------
+class QWidget;
 class ApplicationWindow;
 class MantidUI;
-class QWidget;
-
+class MantidMatrix;
+class Table;
 
 /**
  * An object that ensures all function calls that occur end up on the
@@ -38,13 +39,32 @@ public:
   /// Construct with an ApplicationWindow & MantidUI instance
   explicit ThreadAdapter(ApplicationWindow & appWindow, MantidUI & mantidUI);
 
+public slots:
   //-------------------------- Plotting -------------------------------------------------------
-
   MultiLayer * plotSpectraList(const QStringList& wsNames, const QList<int>& spectrumList,
                                bool errs = true, Graph::CurveType style = Graph::Unspecified);
-private slots:
-  void plotSpectraListGUIThread(const QStringList& wsNames, const QList<int>& spectrumList,
-                                bool errs, Graph::CurveType style);
+  MultiLayer* plotBin(const QString& wsName,int index,bool errs = false,
+                      Graph::CurveType style = Graph::Unspecified);
+  MultiLayer* mergePlots(MultiLayer *plotOne, MultiLayer *plotTwo);
+//  void convertToWaterfall(MultiLayer *simplePlot);
+
+  //-------------------------- Instrument view ------------------------------------------------
+  //  InstrumentWindow* getInstrumentView(const QString &, int tab = -1);
+  //%MethodCode
+  //  sipRes = sipCpp->getInstrumentView(*a0,a1);
+  //  sipRes->hide();
+  //%End
+
+  //-------------------------- Mantid Matrices -------------------------------------------------
+  // Methods relating to creating or getting handles to GUI objects
+//  MantidMatrix* getMantidMatrix(const QString &);
+//  MantidMatrix* importMatrixWorkspace(const QString& wsName, int lower=-1, int upper=-1,
+//                                      bool showDlg=false, bool makeVisible=false);
+//
+//  //-------------------------- Tables ----------------------------------------------------------
+//  Table* createTableFromSpectraList(const QString& tableName, const QString& workspaceName,
+//                                    QList<int> indexList, bool errs=true, bool binCentres=false);
+//  Table* importTableWorkspace(const QString&, bool = false, bool = false);
 
 
 private:
diff --git a/Code/Mantid/MantidPlot/src/muParserScript.cpp b/Code/Mantid/MantidPlot/src/muParserScript.cpp
index 8a8178386c79fb8e331dc14c338d4ae85984ef1b..841d790a8b3b5e76e2c5edaf07fa52bab086cf8c 100644
--- a/Code/Mantid/MantidPlot/src/muParserScript.cpp
+++ b/Code/Mantid/MantidPlot/src/muParserScript.cpp
@@ -41,10 +41,10 @@
 
 using namespace mu;
 
-muParserScript::muParserScript(ScriptingEnv *env, const QString &code, QObject *context, 
-			       const QString &name, bool checkMultilineCode)
-  : Script(env, code, context, name),
-    d_warn_multiline_code(checkMultilineCode)
+muParserScript::muParserScript(ScriptingEnv *env,  const QString &name, QObject *context,
+    bool checkMultilineCode)
+: Script(env,name, Script::NonInteractive, context),
+  d_warn_multiline_code(checkMultilineCode)
 {
   variables.setAutoDelete(true);
   rvariables.setAutoDelete(true);
@@ -63,209 +63,208 @@ muParserScript::muParserScript(ScriptingEnv *env, const QString &code, QObject *
     else if (i->numargs == 3 && i->fun3 != NULL)
       parser.DefineFun(i->name, i->fun3);
 
-  if (Context->isA("Table")) {
-	  parser.DefineFun("col", mu_col, false);
-	  parser.DefineFun("cell", mu_tableCell);
-	  parser.DefineFun("tablecol", mu_tablecol, false);
-  } else if (Context->isA("Matrix"))
-	  parser.DefineFun("cell", mu_cell);
+  if (context->isA("Table")) {
+    parser.DefineFun("col", mu_col, false);
+    parser.DefineFun("cell", mu_tableCell);
+    parser.DefineFun("tablecol", mu_tablecol, false);
+  } else if (context->isA("Matrix"))
+    parser.DefineFun("cell", mu_cell);
 
   rparser = parser;
-  if (Context->isA("Table") || Context->isA("Matrix")){
-    if (code.count("\n") > 0){//only autodetect new variables for a script which has min 2 lines
-		if (d_warn_multiline_code){
-        	QApplication::restoreOverrideCursor();
-        	QString mess = tr("Multiline expressions take much more time to evaluate! Do you want to continue anyways?");
-        	if (QMessageBox::Yes == QMessageBox::warning((QWidget *)Context, tr("MantidPlot") + " - " + tr("Warning"), mess,
-                           QMessageBox::Yes, QMessageBox::Cancel)){
-           		parser.SetVarFactory(mu_addVariable);
-            	rparser.SetVarFactory(mu_addVariableR);
-			}
-		} else {
-            parser.SetVarFactory(mu_addVariable);
-            rparser.SetVarFactory(mu_addVariableR);
-		}
-	}
-  } else {
+  if (context->isA("Table") || context->isA("Matrix")){
+    if (d_warn_multiline_code){
+      QApplication::restoreOverrideCursor();
+      QString mess = tr("Multiline expressions take much more time to evaluate! Do you want to continue anyways?");
+      if (QMessageBox::Yes == QMessageBox::warning((QWidget*)context, tr("MantidPlot") + " - " + tr("Warning"), mess,
+          QMessageBox::Yes, QMessageBox::Cancel)){
+        parser.SetVarFactory(mu_addVariable);
+        rparser.SetVarFactory(mu_addVariableR);
+      }
+    } else {
       parser.SetVarFactory(mu_addVariable);
       rparser.SetVarFactory(mu_addVariableR);
+    }
+  } else {
+    parser.SetVarFactory(mu_addVariable);
+    rparser.SetVarFactory(mu_addVariableR);
   }
 }
 
 double muParserScript::col(const QString &arg)
 {
-	if (!Context->isA("Table"))
-		throw Parser::exception_type(tr("col() works only on tables!").ascii());
-	QStringList items;
-	QString item = "";
-
-	for (int i=0; i < arg.size(); i++) {
-		if (arg[i] == '"') {
-			item += "\"";
-			for (i++; i < arg.size() && arg[i] != '"'; i++)
-				if (arg[i] == '\\') {
-					item += "\\";
-					item += arg[++i];
-				} else
-					item += arg[i];
-				item += "\"";
-		} else if (arg[i] == ',') {
-			items << item;
-			item = "";
-		} else
-			item += arg[i];
-	}
-	items << item;
-
-	Table *table = (Table*) Context;
-	int col, row;
-	Parser local_parser(rparser);
-	if (items[0].startsWith("\"") && items[0].endsWith("\"")) {
-		col = table->colNames().findIndex(items[0].mid(1,items[0].length()-2));
-		if (col<0)
-			throw Parser::exception_type(tr("There's no column named %1 in table %2!").
-					arg(items[0]).arg(Context->name()).ascii());
-	} else {// for backwards compatibility
-		col = table->colNames().findIndex(items[0]);
-		if (col<0) {
-			local_parser.SetExpr(items[0].ascii());
-			col = qRound(local_parser.Eval()) - 1;
-		}
-	}
-
-	if (items.count() == 2)
-	{
-		local_parser.SetExpr(items[1].ascii());
-		row = qRound(local_parser.Eval()) - 1;
-	} else if (variables["i"])
-		row = (int) *(variables["i"]) - 1;
-	else
-		return 0;
-	rvariables.clear();
-	if (row < 0 || row >= table->numRows())
-		throw Parser::exception_type(tr("There's no row %1 in table %2!").
-				arg(row+1).arg(Context->name()).ascii());
-	if (col < 0 || col >= table->numCols())
-		throw Parser::exception_type(tr("There's no column %1 in table %2!").
-				arg(col+1).arg(Context->name()).ascii());
-	if (table->text(row, col).isEmpty())
-		throw new EmptySourceError();
-	else
-		return table->cell(row,col);
+  if (!context()->isA("Table"))
+    throw Parser::exception_type(tr("col() works only on tables!").ascii());
+  QStringList items;
+  QString item = "";
+
+  for (int i=0; i < arg.size(); i++) {
+    if (arg[i] == '"') {
+      item += "\"";
+      for (i++; i < arg.size() && arg[i] != '"'; i++)
+        if (arg[i] == '\\') {
+          item += "\\";
+          item += arg[++i];
+        } else
+          item += arg[i];
+      item += "\"";
+    } else if (arg[i] == ',') {
+      items << item;
+      item = "";
+    } else
+      item += arg[i];
+  }
+  items << item;
+
+  Table *table = (Table*) const_cast<QObject*>(context());
+  int col, row;
+  Parser local_parser(rparser);
+  if (items[0].startsWith("\"") && items[0].endsWith("\"")) {
+    col = table->colNames().findIndex(items[0].mid(1,items[0].length()-2));
+    if (col<0)
+      throw Parser::exception_type(tr("There's no column named %1 in table %2!").
+          arg(items[0]).arg(context()->name()).ascii());
+  } else {// for backwards compatibility
+    col = table->colNames().findIndex(items[0]);
+    if (col<0) {
+      local_parser.SetExpr(items[0].ascii());
+      col = qRound(local_parser.Eval()) - 1;
+    }
+  }
+
+  if (items.count() == 2)
+  {
+    local_parser.SetExpr(items[1].ascii());
+    row = qRound(local_parser.Eval()) - 1;
+  } else if (variables["i"])
+    row = (int) *(variables["i"]) - 1;
+  else
+    return 0;
+  rvariables.clear();
+  if (row < 0 || row >= table->numRows())
+    throw Parser::exception_type(tr("There's no row %1 in table %2!").
+        arg(row+1).arg(context()->name()).ascii());
+  if (col < 0 || col >= table->numCols())
+    throw Parser::exception_type(tr("There's no column %1 in table %2!").
+        arg(col+1).arg(context()->name()).ascii());
+  if (table->text(row, col).isEmpty())
+    throw new EmptySourceError();
+  else
+    return table->cell(row,col);
 }
 
 double muParserScript::tablecol(const QString &arg)
 {
-	if (!Context->isA("Table"))
-		throw Parser::exception_type(tr("tablecol() works only on tables!").ascii());
-	QStringList items;
-	QString item = "";
-	for (int i=0; i < arg.size(); i++) {
-		if (arg[i] == '"') {
-			item += "\"";
-			for (i++; i < arg.size() && arg[i] != '"'; i++)
-				if (arg[i] == '\\') {
-					item += "\\";
-					item += arg[++i];
-				} else
-					item += arg[i];
-				item += "\"";
-		} else if (arg[i] == ',') {
-			items << item;
-			item = "";
-		} else
-			item += arg[i];
-	}
-	items << item;
-	Table *this_table = (Table*) Context;
-	int col, row;
-	Parser local_parser(rparser);
-	if (items.count() != 2)
-		throw Parser::exception_type(tr("tablecol: wrong number of arguments (need 2, got %1)").arg(items.count()).ascii());
-	if (!items[0].startsWith("\"") || !items[0].endsWith("\""))
-		throw Parser::exception_type(tr("tablecol: first argument must be a string (table name)").ascii());
-	Table *target_table = this_table->folder()->rootFolder()->table(items[0].mid(1,items[0].length()-2));
-	if (!target_table)
-		throw Parser::exception_type(tr("Couldn't find a table named %1.").arg(items[0]).ascii());
-	if (items[1].startsWith("\"") && items[1].endsWith("\"")) {
-		col = target_table->colNames().findIndex(items[1].mid(1,items[1].length()-2));
-		if (col<0)
-			throw Parser::exception_type(tr("There's no column named %1 in table %2!").
-					arg(items[1]).arg(target_table->name()).ascii());
-	} else {
-		local_parser.SetExpr(items[1].ascii());
-		col = qRound(local_parser.Eval()) - 1;
-	}
-	if (variables["i"])
-		row = (int) *(variables["i"]) - 1;
-	else
-		row = -1;
-	rvariables.clear();
-	if (row < 0 || row >= target_table->numRows())
-		throw Parser::exception_type(tr("There's no row %1 in table %2!").
-				arg(row+1).arg(target_table->name()).ascii());
-	if (col < 0 || col >= target_table->numCols())
-		throw Parser::exception_type(tr("There's no column %1 in table %2!").
-				arg(col+1).arg(target_table->name()).ascii());
-	if (target_table->text(row,col).isEmpty())
-		throw new EmptySourceError();
-	else
-		return target_table->cell(row,col);
+  if (!context()->isA("Table"))
+    throw Parser::exception_type(tr("tablecol() works only on tables!").ascii());
+  QStringList items;
+  QString item = "";
+  for (int i=0; i < arg.size(); i++) {
+    if (arg[i] == '"') {
+      item += "\"";
+      for (i++; i < arg.size() && arg[i] != '"'; i++)
+        if (arg[i] == '\\') {
+          item += "\\";
+          item += arg[++i];
+        } else
+          item += arg[i];
+      item += "\"";
+    } else if (arg[i] == ',') {
+      items << item;
+      item = "";
+    } else
+      item += arg[i];
+  }
+  items << item;
+
+  Table *this_table = (Table*) const_cast<QObject*>(context());
+  int col, row;
+  Parser local_parser(rparser);
+  if (items.count() != 2)
+    throw Parser::exception_type(tr("tablecol: wrong number of arguments (need 2, got %1)").arg(items.count()).ascii());
+  if (!items[0].startsWith("\"") || !items[0].endsWith("\""))
+    throw Parser::exception_type(tr("tablecol: first argument must be a string (table name)").ascii());
+  Table *target_table = this_table->folder()->rootFolder()->table(items[0].mid(1,items[0].length()-2));
+  if (!target_table)
+    throw Parser::exception_type(tr("Couldn't find a table named %1.").arg(items[0]).ascii());
+  if (items[1].startsWith("\"") && items[1].endsWith("\"")) {
+    col = target_table->colNames().findIndex(items[1].mid(1,items[1].length()-2));
+    if (col<0)
+      throw Parser::exception_type(tr("There's no column named %1 in table %2!").
+          arg(items[1]).arg(target_table->name()).ascii());
+  } else {
+    local_parser.SetExpr(items[1].ascii());
+    col = qRound(local_parser.Eval()) - 1;
+  }
+  if (variables["i"])
+    row = (int) *(variables["i"]) - 1;
+  else
+    row = -1;
+  rvariables.clear();
+  if (row < 0 || row >= target_table->numRows())
+    throw Parser::exception_type(tr("There's no row %1 in table %2!").
+        arg(row+1).arg(target_table->name()).ascii());
+  if (col < 0 || col >= target_table->numCols())
+    throw Parser::exception_type(tr("There's no column %1 in table %2!").
+        arg(col+1).arg(target_table->name()).ascii());
+  if (target_table->text(row,col).isEmpty())
+    throw new EmptySourceError();
+  else
+    return target_table->cell(row,col);
 }
 
 double muParserScript::cell(int row, int col)
 {
-	if (!Context->isA("Matrix"))
-		throw Parser::exception_type(tr("cell() works only on tables and matrices!").ascii());
-	Matrix *matrix = (Matrix*) Context;
-	if (row < 1 || row > matrix->numRows())
-		throw Parser::exception_type(tr("There's no row %1 in matrix %2!").
-				arg(row).arg(Context->name()).ascii());
-	if (col < 1 || col > matrix->numCols())
-		throw Parser::exception_type(tr("There's no column %1 in matrix %2!").
-				arg(col).arg(Context->name()).ascii());
-	if (matrix->text(row-1,col-1).isEmpty())
-		throw new EmptySourceError();
-	else
-		return matrix->cell(row-1,col-1);
+  if (!context()->isA("Matrix"))
+    throw Parser::exception_type(tr("cell() works only on tables and matrices!").ascii());
+  Matrix *matrix = (Matrix*) const_cast<QObject*>(context());
+  if (row < 1 || row > matrix->numRows())
+    throw Parser::exception_type(tr("There's no row %1 in matrix %2!").
+        arg(row).arg(context()->name()).ascii());
+  if (col < 1 || col > matrix->numCols())
+    throw Parser::exception_type(tr("There's no column %1 in matrix %2!").
+        arg(col).arg(context()->name()).ascii());
+  if (matrix->text(row-1,col-1).isEmpty())
+    throw new EmptySourceError();
+  else
+    return matrix->cell(row-1,col-1);
 }
 
 double muParserScript::tableCell(int col, int row)
 {
-	if (!Context->isA("Table"))
-		throw Parser::exception_type(tr("cell() works only on tables and matrices!").ascii());
-	Table *table = (Table*) Context;
-	if (row < 1 || row > table->numRows())
-		throw Parser::exception_type(tr("There's no row %1 in table %2!").
-				arg(row).arg(Context->name()).ascii());
-	if (col < 1 || col > table->numCols())
-		throw Parser::exception_type(tr("There's no column %1 in table %2!").
-				arg(col).arg(Context->name()).ascii());
-	if (table->text(row-1,col-1).isEmpty())
-		throw new EmptySourceError();
-	else
-		return table->cell(row-1,col-1);
+  if (!context()->isA("Table"))
+    throw Parser::exception_type(tr("cell() works only on tables and matrices!").ascii());
+  Table *table = (Table*) const_cast<QObject*>(context());
+  if (row < 1 || row > table->numRows())
+    throw Parser::exception_type(tr("There's no row %1 in table %2!").
+        arg(row).arg(context()->name()).ascii());
+  if (col < 1 || col > table->numCols())
+    throw Parser::exception_type(tr("There's no column %1 in table %2!").
+        arg(col).arg(context()->name()).ascii());
+  if (table->text(row-1,col-1).isEmpty())
+    throw new EmptySourceError();
+  else
+    return table->cell(row-1,col-1);
 }
 
 double *muParserScript::addVariable(const char *name)
 {
-	double *valptr = new double;
-	if (!valptr)
-		throw Parser::exception_type(tr("Out of memory").ascii());
-	*valptr = 0;
-	variables.insert(name, valptr);
-	rparser.DefineVar(name, valptr);
-	return valptr;
+  double *valptr = new double;
+  if (!valptr)
+    throw Parser::exception_type(tr("Out of memory").ascii());
+  *valptr = 0;
+  variables.insert(name, valptr);
+  rparser.DefineVar(name, valptr);
+  return valptr;
 }
 
 double *muParserScript::addVariableR(const char *name)
 {
-	double *valptr = new double;
-	if (!valptr)
-		throw Parser::exception_type(tr("Out of memory").ascii());
-	*valptr = 0;
-	rvariables.insert(name, valptr);
-	return valptr;
+  double *valptr = new double;
+  if (!valptr)
+    throw Parser::exception_type(tr("Out of memory").ascii());
+  *valptr = 0;
+  rvariables.insert(name, valptr);
+  return valptr;
 }
 
 double* muParserScript::defineVariable(const char *name, double val)
@@ -276,7 +275,7 @@ double* muParserScript::defineVariable(const char *name, double val)
     valptr = new double;
     if (!valptr)
     {
-      emit_error(tr("Out of memory"), 0);
+      emit error(tr("Out of memory"), this->name(), 0);
       return 0;
     }
     try {
@@ -285,7 +284,7 @@ double* muParserScript::defineVariable(const char *name, double val)
       variables.insert(name, valptr);
     } catch (mu::ParserError &e) {
       delete valptr;
-      emit_error(QString(e.GetMsg().c_str()), 0);
+      emit error(QString(e.GetMsg().c_str()), this->name(), 0);
       return valptr;
     }
   }
@@ -301,7 +300,7 @@ bool muParserScript::setDouble(double val, const char *name)
     valptr = new double;
     if (!valptr)
     {
-      emit_error(tr("Out of memory"),0);
+      emit error(tr("Out of memory"), this->name(), 0);
       return false;
     }
     try {
@@ -310,7 +309,7 @@ bool muParserScript::setDouble(double val, const char *name)
       variables.insert(name, valptr);
     } catch (mu::ParserError &e) {
       delete valptr;
-      emit_error(QString(e.GetMsg().c_str()), 0);
+      emit error(QString(e.GetMsg().c_str()), this->name(), 0);
       return false;
     }
   }
@@ -330,171 +329,179 @@ bool muParserScript::setQObject(QObject*, const char*)
 
 QString muParserScript::compileColArg(const QString &in)
 {
-	QString out = "\"";
-	for (int i=0; i < in.size(); i++)
-		if (in[i] == 'c' && in.mid(i,4)=="col(") {
-			out += "col(";
-			QString arg = "";
-			int paren = 1;
-			for (i+=4; i < in.size() && paren > 0; i++)
-				if (in[i] == '"') {
-					arg += "\"";
-					for (i++; i < in.size() && in[i] != '"'; i++)
-						if (in[i] == '\\') {
-							arg += "\\";
-							arg += in[++i];
-						} else
-							arg += in[i];
-					arg += "\"";
-				} else if (in[i] == '(') {
-					paren++;
-					arg += "(";
-				} else if (in[i] == ')') {
-					paren--;
-					if(paren>0) arg += ")";
-				}
-				else
-					arg += in[i];
-			out += compileColArg(arg).replace('"',"\\\"");
-			out += ")";
-			i--;
-		}
-		else if (in[i] == '\\')
-			out += "\\\\";
-		else if (in[i] == '"')
-			out += "\\\"";
-		else
-			out += in[i];
-	return out + "\"";
-}
-
-bool muParserScript::compile(bool)
-{
-	muCode.clear();
-	QString muCodeLine = "";
-	for (int i=0; i < Code.size(); i++)
-		if (Code[i] == 'c' && Code.mid(i,4)=="col(") {
-			muCodeLine += "col(";
-			QString arg = "";
-			int paren = 1;
-			for (i+=4; i < Code.size() && paren > 0; i++)
-				if (Code[i] == '"') {
-					arg += "\"";
-					for (i++; Code[i] != '"' && i < Code.size(); i++)
-						if (Code[i] == '\\') {
-							arg += "\\";
-							arg += Code[++i];
-						} else
-							arg += Code[i];
-					arg += "\"";
-				} else if (Code[i] == '(') {
-					paren++;
-					arg += "(";
-				} else if (Code[i] == ')') {
-					paren--;
-					if(paren>0) arg += ")";
-				}
-				else
-					arg += Code[i];
-			muCodeLine += compileColArg(arg);
-			muCodeLine += ")";
-			i--;
-		} else if (Code[i] == '#')
-		  for (i++; Code[i] != '\n' && i < Code.size(); i++){;}
-		else if (Code[i] == '\n') {
-			muCodeLine = muCodeLine.stripWhiteSpace();
-			if (!muCodeLine.isEmpty())
-				muCode += muCodeLine;
-			muCodeLine = "";
-		} else
-			muCodeLine += Code[i];
-	muCodeLine = muCodeLine.stripWhiteSpace();
-	if (!muCodeLine.isEmpty())
-		muCode += muCodeLine;
-	compiled = Script::isCompiled;
-
-	if (muCode.size() == 1){		
-	    current = this;
-        parser.SetExpr(muCode[0].ascii());
-        try {
-			parser.Eval();
-		} catch (EmptySourceError*) {
-		    QApplication::restoreOverrideCursor();
-            return false;
-        } catch (mu::ParserError &e) {
-            if (e.GetCode() != ecVAL_EXPECTED){
-                QApplication::restoreOverrideCursor();
-                emit_error(e.GetMsg().c_str(), 0);
-                return false;
-            }
+  QString out = "\"";
+  for (int i=0; i < in.size(); i++)
+    if (in[i] == 'c' && in.mid(i,4)=="col(") {
+      out += "col(";
+      QString arg = "";
+      int paren = 1;
+      for (i+=4; i < in.size() && paren > 0; i++)
+        if (in[i] == '"') {
+          arg += "\"";
+          for (i++; i < in.size() && in[i] != '"'; i++)
+            if (in[i] == '\\') {
+              arg += "\\";
+              arg += in[++i];
+            } else
+              arg += in[i];
+          arg += "\"";
+        } else if (in[i] == '(') {
+          paren++;
+          arg += "(";
+        } else if (in[i] == ')') {
+          paren--;
+          if(paren>0) arg += ")";
         }
-	}
-	return true;
+        else
+          arg += in[i];
+      out += compileColArg(arg).replace('"',"\\\"");
+      out += ")";
+      i--;
+    }
+    else if (in[i] == '\\')
+      out += "\\\\";
+    else if (in[i] == '"')
+      out += "\\\"";
+    else
+      out += in[i];
+  return out + "\"";
 }
 
+
 QString muParserScript::evalSingleLineToString(const QLocale& locale, char f, int prec)
 {
-    double val = 0.0;
-    try {
-        val = parser.Eval();
-    } catch (EmptySourceError*) {
-        return "";
-    } catch (ParserError &) {
-		return "";
-	}
-    return locale.toString(val, f, prec);
+  double val = 0.0;
+  try {
+    val = parser.Eval();
+  } catch (EmptySourceError*) {
+    return "";
+  } catch (ParserError &) {
+    return "";
+  }
+  return locale.toString(val, f, prec);
 }
 
 double muParserScript::evalSingleLine()
 {
-    double val = 0.0;
-    try {
-        val = parser.Eval();
-    } catch (EmptySourceError *) {
-        return GSL_NAN;
-    } catch (ParserError &) {
-		return GSL_NAN;
-	}
-    return val;
+  double val = 0.0;
+  try {
+    val = parser.Eval();
+  } catch (EmptySourceError *) {
+    return GSL_NAN;
+  } catch (ParserError &) {
+    return GSL_NAN;
+  }
+  return val;
 }
 
 muParserScript *muParserScript::current = NULL;
 
-QVariant muParserScript::eval()
+bool muParserScript::compile(const QString & code)
 {
-	if (compiled != Script::isCompiled && !compile())
-		return QVariant();
-	double val = 0.0;
-	try {
-		current = this;
-		for (QStringList::iterator i=muCode.begin(); i != muCode.end(); ++i) {
-			parser.SetExpr(i->ascii());
-			val = parser.Eval();
-		}
-	} catch (EmptySourceError *) {
-		return QVariant("");
-	} catch (ParserError &e) {
-		emit_error(e.GetMsg().c_str(), 0);
-		return QVariant();
-	}
-	return QVariant(val);
+  muCode.clear();
+  QString muCodeLine = "";
+  for (int i=0; i < code.size(); i++)
+    if (code[i] == 'c' && code.mid(i,4)=="col(") {
+      muCodeLine += "col(";
+      QString arg = "";
+      int paren = 1;
+      for (i+=4; i < code.size() && paren > 0; i++)
+        if (code[i] == '"') {
+          arg += "\"";
+          for (i++; code[i] != '"' && i < code.size(); i++)
+            if (code[i] == '\\') {
+              arg += "\\";
+              arg += code[++i];
+            } else
+              arg += code[i];
+          arg += "\"";
+        } else if (code[i] == '(') {
+          paren++;
+          arg += "(";
+        } else if (code[i] == ')') {
+          paren--;
+          if(paren>0) arg += ")";
+        }
+        else
+          arg += code[i];
+      muCodeLine += compileColArg(arg);
+      muCodeLine += ")";
+      i--;
+    } else if (code[i] == '#')
+      for (i++; code[i] != '\n' && i < code.size(); i++){;}
+    else if (code[i] == '\n') {
+      muCodeLine = muCodeLine.stripWhiteSpace();
+      if (!muCodeLine.isEmpty())
+        muCode += muCodeLine;
+      muCodeLine = "";
+    } else
+      muCodeLine += code[i];
+  muCodeLine = muCodeLine.stripWhiteSpace();
+  if (!muCodeLine.isEmpty())
+    muCode += muCodeLine;
+
+  if (muCode.size() == 1){
+    current = this;
+    parser.SetExpr(muCode[0].ascii());
+    try {
+      parser.Eval();
+    } catch (EmptySourceError*) {
+      QApplication::restoreOverrideCursor();
+      return false;
+    } catch (mu::ParserError &e) {
+      if (e.GetCode() != ecVAL_EXPECTED){
+        QApplication::restoreOverrideCursor();
+        emit error(e.GetMsg().c_str(), name(), 0);
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+QVariant muParserScript::evaluate(const QString & code)
+{
+  if (!compile(code))
+    return QVariant();
+  double val = 0.0;
+  try {
+    current = this;
+    for (QStringList::iterator i=muCode.begin(); i != muCode.end(); ++i) {
+      parser.SetExpr(i->ascii());
+      val = parser.Eval();
+    }
+  } catch (EmptySourceError *) {
+    return QVariant("");
+  } catch (ParserError &e) {
+    emit error(e.GetMsg().c_str(), name(), 0);
+    return QVariant();
+  }
+  return QVariant(val);
+}
+
+bool muParserScript::execute(const QString & code)
+{
+  if (!compile(code))
+    return false;
+  try {
+    current = this;
+    for (QStringList::iterator i=muCode.begin(); i != muCode.end(); ++i) {
+      parser.SetExpr(i->ascii());
+      parser.Eval();
+    }
+  } catch (EmptySourceError *) {
+    return true;
+  } catch (mu::ParserError &e) {
+    emit error(e.GetMsg().c_str(), name(), 0);
+    return false;
+  }
+  return true;
 }
 
-bool muParserScript::exec()
+/**
+ * Execute the script in a seprate thread
+ */
+QFuture<bool> muParserScript::executeAsync(const QString &code)
 {
-	if (compiled != Script::isCompiled && !compile())
-		return false;
-	try {
-		current = this;
-		for (QStringList::iterator i=muCode.begin(); i != muCode.end(); ++i) {
-			parser.SetExpr(i->ascii());
-			parser.Eval();
-		}
-	} catch (EmptySourceError *) {
-		return true;
-	} catch (mu::ParserError &e) {
-		emit_error(e.GetMsg().c_str(), 0);
-		return false;
-	}
-	return true;
+  throw std::runtime_error("muParser does not support asynchronous execution");
 }
diff --git a/Code/Mantid/MantidPlot/src/muParserScript.h b/Code/Mantid/MantidPlot/src/muParserScript.h
index 29aa51ceab265107c77fb74411ce53407645b810..46aac0c6895b3abb66e11bd974e36c745e17a73b 100644
--- a/Code/Mantid/MantidPlot/src/muParserScript.h
+++ b/Code/Mantid/MantidPlot/src/muParserScript.h
@@ -30,7 +30,6 @@
 #ifndef MUPARSER_SCRIPT_H
 #define MUPARSER_SCRIPT_H
 
-#include "ScriptingEnv.h"
 #include "Script.h"
 
 #include "MantidGeometry/muParser_Silent.h"
@@ -38,21 +37,23 @@
 #include <gsl/gsl_sf.h>
 #include <q3asciidict.h>
 
-//! TODO
+class ScriptingEnv;
+
 class muParserScript: public Script
 {
   Q_OBJECT
 
   public:
-    muParserScript(ScriptingEnv *env, const QString &code, QObject *context=0, 
-		   const QString &name="<input>", bool checkMultilineCode = true);
+    muParserScript(ScriptingEnv *env, const QString &name,
+                   QObject *context, bool checkMultilineCode = true);
 
   public slots:
-    bool compile(bool asFunction=true);
-    QVariant eval();
+    QVariant evaluate(const QString &);
     double evalSingleLine();
     QString evalSingleLineToString(const QLocale& locale, char f, int prec);
-    bool exec();
+    bool compile(const QString & code);
+    bool execute(const QString &);
+    QFuture<bool> executeAsync(const QString &);
     bool setQObject(QObject *val, const char *name);
     bool setInt(int val, const char* name);
     bool setDouble(double val, const char* name);
diff --git a/Code/Mantid/MantidPlot/src/muParserScripting.h b/Code/Mantid/MantidPlot/src/muParserScripting.h
index 9f008a0b2532d03ea578c433094e20c6997951ef..10726c7ebe38963cd20146fd894c8674fba7718f 100644
--- a/Code/Mantid/MantidPlot/src/muParserScripting.h
+++ b/Code/Mantid/MantidPlot/src/muParserScripting.h
@@ -53,13 +53,10 @@ class muParserScripting: public ScriptingEnv
     static ScriptingEnv *constructor(ApplicationWindow *parent) { return new muParserScripting(parent); }
 
   bool isRunning() const { return true; }
-  Script *newScript(const QString &code = "", QObject *context = NULL,    
-		    const QString &name="<input>", bool interactive=true,bool reportProgress=false)
-    {
-      Q_UNUSED(reportProgress);
-      Q_UNUSED(interactive);
-      return new muParserScript(this, code, context, name);
-    }
+  Script *newScript(const QString &name, QObject * context, const Script::InteractionType) const
+  {
+    return new muParserScript(const_cast<muParserScripting*>(this), name, context);
+  }
     
     virtual bool supportsEvaluation() { return true; }
 
@@ -83,11 +80,6 @@ class muParserScripting: public ScriptingEnv
     static const mathFunction math_functions[];
 
   private:
-  //Mantid M. Gigg - These will cause an infinite recursive loop!
-//     static double ceil(double x)
-//       { return ceil(x); }
-//     static double floor(double x)
-//       { return floor(x); }
     static double mod(double x, double y)
       { return fmod(x,y); }
     static double mypow(double x, double y)
diff --git a/Code/Mantid/MantidPlot/src/qti.sip b/Code/Mantid/MantidPlot/src/qti.sip
index 768c6c6374690aa52c552a1603fce14bda51f411..6d3b50526670e36547805871e48d1910507d85f3 100644
--- a/Code/Mantid/MantidPlot/src/qti.sip
+++ b/Code/Mantid/MantidPlot/src/qti.sip
@@ -1298,10 +1298,8 @@ sipClass=sipFindClass(sipCpp->className());
 
 public:
   // Plotting methods
-  MultiLayer* plotBin(const QString&,int,bool = false,Graph::CurveType style = Graph::Unspecified);
-  MultiLayer* mergePlots(MultiLayer*, MultiLayer*);
-  void convertToWaterfall(MultiLayer*);
 
+  void convertToWaterfall(MultiLayer*);
   // Methods relating to creating or getting handles to GUI objects
   MantidMatrix* getMantidMatrix(const QString &);
   QString getSelectedWorkspaceName();
@@ -1317,7 +1315,6 @@ public:
 
   // Algorithm-related methods
   void setIsRunning(bool);
-  bool runAlgorithmAsync_PyCallback(const QString &);  	
   bool createPropertyInputDialog(const QString &, const QString &, const QString&, const QStringList&, const QStringList&);
 
 private:
@@ -1340,6 +1337,9 @@ public:
   
   MultiLayer * plotSpectraList(const QStringList& wsNames, const QList<int>& spectrumList,
                                bool errs = true, Graph::CurveType style = Graph::Unspecified);
+  MultiLayer* plotBin(const QString&,int,bool = false,Graph::CurveType style = Graph::Unspecified);
+  MultiLayer* mergePlots(MultiLayer*, MultiLayer*);
+  
 private:
   ThreadAdapter(const MantidUI &);
 };
diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/ScriptEditor.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/ScriptEditor.h
index 63bb42ecd9e996313ad819d8473f936de128aa4b..c41051f79c96bb74713fd6bc2ea26ee4001a481e 100644
--- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/ScriptEditor.h
+++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/ScriptEditor.h
@@ -14,6 +14,7 @@
 // Forward declarations
 //----------------------------------
 class QAction;
+class QMenu;
 class QKeyEvent;
 class QMouseEvent;
 class QsciAPIs;
@@ -82,6 +83,12 @@ public:
   ScriptEditor(QWidget* parent = 0, bool interpreter_mode = false, QsciLexer* lexer = NULL);
   ///Destructor
   ~ScriptEditor();
+
+  /// Add actions applicable to an edit menu
+  void populateFileMenu(QMenu &fileMenu);
+  /// Add actions applicable to an edit menu
+  void populateEditMenu(QMenu &editMenu);
+
   // Set a new code lexer for this object
   void setLexer(QsciLexer *);
   // Size hint
@@ -90,8 +97,6 @@ public:
   using QsciScintilla::setText;
   /// Set the text on a given line number
   void setText(int lineno, const QString& text,int index=0);
-  /// Save a the text to the given filename
-  bool saveScript(const QString & filename);
   ///Capture key presses
   void keyPressEvent(QKeyEvent* event);
   /// Set whether or not the current line(where the cursor is located) is editable
@@ -114,52 +119,10 @@ public:
     m_filename = filename;
   }
   
-  /// Undo action for this editor
-  inline QAction* undoAction() const
-  {
-    return m_undo;
-  }
-  /// Redo action for this editor
-  inline QAction* redoAction() const
-  {
-    return m_redo;
-  }
-
-  /// Cut action for this editor
-  inline QAction* cutAction() const
-  {
-    return m_cut;
-  }
-  /// Copy action for this editor
-  inline QAction* copyAction() const
-  {
-    return m_copy;
-  }
-  /// Paste action for this editor
-  inline QAction* pasteAction() const
-  {
-    return m_paste;
-  }
-
-  /// Zoom in action for this editor
-  inline QAction* zoomInAction() const
-  {
-    return m_zoomIn;
-  }
-  /// Zoom out action for this editor
-  inline QAction* zoomOutAction() const
-  {
-    return m_zoomOut;
-  }
 
   /// Override so that ctrl + mouse wheel will zoom in and out
   void wheelEvent( QWheelEvent * e );
 
-  /// Print action for this editor
-  inline QAction* printAction() const
-  {
-    return m_print;
-  } 
   /// Return a pointer to the object responsible for code completion
   inline QsciAPIs * scintillaAPI() const
   {
@@ -196,6 +159,13 @@ public:
   }
   
 public slots:
+  /// Save the script, opening a dialog
+  void saveAs();
+  /// Save to the current filename, opening a dialog if blank
+  void saveToCurrentFile();
+  /// Save a the text to the given filename
+  bool saveScript(const QString & filename);
+
   /// Update the editor
   void update();
   /// Set the marker state
@@ -232,6 +202,9 @@ signals:
   void executeMultiLine();
 
 private:
+  /// Create actions
+  void initActions();
+
   /// Settings group
   QString settingsGroup() const;
   /// Read settings from persistent store
@@ -263,6 +236,8 @@ private:
   /// The file name associated with this editor
   QString m_filename;
 
+  /// Saving actions
+  QAction *m_save, *m_saveAs;
   /// Each editor needs its own undo/redo etc
   QAction *m_undo, *m_redo, *m_cut, *m_copy, *m_paste, *m_print;
   /// Zoom in/out actions
diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/ScriptEditor.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/ScriptEditor.cpp
index 697cbefaa3d219e717e7c3740e12fb2fe018e089..2c14f003e6fde969739b4582ccce601c859cc8be 100644
--- a/Code/Mantid/MantidQt/MantidWidgets/src/ScriptEditor.cpp
+++ b/Code/Mantid/MantidQt/MantidWidgets/src/ScriptEditor.cpp
@@ -6,9 +6,13 @@
 // Qt
 #include <QApplication>
 #include <QFile>
+#include <QFileInfo>
+#include <QFileDialog>
+
 #include <QTextStream>
 #include <QMessageBox>
 #include <QAction>
+#include <QMenu>
 #include <QPrintDialog>
 #include <QPrinter>
 #include <QKeyEvent>
@@ -126,50 +130,7 @@ ScriptEditor::ScriptEditor(QWidget *parent, bool interpreter_mode, QsciLexer *co
   m_compiled(false),
   m_zoomLevel(0)
 {
-  // Undo action
-  m_undo = new QAction(tr("&Undo"), this);
-  m_undo->setShortcut(tr("Ctrl+Z"));
-  connect(m_undo, SIGNAL(activated()), this, SLOT(undo()));
-  connect(this, SIGNAL(undoAvailable(bool)), m_undo, SLOT(setEnabled(bool)));
-  // Redo action
-  m_redo = new QAction(tr("&Redo"), this);
-  m_redo->setShortcut(tr("Ctrl+Y"));
-  connect(m_redo, SIGNAL(activated()), this, SLOT(redo()));
-  connect(this, SIGNAL(redoAvailable(bool)), m_redo, SLOT(setEnabled(bool)));
-
-  //Cut
-  m_cut = new QAction(tr("C&ut"), this);
-  m_cut->setShortcut(tr("Ctrl+X"));
-  connect(m_cut, SIGNAL(activated()), this, SLOT(cut()));
-  connect(this, SIGNAL(copyAvailable(bool)), m_cut, SLOT(setEnabled(bool)));
-
-  //Copy
-  m_copy = new QAction(tr("&Copy"), this);
-  m_copy->setShortcut(tr("Ctrl+C"));
-  connect(m_copy, SIGNAL(activated()), this, SLOT(copy()));
-  connect(this, SIGNAL(copyAvailable(bool)), m_copy, SLOT(setEnabled(bool)));
-
-  //Paste
-  m_paste = new QAction(tr("&Paste"), this);
-  m_paste->setShortcut(tr("Ctrl+V"));
-  connect(m_paste, SIGNAL(activated()), this, SLOT(paste()));
-
-  //Print
-  m_print = new QAction(tr("&Print script"), this);
-  m_print->setShortcut(tr("Ctrl+P"));
-  connect(m_print, SIGNAL(activated()), this, SLOT(print()));
-
-  m_zoomIn = new QAction(("Increase font size"), this);
-  // Setting two shortcuts makes it work for both the plus on the keypad and one above an =
-  // Despite the Qt docs advertising the use of QKeySequence::ZoomIn as the solution to this,
-  // it doesn't seem to work for me
-  m_zoomIn->setShortcut(Qt::SHIFT+Qt::CTRL+Qt::Key_Equal);
-  m_zoomIn->setShortcut(Qt::CTRL+Qt::Key_Plus);
-  connect(m_zoomIn, SIGNAL(activated()),this,SLOT(zoomIn()));
-
-  m_zoomOut = new QAction(("Decrease font size"), this);
-  m_zoomOut->setShortcut(QKeySequence::ZoomOut);
-  connect(m_zoomOut, SIGNAL(activated()),this,SLOT(zoomOut()));
+  initActions();
 
   //Syntax highlighting and code completion
   setLexer(codelexer);
@@ -223,7 +184,7 @@ ScriptEditor::ScriptEditor(QWidget *parent, bool interpreter_mode, QsciLexer *co
     //Update the editor
     update();
   }
-  
+  setFocusPolicy(Qt::StrongFocus);
 }
 
 /**
@@ -242,6 +203,33 @@ ScriptEditor::~ScriptEditor()
   }
 }
 
+/**
+ * Add actions applicable to file menu
+ * @param fileMenu
+ */
+void ScriptEditor::populateFileMenu(QMenu &fileMenu)
+{
+  fileMenu.addAction(m_save);
+  fileMenu.addAction(m_saveAs);
+  fileMenu.addAction(m_print);
+}
+/**
+ * Add actions applicable to an edit menu
+ * @param editMenu
+ */
+void ScriptEditor::populateEditMenu(QMenu &editMenu)
+{
+  editMenu.addAction(m_undo);
+  editMenu.addAction(m_redo);
+  editMenu.addAction(m_cut);
+  editMenu.addAction(m_copy);
+  editMenu.addAction(m_paste);
+
+//  editMenu.insertSeparator();
+//  editMenu.addAction(m_find);
+}
+
+
 /**
  * Set a new code lexer for this object. Note that this clears all auto complete information
  */
@@ -288,22 +276,51 @@ QSize ScriptEditor::sizeHint() const
   }
 }
 
+/**
+ * Save the script, opening a dialog to ask for the filename
+ */
+void ScriptEditor::saveAs()
+{
+  QString selectedFilter;
+  QString filter = "Scripts (*.py *.PY);;All Files (*)";
+  QString filename = QFileDialog::getSaveFileName(NULL, "MantidPlot - Save", "",filter, &selectedFilter);
+
+  if( filename.isEmpty() ) return;
+  if( QFileInfo(filename).suffix().isEmpty() )
+  {
+    QString ext = selectedFilter.section('(',1).section(' ', 0, 0);
+    ext.remove(0,1);
+    if( ext != ")" ) filename += ext;
+  }
+  saveScript(filename);
+}
+
+/// Save to the current filename, opening a dialog if blank
+void ScriptEditor::saveToCurrentFile()
+{
+  QString filename = fileName();
+  if(filename.isEmpty())
+  {
+    saveAs();
+    return;
+  }
+  else
+  {
+    saveScript(filename);
+  }
+}
+
 /**
  * Save the text to the given filename
  * @param filename :: The filename to use
  */
 bool ScriptEditor::saveScript(const QString & filename)
 {
-  if( filename.isEmpty() )
-  {
-    return false;
-  }
-  
   QFile file(filename);
   if( !file.open(QIODevice::WriteOnly) )
   {
     QMessageBox::critical(this, tr("MantidPlot - File error"), 
-			  tr("Could not open file \"%1\" for writing.").arg(filename));
+        tr("Could not open file \"%1\" for writing.").arg(filename));
     return false;
   }
 
@@ -314,6 +331,8 @@ bool ScriptEditor::saveScript(const QString & filename)
   QApplication::restoreOverrideCursor();
   file.close();
 
+  setModified(false);
+
   return true;
 }
 
@@ -771,6 +790,60 @@ void ScriptEditor::zoomOut(int level)
 //------------------------------------------------
 // Private member functions
 //------------------------------------------------
+/**
+ * Create actions
+ */
+void ScriptEditor::initActions()
+{
+  m_save = new QAction(tr("&Save"), this);
+  m_save->setShortcut(tr("Ctrl+S"));
+  connect(m_save, SIGNAL(activated()), this , SLOT(saveToCurrentFile()));
+  //Save a script under a new file name
+  m_saveAs = new QAction(tr("&Save As"), this);
+  connect(m_saveAs, SIGNAL(activated()), this , SLOT(saveAs()));
+  m_saveAs->setShortcut(tr("Ctrl+Shift+S"));
+
+  m_undo = new QAction(tr("&Undo"), this);
+  m_undo->setShortcut(tr("Ctrl+Z"));
+  connect(m_undo, SIGNAL(activated()), this, SLOT(undo()));
+  connect(this, SIGNAL(undoAvailable(bool)), m_undo, SLOT(setEnabled(bool)));
+
+  m_redo = new QAction(tr("&Redo"), this);
+  m_redo->setShortcut(tr("Ctrl+Y"));
+  connect(m_redo, SIGNAL(activated()), this, SLOT(redo()));
+  connect(this, SIGNAL(redoAvailable(bool)), m_redo, SLOT(setEnabled(bool)));
+
+  m_cut = new QAction(tr("C&ut"), this);
+  m_cut->setShortcut(tr("Ctrl+X"));
+  connect(m_cut, SIGNAL(activated()), this, SLOT(cut()));
+  connect(this, SIGNAL(copyAvailable(bool)), m_cut, SLOT(setEnabled(bool)));
+
+  m_copy = new QAction(tr("&Copy"), this);
+  m_copy->setShortcut(tr("Ctrl+C"));
+  connect(m_copy, SIGNAL(activated()), this, SLOT(copy()));
+  connect(this, SIGNAL(copyAvailable(bool)), m_copy, SLOT(setEnabled(bool)));
+
+  m_paste = new QAction(tr("&Paste"), this);
+  m_paste->setShortcut(tr("Ctrl+V"));
+  connect(m_paste, SIGNAL(activated()), this, SLOT(paste()));
+
+  m_print = new QAction(tr("&Print script"), this);
+  m_print->setShortcut(tr("Ctrl+P"));
+  connect(m_print, SIGNAL(activated()), this, SLOT(print()));
+
+  m_zoomIn = new QAction(("Increase font size"), this);
+  // Setting two shortcuts makes it work for both the plus on the keypad and one above an =
+  // Despite the Qt docs advertising the use of QKeySequence::ZoomIn as the solution to this,
+  // it doesn't seem to work for me
+  m_zoomIn->setShortcut(Qt::SHIFT+Qt::CTRL+Qt::Key_Equal);
+  m_zoomIn->setShortcut(Qt::CTRL+Qt::Key_Plus);
+  connect(m_zoomIn, SIGNAL(activated()),this,SLOT(zoomIn()));
+
+  m_zoomOut = new QAction(("Decrease font size"), this);
+  m_zoomOut->setShortcut(QKeySequence::ZoomOut);
+  connect(m_zoomOut, SIGNAL(activated()),this,SLOT(zoomOut()));
+
+}
 
 /// Settings group
 /**
@@ -812,13 +885,6 @@ void ScriptEditor::writeSettings()
 void ScriptEditor::executeCodeAtLine(int lineno)
 {
   QString cmd = text(lineno).remove('\r').remove('\n');
-  // I was seeing strange behaviour with the first line marker disappearing after
-  // entering some text, removing it and retyping then pressing enter
-  if( cmd.isEmpty() )
-  {
-    return;
-  }
-
   m_history.add(cmd);
   if( lineno == 0 ) markerAdd(lineno, m_marker_handle); 
   m_need_newline = true;
@@ -828,7 +894,7 @@ void ScriptEditor::executeCodeAtLine(int lineno)
 /**
   *compiles multi line code and if end of multi line executes the code
   *@param line :: number of line
-  *@param multiCmd :: text to inpterpret
+  *@param multiCmd :: text to interpret
 */
 void ScriptEditor::interpretMultiLineCode(const int line,const QString & multiCmd)
 {