diff --git a/IPython/frontend/_process/__init__.py b/IPython/frontend/_process/__init__.py
new file mode 100644
index 0000000..af9be72
--- /dev/null
+++ b/IPython/frontend/_process/__init__.py
@@ -0,0 +1,19 @@
+"""
+Package for dealing for process execution in a callback environment, in a
+portable way.
+
+killable_process.py is a wrapper of subprocess.Popen that allows the
+subprocess and its children to be killed in a reliable way, including
+under windows.
+
+winprocess.py is required by killable_process.py to kill processes under
+windows.
+
+piped_process.py wraps process execution with callbacks to print output,
+in a non-blocking way. It can be used to interact with a subprocess in eg
+a GUI event loop.
+"""
+
+from pipedprocess import PipedProcess
+
+
diff --git a/IPython/frontend/killable_process.py b/IPython/frontend/_process/killableprocess.py
similarity index 100%
rename from IPython/frontend/killable_process.py
rename to IPython/frontend/_process/killableprocess.py
diff --git a/IPython/frontend/piped_process.py b/IPython/frontend/_process/pipedprocess.py
similarity index 97%
rename from IPython/frontend/piped_process.py
rename to IPython/frontend/_process/pipedprocess.py
index 5339fdd..ee60ab4 100644
--- a/IPython/frontend/piped_process.py
+++ b/IPython/frontend/_process/pipedprocess.py
@@ -15,7 +15,7 @@ __docformat__ = "restructuredtext en"
 #-------------------------------------------------------------------------------
 # Imports
 #-------------------------------------------------------------------------------
-from killable_process import Popen, PIPE
+from killableprocess import Popen, PIPE
 from threading import Thread
 from time import sleep
 
diff --git a/IPython/frontend/winprocess.py b/IPython/frontend/_process/winprocess.py
similarity index 100%
rename from IPython/frontend/winprocess.py
rename to IPython/frontend/_process/winprocess.py
diff --git a/IPython/frontend/asyncfrontendbase.py b/IPython/frontend/asyncfrontendbase.py
index c3614b7..3662351 100644
--- a/IPython/frontend/asyncfrontendbase.py
+++ b/IPython/frontend/asyncfrontendbase.py
@@ -18,14 +18,11 @@ import uuid
 
 try:
     from zope.interface import Interface, Attribute, implements, classProvides
-except ImportError:
-    #zope.interface is not available
-    Interface = object
-    def Attribute(name, doc): pass
-    def implements(interface): pass
-    def classProvides(interface): pass
-
-
+except ImportError, e:
+    e.message = """%s
+________________________________________________________________________________
+zope.interface is required to run asynchronous frontends.""" % e.message
+    e.args = (e.message, ) + e.args[1:]
 
 from frontendbase import FrontEndBase, IFrontEnd, IFrontEndFactory
 
@@ -34,9 +31,11 @@ from IPython.kernel.core.history import FrontEndHistory
 
 try:
     from twisted.python.failure import Failure
-except ImportError:
-    #Twisted not available
-    Failure = Exception
+except ImportError, e:
+    e.message = """%s
+________________________________________________________________________________
+twisted is required to run asynchronous frontends.""" % e.message
+    e.args = (e.message, ) + e.args[1:]
 
 
 
diff --git a/IPython/frontend/frontendbase.py b/IPython/frontend/frontendbase.py
index 9d0ecfa..4fa4ad8 100644
--- a/IPython/frontend/frontendbase.py
+++ b/IPython/frontend/frontendbase.py
@@ -24,14 +24,7 @@ import string
 import uuid
 import _ast
 
-try:
-    from zope.interface import Interface, Attribute, implements, classProvides
-except ImportError:
-    #zope.interface is not available
-    Interface = object
-    def Attribute(name, doc): pass
-    def implements(interface): pass
-    def classProvides(interface): pass
+from zopeinterface import Interface, Attribute, implements, classProvides
 
 from IPython.kernel.core.history import FrontEndHistory
 from IPython.kernel.core.util import Bunch
@@ -46,6 +39,8 @@ rc.prompt_in2 = r'...'
 rc.prompt_out = r'Out [$number]:  '
 
 ##############################################################################
+# Interface definitions
+##############################################################################
 
 class IFrontEndFactory(Interface):
     """Factory interface for frontends."""
@@ -59,7 +54,6 @@ class IFrontEndFactory(Interface):
         pass
 
 
-
 class IFrontEnd(Interface):
     """Interface for frontends. All methods return t.i.d.Deferred"""
     
@@ -72,9 +66,10 @@ class IFrontEnd(Interface):
     
     def update_cell_prompt(result, blockID=None):
         """Subclass may override to update the input prompt for a block. 
-        Since this method will be called as a 
-        twisted.internet.defer.Deferred's callback/errback,
-        implementations should return result when finished.
+
+        In asynchronous frontends, this method will be called as a
+        twisted.internet.defer.Deferred's callback/errback.
+        Implementations should thus return result when finished.
         
         Result is a result dict in case of success, and a
         twisted.python.util.failure.Failure in case of an error
@@ -82,7 +77,6 @@ class IFrontEnd(Interface):
         
         pass
     
-    
     def render_result(result):
         """Render the result of an execute call. Implementors may choose the
          method of rendering.
@@ -100,16 +94,17 @@ class IFrontEnd(Interface):
         pass
     
     def render_error(failure):
