diff --git a/IPython/Extensions/ipy_autoreload.py b/IPython/Extensions/ipy_autoreload.py
index e64161d..230f575 100644
--- a/IPython/Extensions/ipy_autoreload.py
+++ b/IPython/Extensions/ipy_autoreload.py
@@ -1,7 +1,7 @@
 """
 IPython extension: autoreload modules before executing the next line
 
-Try:: 
+Try::
 
     %autoreload?
 
@@ -32,7 +32,7 @@ PY_COMPILED_EXT = _get_compiled_ext()
 class ModuleReloader(object):
     failed = {}
     """Modules that failed to reload: {module: mtime-on-failed-reload, ...}"""
-    
+
     modules = {}
     """Modules specially marked as autoreloadable."""
 
@@ -44,39 +44,39 @@ class ModuleReloader(object):
 
     old_objects = {}
     """(module-name, name) -> weakref, for replacing old code objects"""
-    
+
     def check(self, check_all=False):
         """Check whether some modules need to be reloaded."""
-        
+
         if check_all or self.check_all:
             modules = sys.modules.keys()
         else:
             modules = self.modules.keys()
-        
+
         for modname in modules:
             m = sys.modules.get(modname, None)
 
             if modname in self.skip_modules:
                 continue
-            
+
             if not hasattr(m, '__file__'):
                 continue
-            
+
             if m.__name__ == '__main__':
                 # we cannot reload(__main__)
                 continue
-            
+
             filename = m.__file__
             dirname = os.path.dirname(filename)
             path, ext = os.path.splitext(filename)
-            
+
             if ext.lower() == '.py':
                 ext = PY_COMPILED_EXT
                 filename = os.path.join(dirname, path + PY_COMPILED_EXT)
-            
+
             if ext != PY_COMPILED_EXT:
                 continue
-            
+
             try:
                 pymtime = os.stat(filename[:-1]).st_mtime
                 if pymtime <= os.stat(filename).st_mtime:
@@ -85,7 +85,7 @@ class ModuleReloader(object):
                     continue
             except OSError:
                 continue
-            
+
             try:
                 superreload(m, reload, self.old_objects)
                 if filename[:-1] in self.failed:
@@ -118,12 +118,12 @@ def update_class(old, new):
             new_obj = getattr(new, key)
         except AttributeError:
             # obsolete attribute: remove it
-            try: 
+            try:
                 delattr(old, key)
             except (AttributeError, TypeError):
                 pass
             continue
-        
+
         if update_generic(old_obj, new_obj): continue
 
         try:
@@ -146,9 +146,9 @@ UPDATE_RULES = [
     (lambda a, b: isinstance2(a, b, types.TypeType),
      update_class),
     (lambda a, b: isinstance2(a, b, types.FunctionType),
-     update_function), 
+     update_function),
     (lambda a, b: isinstance2(a, b, property),
-     update_property), 
+     update_property),
     (lambda a, b: isinstance2(a, b, types.MethodType),
      lambda a, b: update_function(a.im_func, b.im_func)),
 ]
@@ -168,15 +168,15 @@ class StrongRef(object):
 
 def superreload(module, reload=reload, old_objects={}):
     """Enhanced version of the builtin reload function.
-   
+
     superreload remembers objects previously in the module, and
 
     - upgrades the class dictionary of every old class in the module
     - upgrades the code object of every old function and method
     - clears the module's namespace before reloading
-    
+
     """
-    
+
     # collect old objects in the module
     for name, obj in module.__dict__.items():
         if not hasattr(obj, '__module__') or obj.__module__ != module.__name__:
@@ -199,7 +199,7 @@ def superreload(module, reload=reload, old_objects={}):
     except (TypeError, AttributeError, KeyError):
         pass
     module = reload(module)
-    
+
     # iterate over all objects and update functions & classes
     for name, new_obj in module.__dict__.items():
         key = (module.__name__, name)
@@ -248,40 +248,46 @@ def disable_autoreload():
 
 def autoreload_f(self, parameter_s=''):
     r""" %autoreload => Reload modules automatically
-    
+
     %autoreload
     Reload all modules (except those excluded by %aimport) automatically now.
-    
+
+    %autoreload 0
+    Disable automatic reloading.
+
     %autoreload 1
     Reload all modules imported with %aimport every time before executing
     the Python code typed.
