diff --git a/IPython/core/inputsplitter.py b/IPython/core/inputsplitter.py
index f2e148a..146104e 100644
--- a/IPython/core/inputsplitter.py
+++ b/IPython/core/inputsplitter.py
@@ -559,19 +559,23 @@ def _make_help_call(target, esc, lspace, next_input=None):
                 else 'pinfo'
     arg = " ".join([method, target])
     
-    if next_input:
-        tpl = '%sget_ipython().magic(%r, next_input=%r)'
-        return tpl % (lspace, arg, next_input)
-    else:
+    if next_input is None:
         return '%sget_ipython().magic(%r)' % (lspace, arg)
+    else:
+        return '%sget_ipython().set_next_input(%r);get_ipython().magic(%r)' % \
+           (lspace, next_input, arg)
+
 
 _initial_space_re = re.compile(r'\s*')
+
 _help_end_re = re.compile(r"""(%?
                               [a-zA-Z_*][\w*]*        # Variable name
                               (\.[a-zA-Z_*][\w*]*)*   # .etc.etc
                               )
                               (\?\??)$                # ? or ??""",
                               re.VERBOSE)
+
+
 def transform_help_end(line):
     """Translate lines with ?/?? at the end"""
     m = _help_end_re.search(line)
diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py
index e39e1fe..e1c5355 100644
--- a/IPython/core/interactiveshell.py
+++ b/IPython/core/interactiveshell.py
@@ -2014,7 +2014,7 @@ class InteractiveShell(SingletonConfigurable):
         # even need a centralize colors management object.
         self.magic('colors %s' % self.colors)
 
-    def line_magic(self, magic_name, line, next_input=None):
+    def line_magic(self, magic_name, line):
         """Execute the given line magic.
 
         Parameters
@@ -2024,15 +2024,7 @@ class InteractiveShell(SingletonConfigurable):
 
         line : str
           The rest of the input line as a single string.
-
-        next_input : str, optional
-          Text to pre-load into the next input line.
         """
-        # Allow setting the next input - this is used if the user does `a=abs?`.
-        # We do this first so that magic functions can override it.
-        if next_input:
-            self.set_next_input(next_input)
-
         fn = self.find_line_magic(magic_name)
         if fn is None:
             error("Magic function `%s` not found." % magic_name)
@@ -2079,13 +2071,13 @@ class InteractiveShell(SingletonConfigurable):
         Returns None if the magic isn't found."""
         return self.magics_manager.magics['cell'].get(magic_name)
 
-    def find_magic(self, magic_name, magic_type='line'):
+    def find_magic(self, magic_name, magic_kind='line'):
         """Find and return a magic of the given type by name.
 
         Returns None if the magic isn't found."""
-        return self.magics_manager.magics[magic_type].get(magic_name)
+        return self.magics_manager.magics[magic_kind].get(magic_name)
 
-    def magic(self, arg_s, next_input=None):
+    def magic(self, arg_s):
         """DEPRECATED. Use line_magic() instead.
 
         Call a magic function by name.
@@ -2107,7 +2099,7 @@ class InteractiveShell(SingletonConfigurable):
         # TODO: should we issue a loud deprecation warning here?
         magic_name, _, magic_arg_s = arg_s.partition(' ')
         magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
-        return self.line_magic(magic_name, magic_arg_s, next_input)
+        return self.line_magic(magic_name, magic_arg_s)
 
     #-------------------------------------------------------------------------
     # Things related to macros
diff --git a/IPython/core/magic.py b/IPython/core/magic.py
index 8173417..a87abf4 100644
--- a/IPython/core/magic.py
+++ b/IPython/core/magic.py
@@ -44,7 +44,7 @@ from IPython.utils.warn import error, warn
 
 magics = dict(line={}, cell={})
 
-magic_types = ('line', 'cell')
+magic_kinds = ('line', 'cell')
 magic_spec = ('line', 'cell', 'line_cell')
 
 #-----------------------------------------------------------------------------
@@ -98,16 +98,16 @@ def record_magic(dct, mtype, mname, func):
         dct[mtype][mname] = func
 
 
-def validate_type(magic_type):
-    if magic_type not in magic_spec:
-        raise ValueError('magic_type must be one of %s, %s given' %
-                         magic_types, magic_type)
+def validate_type(magic_kind):
+    if magic_kind not in magic_spec:
+        raise ValueError('magic_kind must be one of %s, %s given' %
+                         magic_kinds, magic_kind)
 
 
-def _magic_marker(magic_type):
-    validate_type(magic_type)
+def _magic_marker(magic_kind):
+    validate_type(magic_kind)
 
-    # This is a closure to capture the magic_type.  We could also use a class,
+    # This is a closure to capture the magic_kind.  We could also use a class,
     # but it's overkill for just that one bit of state.
     def magic_deco(arg):
         call = lambda f, *a, **k: f(*a, **k)
@@ -118,13 +118,13 @@ def _magic_marker(magic_type):
             name = func.func_name
             func.magic_name = name
             retval = decorator(call, func)
-            record_magic(magics, magic_type, name, name)
+            record_magic(magics, magic_kind, name, name)
         elif isinstance(arg, basestring):
             # Decorator called with arguments (@foo('bar'))
             name = arg
             def mark(func, *a, **kw):
                 func.magic_name = name
-                record_magic(magics, magic_type, name, func.func_name)
+                record_magic(magics, magic_kind, name, func.func_name)
                 return decorator(call, func)
             retval = mark
         else:
@@ -135,10 +135,10 @@ def _magic_marker(magic_type):
     return magic_deco
 
 
-def _function_magic_marker(magic_type):
-    validate_type(magic_type)
+def _function_magic_marker(magic_kind):
+    validate_type(magic_kind)
 
-    # This is a closure to capture the magic_type.  We could also use a class,
+    # This is a closure to capture the magic_kind.  We could also use a class,
     # but it's overkill for just that one bit of state.
     def magic_deco(arg):
         call = lambda f, *a, **k: f(*a, **k)
@@ -157,16 +157,14 @@ def _function_magic_marker(magic_type):
         if callable(arg):
             # "Naked" decorator call (just @foo, no args)
             func = arg
-            #name = func.func_name
-            #func.magic_name = name
-            ip.register_magic_function(func)
+            name = func.func_name
+            ip.register_magic_function(func, magic_kind, name)
             retval = decorator(call, func)
         elif isinstance(arg, basestring):
             # Decorator called with arguments (@foo('bar'))
             name = arg
             def mark(func, *a, **kw):
-                #func.magic_name = name
-                ip.register_magic_function(func)
+                ip.register_magic_function(func, magic_kind, name)
                 return decorator(call, func)
             retval = mark
         else:
@@ -254,19 +252,19 @@ class MagicsManager(Configurable):
             # Now that we have an instance, we can register it and update the
             # table of callables
             self.registry[m.__class__.__name__] = m
-            for mtype in magic_types:
+            for mtype in magic_kinds:
                 self.magics[mtype].update(m.magics[mtype])
 
-    def register_function(self, func, magic_type='line', magic_name=None):
+    def register_function(self, func, magic_kind='line', magic_name=None):
         """Expose a standalone function as magic function for ipython.
         """
 
         # Create the new method in the user_magics and register it in the
         # global table
-        validate_type(magic_type)
+        validate_type(magic_kind)
         magic_name = func.func_name if magic_name is None else magic_name
         setattr(self.user_magics, magic_name, func)
-        record_magic(self.magics, magic_type, magic_name, func)
+        record_magic(self.magics, magic_kind, magic_name, func)
 
     def define_magic(self, name, func):
         """Support for deprecated API.