-        """Subclasses must override to render the failure. Since this method 
-        will be called as a twisted.internet.defer.Deferred's callback, 
-        implementations should return result when finished.
+        """Subclasses must override to render the failure. 
+        
+        In asynchronous frontend, since this method will be called as a
+        twisted.internet.defer.Deferred's callback. Implementations
+        should thus return result when finished.
         
         blockID = failure.blockID
         """
         
         pass
     
-    
     def input_prompt(number=''):
         """Returns the input prompt by subsituting into 
         self.input_prompt_template
@@ -140,7 +135,6 @@ class IFrontEnd(Interface):
         
         pass
     
-    
     def get_history_previous(current_block):
         """Returns the block previous in  the history. Saves currentBlock if
         the history_cursor is currently at the end of the input history"""
@@ -151,6 +145,20 @@ class IFrontEnd(Interface):
         
         pass
     
+    def complete(self, line):
+        """Returns the list of possible completions, and the completed
+            line.
+
+        The input argument is the full line to be completed. This method
+        returns both the line completed as much as possible, and the list
+        of further possible completions (full words).
+        """
+        pass
+
+
+##############################################################################
+# Base class for all the frontends. 
+##############################################################################
 
 class FrontEndBase(object):
     """
@@ -321,6 +329,8 @@ class FrontEndBase(object):
     
     def update_cell_prompt(self, result, blockID=None):
         """Subclass may override to update the input prompt for a block. 
+
+        This method only really makes sens in asyncrhonous frontend.
         Since this method will be called as a 
         twisted.internet.defer.Deferred's callback, implementations should 
         return result when finished.
@@ -330,18 +340,22 @@ class FrontEndBase(object):
     
     
     def render_result(self, result):
-        """Subclasses must override to render result. Since this method will
-        be called as a twisted.internet.defer.Deferred's callback, 
-        implementations should return result when finished.
+        """Subclasses must override to render result. 
+        
+        In asynchronous frontends, this method will be called as a
+        twisted.internet.defer.Deferred's callback. Implementations
+        should thus return result when finished.
         """
         
         return result
     
     
     def render_error(self, failure):
-        """Subclasses must override to render the failure. Since this method 
-        will be called as a twisted.internet.defer.Deferred's callback, 
-        implementations should return result when finished.
+        """Subclasses must override to render the failure. 
+        
+        In asynchronous frontends, this method will be called as a
+        twisted.internet.defer.Deferred's callback. Implementations
+        should thus return result when finished.
         """
         
         return failure
diff --git a/IPython/frontend/linefrontendbase.py b/IPython/frontend/linefrontendbase.py
index b89d46d..e9d76cd 100644
--- a/IPython/frontend/linefrontendbase.py
+++ b/IPython/frontend/linefrontendbase.py
@@ -1,5 +1,6 @@
 """
-Base front end class for all line-oriented frontends.
+Base front end class for all line-oriented frontends, rather than
+block-oriented.
 
 Currently this focuses on synchronous frontends.
 """
@@ -23,6 +24,9 @@ from frontendbase import FrontEndBase
 from IPython.kernel.core.interpreter import Interpreter
 
 def common_prefix(strings):
+    """ Given a list of strings, return the common prefix between all
+        these strings.
+    """
     ref = strings[0]
     prefix = ''
     for size in range(len(ref)):
@@ -38,6 +42,10 @@ def common_prefix(strings):
 # Base class for the line-oriented front ends
 #-------------------------------------------------------------------------------
 class LineFrontEndBase(FrontEndBase):
+    """ Concrete implementation of the FrontEndBase class. This is meant
+    to be the base class behind all the frontend that are line-oriented,
+    rather than block-oriented.
+    """
     
     # We need to keep the prompt number, to be able to increment
     # it when there is an exception.
@@ -47,7 +55,7 @@ class LineFrontEndBase(FrontEndBase):
     last_result = dict(number=0)
 
     #--------------------------------------------------------------------------
-    # Public API
+    # FrontEndBase interface
     #--------------------------------------------------------------------------
 
     def __init__(self, shell=None, history=None):
@@ -81,6 +89,9 @@ class LineFrontEndBase(FrontEndBase):
  
 
     def render_result(self, result):
+        """ Frontend-specific rendering of the result of a calculation
+        that has been sent to an engine.
+        """
         if 'stdout' in result and result['stdout']:
             self.write('\n' + result['stdout'])
         if 'display' in result and result['display']:
@@ -91,20 +102,25 @@ class LineFrontEndBase(FrontEndBase):
        
 
     def render_error(self, failure):
+        """ Frontend-specific rendering of error. 
+        """
         self.insert_text('\n\n'+str(failure)+'\n\n')
         return failure
 
 
-    def prefilter_input(self, string):
-        string = string.replace('\r\n', '\n')
-        string = string.replace('\t', 4*' ')
-        # Clean the trailing whitespace
-        string = '\n'.join(l.rstrip()  for l in string.split('\n'))
-        return string
-
-
     def is_complete(self, string):
+        """ Check if a string forms a complete, executable set of
+        commands.
+
+        For the line-oriented frontend, multi-line code is not executed
+        as soon as it is complete: the users has to enter two line
+        returns.
+        """
         if string in ('', '\n'):
+            # Prefiltering, eg through ipython0, may return an empty
+            # string although some operations have been accomplished. We
+            # thus want to consider an empty string as a complete
+            # statement.
             return True
         elif ( len(self.get_current_edit_buffer().split('\n'))>2 
                         and not re.findall(r"\n[\t ]*\n[\t ]*$", string)):