-    
+
     %autoreload 2
     Reload all modules (except those excluded by %aimport) every time
     before executing the Python code typed.
-    
-    Reloading Python modules in a reliable way is in general difficult,
-    and unexpected things may occur. %autoreload tries to work
-    around common pitfalls by replacing code objects of functions
-    previously in the module with new versions. This makes the following
-    things to work:
+
+    Reloading Python modules in a reliable way is in general
+    difficult, and unexpected things may occur. %autoreload tries to
+    work around common pitfalls by replacing function code objects and
+    parts of classes previously in the module with new versions. This
+    makes the following things to work:
 
     - Functions and classes imported via 'from xxx import foo' are upgraded
       to new versions when 'xxx' is reloaded.
+
     - Methods and properties of classes are upgraded on reload, so that
       calling 'c.foo()' on an object 'c' created before the reload causes
       the new code for 'foo' to be executed.
-    
+
     Some of the known remaining caveats are:
-    
+
     - Replacing code objects does not always succeed: changing a @property
       in a class to an ordinary method or a method to a member variable
       can cause problems (but in old objects only).
+
     - Functions that are removed (eg. via monkey-patching) from a module
       before it is reloaded are not upgraded.
+
     - C extension modules cannot be reloaded, and so cannot be
       autoreloaded.
-    
+
     """
     if parameter_s == '':
         reloader.check(True)
@@ -307,7 +313,7 @@ def aimport_f(self, parameter_s=''):
     Mark module 'foo' to not be autoreloaded for %autoreload 1
 
     """
-    
+
     modname = parameter_s
     if not modname:
         to_reload = reloader.modules.keys()
@@ -329,12 +335,15 @@ def aimport_f(self, parameter_s=''):
         except KeyError: pass
         reloader.modules[modname] = True
 
-        mod = __import__(modname)
-        ip.to_user_ns({modname: mod})
+        # Inject module to user namespace; handle also submodules properly
+        __import__(modname)
+        basename = modname.split('.')[0]
+        mod = sys.modules[basename]
+        ip.to_user_ns({basename: mod})
 
 def init():
     ip.expose_magic('autoreload', autoreload_f)
     ip.expose_magic('aimport', aimport_f)
     ip.set_hook('pre_runcode_hook', runcode_hook)
-    
+
 init()
diff --git a/IPython/frontend/wx/console_widget.py b/IPython/frontend/wx/console_widget.py
index 8fcb17a..8c7967f 100644
--- a/IPython/frontend/wx/console_widget.py
+++ b/IPython/frontend/wx/console_widget.py
@@ -447,29 +447,30 @@ class ConsoleWidget(editwindow.EditWindow):
         #  different callbacks share local variables?
 
         # Intercept some specific keys.
-        if event.KeyCode == ord('L') and event.ControlDown() :
+        key_code = event.GetKeyCode()
+        if key_code == ord('L') and event.ControlDown() :
             self.scroll_to_bottom()
-        elif event.KeyCode == ord('K') and event.ControlDown() :
+        elif key_code == ord('K') and event.ControlDown() :
             self.input_buffer = ''
-        elif event.KeyCode == ord('A') and event.ControlDown() :
+        elif key_code == ord('A') and event.ControlDown() :
             self.GotoPos(self.GetLength())
             self.SetSelectionStart(self.current_prompt_pos)
             self.SetSelectionEnd(self.GetCurrentPos())
             catched = True
-        elif event.KeyCode == ord('E') and event.ControlDown() :
+        elif key_code == ord('E') and event.ControlDown() :
             self.GotoPos(self.GetLength())
             catched = True
-        elif event.KeyCode == wx.WXK_PAGEUP:
+        elif key_code == wx.WXK_PAGEUP:
             self.ScrollPages(-1)
-        elif event.KeyCode == wx.WXK_PAGEDOWN:
+        elif key_code == wx.WXK_PAGEDOWN:
             self.ScrollPages(1)
-        elif event.KeyCode == wx.WXK_HOME:
+        elif key_code == wx.WXK_HOME:
             self.GotoPos(self.GetLength())
-        elif event.KeyCode == wx.WXK_END:
+        elif key_code == wx.WXK_END:
             self.GotoPos(self.GetLength())
-        elif event.KeyCode == wx.WXK_UP and event.ShiftDown():
+        elif key_code == wx.WXK_UP and event.ShiftDown():
             self.ScrollLines(-1)