@@ -320,7 +318,7 @@ class Magics(object):
         # grab.  Only now, that the instance exists, can we create the proper
         # mapping to bound methods.  So we read the info off the original names
         # table and replace each method name by the actual bound method.
-        for mtype in magic_types:
+        for mtype in magic_kinds:
             tab = self.magics[mtype]
             # must explicitly use keys, as we're mutating this puppy
             for magic_name in tab.keys():
diff --git a/IPython/core/tests/test_inputsplitter.py b/IPython/core/tests/test_inputsplitter.py
index 73e4dba..0d244b9 100644
--- a/IPython/core/tests/test_inputsplitter.py
+++ b/IPython/core/tests/test_inputsplitter.py
@@ -466,10 +466,14 @@ syntax = \
         (u'%hist?', "get_ipython().magic({u}'pinfo %hist')"),
         (u'f*?', "get_ipython().magic({u}'psearch f*')"),
         (u'ax.*aspe*?', "get_ipython().magic({u}'psearch ax.*aspe*')"),
-        (u'a = abc?', "get_ipython().magic({u}'pinfo abc', next_input={u}'a = abc')"),
-        (u'a = abc.qe??', "get_ipython().magic({u}'pinfo2 abc.qe', next_input={u}'a = abc.qe')"),
-        (u'a = *.items?', "get_ipython().magic({u}'psearch *.items', next_input={u}'a = *.items')"),
-        (u'plot(a?', "get_ipython().magic({u}'pinfo a', next_input={u}'plot(a')"),
+        (u'a = abc?', "get_ipython().set_next_input({u}'a = abc');"
+                      "get_ipython().magic({u}'pinfo abc')"),
+        (u'a = abc.qe??', "get_ipython().set_next_input({u}'a = abc.qe');"
+                          "get_ipython().magic({u}'pinfo2 abc.qe')"),
+        (u'a = *.items?', "get_ipython().set_next_input({u}'a = *.items');"
+                          "get_ipython().magic({u}'psearch *.items')"),
+        (u'plot(a?', "get_ipython().set_next_input({u}'plot(a');"
+                     "get_ipython().magic({u}'pinfo a')"),
         (u'a*2 #comment?', 'a*2 #comment?'),
         ]],
 
diff --git a/IPython/core/tests/test_magic.py b/IPython/core/tests/test_magic.py
index d664931..bc17c76 100644
--- a/IPython/core/tests/test_magic.py
+++ b/IPython/core/tests/test_magic.py
@@ -13,10 +13,15 @@ import io
 import os
 import sys
 from StringIO import StringIO
+from unittest import TestCase
 
 import nose.tools as nt
 
 from IPython.core import magic
+from IPython.core.magic import (Magics, magics_class, line_magic,
+                                cell_magic, line_cell_magic,
+                                register_line_magic, register_cell_magic,
+                                register_line_cell_magic)
 from IPython.core.magics import execution
 from IPython.nbformat.v3.tests.nbexamples import nb0
 from IPython.nbformat import current