@@ -116,8 +132,8 @@ class LineFrontEndBase(FrontEndBase):
     
 
     def execute(self, python_string, raw_string=None):
-        """ Send the python_string to the interpreter, stores the
-            raw_string in the history and starts a new prompt.
+        """ Stores the raw_string in the history, and sends the
+        python string to the interpreter.
         """
         if raw_string is None:
             raw_string = python_string
@@ -133,6 +149,18 @@ class LineFrontEndBase(FrontEndBase):
         finally:
             self.after_execute()
 
+    #--------------------------------------------------------------------------
+    # LineFrontEndBase interface
+    #--------------------------------------------------------------------------
+
+    def prefilter_input(self, string):
+        """ Priflter the input to turn it in valid python.
+        """
+        string = string.replace('\r\n', '\n')
+        string = string.replace('\t', 4*' ')
+        # Clean the trailing whitespace
+        string = '\n'.join(l.rstrip()  for l in string.split('\n'))
+        return string
 
     def after_execute(self):
         """ All the operations required after an execution to put the
@@ -145,6 +173,10 @@ class LineFrontEndBase(FrontEndBase):
         self.history_cursor = len(self.history.input_cache) - 1
 
 
+    #--------------------------------------------------------------------------
+    # Private API
+    #--------------------------------------------------------------------------
+ 
     def _on_enter(self):
         """ Called when the return key is pressed in a line editing
             buffer.
@@ -160,11 +192,10 @@ class LineFrontEndBase(FrontEndBase):
                 self.write('\t')
 
 
-    #--------------------------------------------------------------------------
-    # Private API
-    #--------------------------------------------------------------------------
- 
     def _get_indent_string(self, string):
+        """ Return the string of whitespace that prefixes a line. Used to
+        add the right amount of indendation when creating a new line.
+        """
         string = string.replace('\t', ' '*4)
         string = string.split('\n')[-1]
         indent_chars = len(string) - len(string.lstrip())
diff --git a/IPython/frontend/prefilterfrontend.py b/IPython/frontend/prefilterfrontend.py
index d22bb40..f84c4c0 100644
--- a/IPython/frontend/prefilterfrontend.py
+++ b/IPython/frontend/prefilterfrontend.py
@@ -2,6 +2,12 @@
 Frontend class that uses IPython0 to prefilter the inputs.
 
 Using the IPython0 mechanism gives us access to the magics.
+
+This is a transitory class, used here to do the transition between
+ipython0 and ipython1. This class is meant to be short-lived as more
+functionnality is abstracted out of ipython0 in reusable functions and
+is added on the interpreter. This class can be a used to guide this
+refactoring.
 """
 __docformat__ = "restructuredtext en"
 
@@ -27,6 +33,8 @@ from IPython.kernel.core.sync_traceback_trap import SyncTracebackTrap
 
 from IPython.genutils import Term
 import pydoc
+import os
+
 
 def mk_system_call(system_call_function, command):
     """ given a os.system replacement, and a leading string command,
@@ -41,6 +49,14 @@ def mk_system_call(system_call_function, command):
 # Frontend class using ipython0 to do the prefiltering. 
 #-------------------------------------------------------------------------------
 class PrefilterFrontEnd(LineFrontEndBase):
+    """ Class that uses ipython0 to do prefilter the input, do the
+    completion and the magics.
+
+    The core trick is to use an ipython0 instance to prefilter the
+    input, and share the namespace between the interpreter instance used
+    to execute the statements and the ipython0 used for code
+    completion...
+    """
     
     def __init__(self, *args, **kwargs):
         LineFrontEndBase.__init__(self, *args, **kwargs)
@@ -67,38 +83,20 @@ class PrefilterFrontEnd(LineFrontEndBase):
                             err_callback=self.write,
                                             )
         self.shell.traceback_trap = SyncTracebackTrap(
-                        formatters=self.shell.traceback_trap.formatters
+                        formatters=self.shell.traceback_trap.formatters,
                             )
         # Capture and release the outputs, to make sure all the
         # shadow variables are set
         self.capture_output()
         self.release_output()
 
-    
-    def prefilter_input(self, input_string):
-        """ Using IPython0 to prefilter the commands.
-        """
-        input_string = LineFrontEndBase.prefilter_input(self, input_string)
-        filtered_lines = []
-        # The IPython0 prefilters sometime produce output. We need to
-        # capture it.
-        self.capture_output()
-        self.last_result = dict(number=self.prompt_number)
-        try:
-            for line in input_string.split('\n'):
-                filtered_lines.append(self.ipython0.prefilter(line, False))
-        except:
-            # XXX: probably not the right thing to do.
-            self.ipython0.showsyntaxerror()
-            self.after_execute()
-        finally:
-            self.release_output()
-
-        filtered_string = '\n'.join(filtered_lines)
-        return filtered_string
-
+    #--------------------------------------------------------------------------
+    # FrontEndBase interface 
+    #--------------------------------------------------------------------------
 
     def show_traceback(self):
+        """ Use ipython0 to capture the last traceback and display it.
+        """
         self.capture_output()
         self.ipython0.showtraceback()
         self.release_output()
@@ -111,13 +109,6 @@ class PrefilterFrontEnd(LineFrontEndBase):
         self.release_output()
 
 
-    def system_call(self, command):
-        """ Allows for frontend to define their own system call, to be
-            able capture output and redirect input.
-        """
-        return os.system(command, args)
-
-
     def capture_output(self):
         """ Capture all the output mechanisms we can think of.
         """
@@ -154,6 +145,45 @@ class PrefilterFrontEnd(LineFrontEndBase):
             line = line[:-len(word)] + prefix
         return line, completions 
  
+    
+    #--------------------------------------------------------------------------
+    # LineFrontEndBase interface 
+    #--------------------------------------------------------------------------
+
+    def prefilter_input(self, input_string):
+        """ Using IPython0 to prefilter the commands to turn them
+        in executable statements that are valid Python strings.
+        """
+        input_string = LineFrontEndBase.prefilter_input(self, input_string)
+        filtered_lines = []
+        # The IPython0 prefilters sometime produce output. We need to
+        # capture it.
+        self.capture_output()
+        self.last_result = dict(number=self.prompt_number)
+        try:
+            for line in input_string.split('\n'):
+                filtered_lines.append(self.ipython0.prefilter(line, False))
+        except:
+            # XXX: probably not the right thing to do.
+            self.ipython0.showsyntaxerror()
+            self.after_execute()
+        finally:
+            self.release_output()
+
+        filtered_string = '\n'.join(filtered_lines)
+        return filtered_string
+
+
+    #--------------------------------------------------------------------------
+    # PrefilterLineFrontEnd interface 
+    #--------------------------------------------------------------------------
+ 
+    def system_call(self, command_string):
+        """ Allows for frontend to define their own system call, to be
+            able capture output and redirect input.
+        """
+        return os.system(command_string)
+
 
     def do_exit(self):
         """ Exit the shell, cleanup and save the history.