-        elif event.KeyCode == wx.WXK_DOWN and event.ShiftDown():
+        elif key_code == wx.WXK_DOWN and event.ShiftDown():
             self.ScrollLines(1)
         else:
             catched = False
@@ -477,13 +478,12 @@ class ConsoleWidget(editwindow.EditWindow):
         if self.AutoCompActive():
             event.Skip()
         else:
-            if event.KeyCode in (13, wx.WXK_NUMPAD_ENTER) and \
-                                event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN,
-                                                    wx.MOD_SHIFT):
+            if key_code in (13, wx.WXK_NUMPAD_ENTER):
+                # XXX: not catching modifiers, to be wx2.6-compatible
                 catched = True
                 if not self.enter_catched:
                     self.CallTipCancel()
-                    if event.Modifiers == wx.MOD_SHIFT:
+                    if event.ShiftDown():
                         # Try to force execution
                         self.GotoPos(self.GetLength())
                         self.write('\n' + self.continuation_prompt(), 
@@ -493,19 +493,18 @@ class ConsoleWidget(editwindow.EditWindow):
                         self._on_enter()
                     self.enter_catched = True
 
-            elif event.KeyCode == wx.WXK_HOME:
-                if event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN):
+            elif key_code == wx.WXK_HOME:
+                if not event.ShiftDown():
                     self.GotoPos(self.current_prompt_pos)
                     catched = True
-
-                elif event.Modifiers == wx.MOD_SHIFT:
+                else:
                     # FIXME: This behavior is not ideal: if the selection
                     # is already started, it will jump.
                     self.SetSelectionStart(self.current_prompt_pos) 
                     self.SetSelectionEnd(self.GetCurrentPos())
                     catched = True
 
-            elif event.KeyCode == wx.WXK_UP:
+            elif key_code == wx.WXK_UP:
                 if self.GetCurrentLine() > self.current_prompt_line:
                     if self.GetCurrentLine() == self.current_prompt_line + 1 \
                             and self.GetColumn(self.GetCurrentPos()) < \
@@ -515,18 +514,18 @@ class ConsoleWidget(editwindow.EditWindow):
                         event.Skip()
                 catched = True
 
-            elif event.KeyCode in (wx.WXK_LEFT, wx.WXK_BACK):
+            elif key_code in (wx.WXK_LEFT, wx.WXK_BACK):
                 if not self._keep_cursor_in_buffer(self.GetCurrentPos() - 1):
                     event.Skip()
                 catched = True
 
-            elif event.KeyCode == wx.WXK_RIGHT:
+            elif key_code == wx.WXK_RIGHT:
                 if not self._keep_cursor_in_buffer(self.GetCurrentPos() + 1):
                     event.Skip()
                 catched = True
 
 
-            elif event.KeyCode == wx.WXK_DELETE:
+            elif key_code == wx.WXK_DELETE:
                 if not self._keep_cursor_in_buffer(self.GetCurrentPos() - 1):
                     event.Skip()
                 catched = True
@@ -535,7 +534,7 @@ class ConsoleWidget(editwindow.EditWindow):
                 # Put the cursor back in the edit region
                 if not self._keep_cursor_in_buffer():
                     if not (self.GetCurrentPos() == self.GetLength()
-                                and event.KeyCode == wx.WXK_DELETE):
+                                and key_code == wx.WXK_DELETE):
                         event.Skip()
                     catched = True
 