diff --git a/IPython/frontend/wx/console_widget.py b/IPython/frontend/wx/console_widget.py
index da91206..1091658 100644
--- a/IPython/frontend/wx/console_widget.py
+++ b/IPython/frontend/wx/console_widget.py
@@ -76,6 +76,8 @@ class ConsoleWidget(editwindow.EditWindow):
         keeping the cursor inside the editing line.
     """
 
+    # This is where the title captured from the ANSI escape sequences are
+    # stored.
     title = 'Console'
 
     style = _DEFAULT_STYLE.copy()
@@ -102,7 +104,7 @@ class ConsoleWidget(editwindow.EditWindow):
     def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, 
                         size=wx.DefaultSize, style=0, ):
         editwindow.EditWindow.__init__(self, parent, id, pos, size, style)
-        self.configure_scintilla()
+        self._configure_scintilla()
 
         # FIXME: we need to retrieve this from the interpreter.
         self.prompt = \
@@ -113,87 +115,6 @@ class ConsoleWidget(editwindow.EditWindow):
         self.Bind(wx.EVT_KEY_UP, self._on_key_up)
     
 
-    def configure_scintilla(self):
-        self.SetEOLMode(stc.STC_EOL_LF)
-
-        # Ctrl"+" or Ctrl "-" can be used to zoomin/zoomout the text inside 
-        # the widget
-        self.CmdKeyAssign(ord('+'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
-        self.CmdKeyAssign(ord('-'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
-        # Also allow Ctrl Shift "=" for poor non US keyboard users. 
-        self.CmdKeyAssign(ord('='), stc.STC_SCMOD_CTRL|stc.STC_SCMOD_SHIFT, 
-                                            stc.STC_CMD_ZOOMIN)
-        
-        #self.CmdKeyAssign(stc.STC_KEY_PRIOR, stc.STC_SCMOD_SHIFT,
-        #                                    stc.STC_CMD_PAGEUP)
-
-        #self.CmdKeyAssign(stc.STC_KEY_NEXT, stc.STC_SCMOD_SHIFT,
-        #                                    stc.STC_CMD_PAGEDOWN)
-
-        # Keys: we need to clear some of the keys the that don't play
-        # well with a console.
-        self.CmdKeyClear(ord('D'), stc.STC_SCMOD_CTRL)
-        self.CmdKeyClear(ord('L'), stc.STC_SCMOD_CTRL)
-        self.CmdKeyClear(ord('T'), stc.STC_SCMOD_CTRL)
-
-
-        self.SetEOLMode(stc.STC_EOL_CRLF)
-        self.SetWrapMode(stc.STC_WRAP_CHAR)
-        self.SetWrapMode(stc.STC_WRAP_WORD)
-        self.SetBufferedDraw(True)
-        self.SetUseAntiAliasing(True)
-        self.SetLayoutCache(stc.STC_CACHE_PAGE)
-        self.SetUndoCollection(False)
-        self.SetUseTabs(True)
-        self.SetIndent(4)
-        self.SetTabWidth(4)
-
-        self.EnsureCaretVisible()
-        # we don't want scintilla's autocompletion to choose 
-        # automaticaly out of a single choice list, as we pop it up
-        # automaticaly
-        self.AutoCompSetChooseSingle(False)
-        self.AutoCompSetMaxHeight(10)
-
-        self.SetMargins(3, 3) #text is moved away from border with 3px
-        # Suppressing Scintilla margins
-        self.SetMarginWidth(0, 0)
-        self.SetMarginWidth(1, 0)
-        self.SetMarginWidth(2, 0)
-
-        self._apply_style()
-
-        # Xterm escape sequences
-        self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?')
-        self.title_pat = re.compile('\x1b]0;(.*?)\x07')
-
-        #self.SetEdgeMode(stc.STC_EDGE_LINE)
-        #self.SetEdgeColumn(80)
-
-        # styles
-        p = self.style
-        self.StyleSetSpec(stc.STC_STYLE_DEFAULT, p['default'])
-        self.StyleClearAll()
-        self.StyleSetSpec(_STDOUT_STYLE, p['stdout'])
-        self.StyleSetSpec(_STDERR_STYLE, p['stderr'])
-        self.StyleSetSpec(_TRACE_STYLE, p['trace'])
-
-        self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT, p['bracegood'])
-        self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, p['bracebad'])
-        self.StyleSetSpec(stc.STC_P_COMMENTLINE, p['comment'])
-        self.StyleSetSpec(stc.STC_P_NUMBER, p['number'])
-        self.StyleSetSpec(stc.STC_P_STRING, p['string'])
-        self.StyleSetSpec(stc.STC_P_CHARACTER, p['char'])
-        self.StyleSetSpec(stc.STC_P_WORD, p['keyword'])
-        self.StyleSetSpec(stc.STC_P_WORD2, p['keyword'])
-        self.StyleSetSpec(stc.STC_P_TRIPLE, p['triple'])
-        self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE, p['tripledouble'])
-        self.StyleSetSpec(stc.STC_P_CLASSNAME, p['class'])
-        self.StyleSetSpec(stc.STC_P_DEFNAME, p['def'])
-        self.StyleSetSpec(stc.STC_P_OPERATOR, p['operator'])
-        self.StyleSetSpec(stc.STC_P_COMMENTBLOCK, p['comment'])
-
-
     def write(self, text, refresh=True):
         """ Write given text to buffer, while translating the ansi escape
             sequences.