diff --git a/IPython/frontend/wx/wx_frontend.py b/IPython/frontend/wx/wx_frontend.py
index 854c47e..e22c91e 100644
--- a/IPython/frontend/wx/wx_frontend.py
+++ b/IPython/frontend/wx/wx_frontend.py
@@ -389,7 +389,8 @@ class WxController(ConsoleWidget, PrefilterFrontEnd):
         """
         # FIXME: This method needs to be broken down in smaller ones.
         current_line_num = self.GetCurrentLine()
-        if event.KeyCode in (ord('c'), ord('C')) and event.ControlDown():
+        key_code = event.GetKeyCode()
+        if key_code in (ord('c'), ord('C')) and event.ControlDown():
             # Capture Control-C
             if self._input_state == 'subprocess':
                 if self.debug:
@@ -403,40 +404,39 @@ class WxController(ConsoleWidget, PrefilterFrontEnd):
                 # XXX: We need to make really sure we
                 # get back to a prompt.
         elif self._input_state == 'subprocess' and (
-                ( event.KeyCode<256 and
-                        not event.ControlDown() )
+                ( key_code <256 and not event.ControlDown() )
                     or 
-                ( event.KeyCode in (ord('d'), ord('D')) and
+                ( key_code in (ord('d'), ord('D')) and
                   event.ControlDown())):
             #  We are running a process, we redirect keys.
             ConsoleWidget._on_key_down(self, event, skip=skip)
-            char = chr(event.KeyCode)
+            char = chr(key_code)
             # Deal with some inconsistency in wx keycodes:
             if char == '\r':
                 char = '\n'
             elif not event.ShiftDown():
                 char = char.lower()
-            if event.ControlDown() and event.KeyCode in (ord('d'), ord('D')):
+            if event.ControlDown() and key_code in (ord('d'), ord('D')):
                 char = '\04'
             self._running_process.process.stdin.write(char)
             self._running_process.process.stdin.flush()
-        elif event.KeyCode in (ord('('), 57, 53):
+        elif key_code in (ord('('), 57, 53):
             # Calltips
             event.Skip()
             self.do_calltip()
-        elif self.AutoCompActive() and not event.KeyCode == ord('\t'):
+        elif self.AutoCompActive() and not key_code == ord('\t'):
             event.Skip()
-            if event.KeyCode in (wx.WXK_BACK, wx.WXK_DELETE): 
+            if key_code in (wx.WXK_BACK, wx.WXK_DELETE): 
                 wx.CallAfter(self._popup_completion, create=True)
-            elif not event.KeyCode in (wx.WXK_UP, wx.WXK_DOWN, wx.WXK_LEFT,
+            elif not key_code in (wx.WXK_UP, wx.WXK_DOWN, wx.WXK_LEFT,
                             wx.WXK_RIGHT, wx.WXK_ESCAPE):
                 wx.CallAfter(self._popup_completion)
         else:
             # Up history
-            if event.KeyCode == wx.WXK_UP and (
-                    ( current_line_num == self.current_prompt_line and
-                        event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN) ) 
-                    or event.ControlDown() ):
+            if key_code == wx.WXK_UP and (
+                            event.ControlDown() or
+                            current_line_num == self.current_prompt_line
+                    ):
                 new_buffer = self.get_history_previous(
                                             self.input_buffer)
                 if new_buffer is not None:
@@ -445,23 +445,24 @@ class WxController(ConsoleWidget, PrefilterFrontEnd):
                         # Go to first line, for seemless history up.
                         self.GotoPos(self.current_prompt_pos)
             # Down history
-            elif event.KeyCode == wx.WXK_DOWN and (
-                    ( current_line_num == self.LineCount -1 and
-                        event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN) ) 
-                    or event.ControlDown() ):
+            elif key_code == wx.WXK_DOWN and (
+                            event.ControlDown() or
+                            current_line_num == self.LineCount -1
+                    ):
                 new_buffer = self.get_history_next()
                 if new_buffer is not None:
                     self.input_buffer = new_buffer
             # Tab-completion
-            elif event.KeyCode == ord('\t'):
+            elif key_code == ord('\t'):
                 current_line, current_line_num = self.CurLine
-                if not re.match(r'^\s*$', current_line):
+                if not re.match(r'^%s\s*$' % self.continuation_prompt(), 
+                                                            current_line):
                     self.complete_current_input()
                     if self.AutoCompActive():
                         wx.CallAfter(self._popup_completion, create=True)
                 else:
                     event.Skip()
-            elif event.KeyCode == wx.WXK_BACK:
+            elif key_code == wx.WXK_BACK:
                 # If characters where erased, check if we have to
                 # remove a line.
                 # XXX: What about DEL?
@@ -496,7 +497,7 @@ class WxController(ConsoleWidget, PrefilterFrontEnd):
     def _on_key_up(self, event, skip=True):
         """ Called when any key is released.
         """
-        if event.KeyCode in (59, ord('.')):
+        if event.GetKeyCode() in (59, ord('.')):
             # Intercepting '.'
             event.Skip()
             wx.CallAfter(self._popup_completion, create=True)
diff --git a/IPython/kernel/scripts/ipcluster.py b/IPython/kernel/scripts/ipcluster.py
old mode 100755
new mode 100644