@@ -270,24 +191,20 @@ class ConsoleWidget(editwindow.EditWindow):
         return current_edit_buffer
 
 
-    #--------------------------------------------------------------------------
-    # Private API
-    #--------------------------------------------------------------------------
-    
-    def _apply_style(self):
-        """ Applies the colors for the different text elements and the
-            carret.
-        """
-        self.SetCaretForeground(self.carret_color)
+    def scroll_to_bottom(self):
+        maxrange = self.GetScrollRange(wx.VERTICAL)
+        self.ScrollLines(maxrange)
 
-        #self.StyleClearAll()
-        self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,  
-                          "fore:#FF0000,back:#0000FF,bold")
-        self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
-                          "fore:#000000,back:#FF0000,bold")
 
-        for style in self.ANSI_STYLES.values():
-            self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
+    def pop_completion(self, possibilities, offset=0):
+        """ Pops up an autocompletion menu. Offset is the offset
+            in characters of the position at which the menu should
+            appear, relativ to the cursor.
+        """
+        self.AutoCompSetIgnoreCase(False)
+        self.AutoCompSetAutoHide(False)
+        self.AutoCompSetMaxHeight(len(possibilities))
+        self.AutoCompShow(offset, " ".join(possibilities))
 
 
     def write_completion(self, possibilities):
@@ -315,21 +232,105 @@ class ConsoleWidget(editwindow.EditWindow):
         self.new_prompt(self.prompt % (self.last_result['number'] + 1))
         self.replace_current_edit_buffer(current_buffer)
 
-
-    def pop_completion(self, possibilities, offset=0):
-        """ Pops up an autocompletion menu. Offset is the offset
-            in characters of the position at which the menu should
-            appear, relativ to the cursor.
+    #--------------------------------------------------------------------------
+    # Private API
+    #--------------------------------------------------------------------------
+    
+    def _apply_style(self):
+        """ Applies the colors for the different text elements and the
+            carret.
         """
-        self.AutoCompSetIgnoreCase(False)
-        self.AutoCompSetAutoHide(False)
-        self.AutoCompSetMaxHeight(len(possibilities))
-        self.AutoCompShow(offset, " ".join(possibilities))
+        self.SetCaretForeground(self.carret_color)
 
-    
-    def scroll_to_bottom(self):
-        maxrange = self.GetScrollRange(wx.VERTICAL)
-        self.ScrollLines(maxrange)
+        #self.StyleClearAll()
+        self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,  
+                          "fore:#FF0000,back:#0000FF,bold")
+        self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
+                          "fore:#000000,back:#FF0000,bold")
+
+        for style in self.ANSI_STYLES.values():
+            self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
+
+   
+    def _configure_scintilla(self):
+        self.SetEOLMode(stc.STC_EOL_LF)
+
+        # Ctrl"+" or Ctrl "-" can be used to zoomin/zoomout the text inside 
+        # the widget
+        self.CmdKeyAssign(ord('+'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
+        self.CmdKeyAssign(ord('-'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
+        # Also allow Ctrl Shift "=" for poor non US keyboard users. 
+        self.CmdKeyAssign(ord('='), stc.STC_SCMOD_CTRL|stc.STC_SCMOD_SHIFT, 
+                                            stc.STC_CMD_ZOOMIN)
+        
+        #self.CmdKeyAssign(stc.STC_KEY_PRIOR, stc.STC_SCMOD_SHIFT,
+        #                                    stc.STC_CMD_PAGEUP)
+
+        #self.CmdKeyAssign(stc.STC_KEY_NEXT, stc.STC_SCMOD_SHIFT,
+        #                                    stc.STC_CMD_PAGEDOWN)
+
+        # Keys: we need to clear some of the keys the that don't play
+        # well with a console.
+        self.CmdKeyClear(ord('D'), stc.STC_SCMOD_CTRL)
+        self.CmdKeyClear(ord('L'), stc.STC_SCMOD_CTRL)
+        self.CmdKeyClear(ord('T'), stc.STC_SCMOD_CTRL)
+
+
+        self.SetEOLMode(stc.STC_EOL_CRLF)
+        self.SetWrapMode(stc.STC_WRAP_CHAR)
+        self.SetWrapMode(stc.STC_WRAP_WORD)
+        self.SetBufferedDraw(True)
+        self.SetUseAntiAliasing(True)
+        self.SetLayoutCache(stc.STC_CACHE_PAGE)
+        self.SetUndoCollection(False)
+        self.SetUseTabs(True)
+        self.SetIndent(4)
+        self.SetTabWidth(4)
+
+        self.EnsureCaretVisible()
+        # we don't want scintilla's autocompletion to choose 
+        # automaticaly out of a single choice list, as we pop it up
+        # automaticaly
+        self.AutoCompSetChooseSingle(False)
+        self.AutoCompSetMaxHeight(10)
+
+        self.SetMargins(3, 3) #text is moved away from border with 3px
+        # Suppressing Scintilla margins
+        self.SetMarginWidth(0, 0)
+        self.SetMarginWidth(1, 0)
+        self.SetMarginWidth(2, 0)
+
+        self._apply_style()
+
+        # Xterm escape sequences
+        self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?')
+        self.title_pat = re.compile('\x1b]0;(.*?)\x07')
+
+        #self.SetEdgeMode(stc.STC_EDGE_LINE)
+        #self.SetEdgeColumn(80)
+
+        # styles
+        p = self.style
+        self.StyleSetSpec(stc.STC_STYLE_DEFAULT, p['default'])
+        self.StyleClearAll()
+        self.StyleSetSpec(_STDOUT_STYLE, p['stdout'])
+        self.StyleSetSpec(_STDERR_STYLE, p['stderr'])
+        self.StyleSetSpec(_TRACE_STYLE, p['trace'])
+
+        self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT, p['bracegood'])
+        self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, p['bracebad'])
+        self.StyleSetSpec(stc.STC_P_COMMENTLINE, p['comment'])
+        self.StyleSetSpec(stc.STC_P_NUMBER, p['number'])
+        self.StyleSetSpec(stc.STC_P_STRING, p['string'])
+        self.StyleSetSpec(stc.STC_P_CHARACTER, p['char'])
+        self.StyleSetSpec(stc.STC_P_WORD, p['keyword'])
+        self.StyleSetSpec(stc.STC_P_WORD2, p['keyword'])
+        self.StyleSetSpec(stc.STC_P_TRIPLE, p['triple'])
+        self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE, p['tripledouble'])
+        self.StyleSetSpec(stc.STC_P_CLASSNAME, p['class'])
+        self.StyleSetSpec(stc.STC_P_DEFNAME, p['def'])
+        self.StyleSetSpec(stc.STC_P_OPERATOR, p['operator'])
+        self.StyleSetSpec(stc.STC_P_COMMENTBLOCK, p['comment'])
 
 
     def _on_key_down(self, event, skip=True):
@@ -418,7 +419,6 @@ class ConsoleWidget(editwindow.EditWindow):
 
 
 
-
 if __name__ == '__main__':
     # Some simple code to test the console widget.
     class MainWindow(wx.Frame):
diff --git a/IPython/frontend/wx/wx_frontend.py b/IPython/frontend/wx/wx_frontend.py
index 1ba94f1..6a5f377 100644
--- a/IPython/frontend/wx/wx_frontend.py
+++ b/IPython/frontend/wx/wx_frontend.py
@@ -5,6 +5,8 @@
 """Classes to provide a Wx frontend to the
 IPython.kernel.core.interpreter.
 
+This class inherits from ConsoleWidget, that provides a console-like
+widget to provide a text-rendering widget suitable for a terminal.
 """
 
 __docformat__ = "restructuredtext en"
@@ -20,21 +22,25 @@ __docformat__ = "restructuredtext en"
 # Imports
 #-------------------------------------------------------------------------------
 
-
-import wx
+# Major library imports
 import re
-from wx import stc
-from console_widget import ConsoleWidget
 import __builtin__
 from time import sleep
 import sys
-import signal
-
 from threading import Lock
 
-from IPython.frontend.piped_process import PipedProcess
+import wx
+from wx import stc
+
+# Ipython-specific imports.
+from IPython.frontend._process import PipedProcess
+from console_widget import ConsoleWidget
 from IPython.frontend.prefilterfrontend import PrefilterFrontEnd
 
+#-------------------------------------------------------------------------------
+# Constants 
+#-------------------------------------------------------------------------------
+
 #_COMMAND_BG = '#FAFAF1' # Nice green
 _RUNNING_BUFFER_BG = '#FDFFD3' # Nice yellow
 _ERROR_BG = '#FFF1F1' # Nice red
@@ -46,7 +52,14 @@ _ERROR_MARKER = 30
 # Classes to implement the Wx frontend
 #-------------------------------------------------------------------------------
 class WxController(PrefilterFrontEnd, ConsoleWidget):
+    """Classes to provide a Wx frontend to the
+    IPython.kernel.core.interpreter.
+
+    This class inherits from ConsoleWidget, that provides a console-like
+    widget to provide a text-rendering widget suitable for a terminal.
+    """
 
+    # FIXME: this shouldn't be there.
     output_prompt = \
     '\x01\x1b[0;31m\x02Out[\x01\x1b[1;31m\x02%i\x01\x1b[0;31m\x02]: \x01\x1b[0m\x02'
 
@@ -55,7 +68,6 @@ class WxController(PrefilterFrontEnd, ConsoleWidget):
 
     # The title of the terminal, as captured through the ANSI escape
     # sequences.
-
     def _set_title(self, title):
             return self.Parent.SetTitle(title)
 
@@ -114,8 +126,43 @@ class WxController(PrefilterFrontEnd, ConsoleWidget):
         self._buffer_flush_timer = wx.Timer(self, BUFFER_FLUSH_TIMER_ID)
         wx.EVT_TIMER(self, BUFFER_FLUSH_TIMER_ID, self._buffer_flush)
 
+
+    def raw_input(self, prompt):
+        """ A replacement from python's raw_input.
+        """
+        self.new_prompt(prompt)
+        self.waiting = True
+        self.__old_on_enter = self._on_enter
+        def my_on_enter():
+            self.waiting = False
+        self._on_enter = my_on_enter
+        # XXX: Busy waiting, ugly.
+        while self.waiting:
+            wx.Yield()
+            sleep(0.1)
+        self._on_enter = self.__old_on_enter
+        self._input_state = 'buffering'
+        return self.get_current_edit_buffer().rstrip('\n')
+
+
+    def system_call(self, command_string):
+        self._input_state = 'subprocess'
+        self._running_process = PipedProcess(command_string, 
+                    out_callback=self.buffered_write,
+                    end_callback = self._end_system_call)
+        self._running_process.start()
+        # XXX: another one of these polling loops to have a blocking
+        # call
+        wx.Yield()
+        while self._running_process:
+            wx.Yield()
+            sleep(0.1)
+        # Be sure to flush the buffer.
+        self._buffer_flush(event=None)
+
+
     def do_completion(self):
-        """ Do code completion. 
+        """ Do code completion on current line. 
         """
         if self.debug:
             print >>sys.__stdout__, "do_completion", 
@@ -129,6 +176,8 @@ class WxController(PrefilterFrontEnd, ConsoleWidget):
 
 
     def do_calltip(self):
+        """ Analyse current and displays useful calltip for it.
+        """
         if self.debug:
             print >>sys.__stdout__, "do_calltip" 
         separators =  re.compile('[\s\{\}\[\]\(\)\= ,:]')
@@ -154,12 +203,12 @@ class WxController(PrefilterFrontEnd, ConsoleWidget):
             pass
 
 
-    def popup_completion(self, create=False):
+    def _popup_completion(self, create=False):
         """ Updates the popup completion menu if it exists. If create is 
             true, open the menu.
         """
         if self.debug:
-            print >>sys.__stdout__, "popup_completion", 
+            print >>sys.__stdout__, "_popup_completion", 
         line = self.get_current_edit_buffer()
         if (self.AutoCompActive() and not line[-1] == '.') \
                     or create==True:
@@ -174,28 +223,23 @@ class WxController(PrefilterFrontEnd, ConsoleWidget):
                     print >>sys.__stdout__, completions 
 
 
-    def new_prompt(self, prompt):
-        self._input_state = 'readline'
-        ConsoleWidget.new_prompt(self, prompt)
-
+    def buffered_write(self, text):
+        """ A write method for streams, that caches the stream in order
+            to avoid flooding the event loop.
 
-    def raw_input(self, prompt):
-        """ A replacement from python's raw_input.
+            This can be called outside of the main loop, in separate
+            threads.
         """
-        self.new_prompt(prompt)
-        self.waiting = True
-        self.__old_on_enter = self._on_enter
-        def my_on_enter():
-            self.waiting = False
-        self._on_enter = my_on_enter
-        # XXX: Busy waiting, ugly.
-        while self.waiting:
-            wx.Yield()
-            sleep(0.1)
-        self._on_enter = self.__old_on_enter
-        self._input_state = 'buffering'
-        return self.get_current_edit_buffer().rstrip('\n')
-        
+        self._out_buffer_lock.acquire()
+        self._out_buffer.append(text)
+        self._out_buffer_lock.release()
+        if not self._buffer_flush_timer.IsRunning():
+            wx.CallAfter(self._buffer_flush_timer.Start, 100)  # milliseconds
+
+
+    #--------------------------------------------------------------------------
+    # LineFrontEnd interface 
+    #--------------------------------------------------------------------------
  
     def execute(self, python_string, raw_string=None):
         self._input_state = 'buffering'
@@ -226,39 +270,10 @@ class WxController(PrefilterFrontEnd, ConsoleWidget):
 
     def after_execute(self):
         PrefilterFrontEnd.after_execute(self)
+        # Clear the wait cursor
         if hasattr(self, '_cursor'):
             del self._cursor
 
-    
-    def system_call(self, command_string):
-        self._input_state = 'subprocess'
-        self._running_process = PipedProcess(command_string, 
-                    out_callback=self.buffered_write,
-                    end_callback = self._end_system_call)
-        self._running_process.start()
-        # XXX: another one of these polling loops to have a blocking
-        # call
-        wx.Yield()
-        while self._running_process:
-            wx.Yield()
-            sleep(0.1)
-        # Be sure to flush the buffer.
-        self._buffer_flush(event=None)
-
-
-    def buffered_write(self, text):
-        """ A write method for streams, that caches the stream in order
-            to avoid flooding the event loop.
-
-            This can be called outside of the main loop, in separate
-            threads.
-        """
-        self._out_buffer_lock.acquire()
-        self._out_buffer.append(text)
-        self._out_buffer_lock.release()
-        if not self._buffer_flush_timer.IsRunning():
-            wx.CallAfter(self._buffer_flush_timer.Start, 100)  # milliseconds
-
 
     def show_traceback(self):
         start_line = self.GetCurrentLine()
@@ -266,12 +281,19 @@ class WxController(PrefilterFrontEnd, ConsoleWidget):
         wx.Yield()
         for i in range(start_line, self.GetCurrentLine()):
             self.MarkerAdd(i, _ERROR_MARKER)
-            
 
+    
     #--------------------------------------------------------------------------
-    # Private API
+    # ConsoleWidget interface 
     #--------------------------------------------------------------------------
- 
+
+    def new_prompt(self, prompt):
+        """ Display a new prompt, and start a new input buffer.
+        """
+        self._input_state = 'readline'
+        ConsoleWidget.new_prompt(self, prompt)
+
+
     def _on_key_down(self, event, skip=True):
         """ Capture the character events, let the parent
             widget handle them, and put our logic afterward.
@@ -286,8 +308,8 @@ class WxController(PrefilterFrontEnd, ConsoleWidget):
                 self._running_process.process.kill()
             elif self._input_state == 'buffering':
                 if self.debug:
-                    print >>sys.__stderr__, 'Raising KeyboardException'
-                raise KeyboardException
+                    print >>sys.__stderr__, 'Raising KeyboardInterrupt'
+                raise KeyboardInterrupt
                 # XXX: We need to make really sure we
                 # get back to a prompt.
         elif self._input_state == 'subprocess' and (
@@ -315,10 +337,10 @@ class WxController(PrefilterFrontEnd, ConsoleWidget):
         elif self.AutoCompActive():
             event.Skip()
             if event.KeyCode in (wx.WXK_BACK, wx.WXK_DELETE): 
-                wx.CallAfter(self.popup_completion, create=True)
+                wx.CallAfter(self._popup_completion, create=True)
             elif not event.KeyCode in (wx.WXK_UP, wx.WXK_DOWN, wx.WXK_LEFT,
                             wx.WXK_RIGHT):
-                wx.CallAfter(self.popup_completion)
+                wx.CallAfter(self._popup_completion)
         else:
             # Up history
             if event.KeyCode == wx.WXK_UP and (
@@ -352,20 +374,28 @@ class WxController(PrefilterFrontEnd, ConsoleWidget):
 
 
     def _on_key_up(self, event, skip=True):
+        """ Called when any key is released.
+        """
         if event.KeyCode in (59, ord('.')):
             # Intercepting '.'
             event.Skip()
-            self.popup_completion(create=True)
+            self._popup_completion(create=True)
         else:
             ConsoleWidget._on_key_up(self, event, skip=skip)
 
 
     def _on_enter(self):
+        """ Called on return key down, in readline input_state.
+        """
         if self.debug:
             print >>sys.__stdout__, repr(self.get_current_edit_buffer())
         PrefilterFrontEnd._on_enter(self)
 
 
+    #--------------------------------------------------------------------------
+    # Private API
+    #--------------------------------------------------------------------------
+ 
     def _end_system_call(self):
         """ Called at the end of a system call.
         """
diff --git a/IPython/frontend/zopeinterface.py b/IPython/frontend/zopeinterface.py
new file mode 100644
index 0000000..fd37101
--- /dev/null
+++ b/IPython/frontend/zopeinterface.py
@@ -0,0 +1,34 @@
+# encoding: utf-8
+# -*- test-case-name: IPython.frontend.tests.test_frontendbase -*-
+"""
+zope.interface mock. If zope is installed, this module provides a zope
+interface classes, if not it provides mocks for them.
+
+Classes provided: 
+Interface, Attribute, implements, classProvides
+"""
+__docformat__ = "restructuredtext en"
+
+#-------------------------------------------------------------------------------
+#  Copyright (C) 2008  The IPython Development Team
+#
+#  Distributed under the terms of the BSD License.  The full license is in
+#  the file COPYING, distributed as part of this software.
+#-------------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------------
+# Imports
+#-------------------------------------------------------------------------------
+import string
+import uuid
+import _ast
+
+try:
+    from zope.interface import Interface, Attribute, implements, classProvides
+except ImportError:
+    #zope.interface is not available
+    Interface = object
+    def Attribute(name, doc): pass
+    def implements(interface): pass
+    def classProvides(interface): pass
+
diff --git a/IPython/kernel/core/sync_traceback_trap.py b/IPython/kernel/core/sync_traceback_trap.py
index 439d2b8..df9b0e5 100644
--- a/IPython/kernel/core/sync_traceback_trap.py
+++ b/IPython/kernel/core/sync_traceback_trap.py
@@ -22,19 +22,23 @@ from IPython.ultraTB import ColorTB
 
 class SyncTracebackTrap(TracebackTrap):
 
-    def __init__(self, sync_formatter=None, formatters=None):
+    def __init__(self, sync_formatter=None, formatters=None,
+                                                    raiseException=True):
         TracebackTrap.__init__(self, formatters=formatters)
         if sync_formatter is None:
             sync_formatter = ColorTB(color_scheme='LightBG')
         self.sync_formatter = sync_formatter
+        self.raiseException = raiseException
 
 
     def hook(self, *args):
         """ This method actually implements the hook.
         """
         self.args = args
-        
-        print self.sync_formatter(*self.args)
+        if not self.raiseException:
+            print self.sync_formatter(*self.args)
+        else:
+            raise