diff --git a/IPython/core/inputsplitter.py b/IPython/core/inputsplitter.py
index 5b316a9..bae1c74 100644
--- a/IPython/core/inputsplitter.py
+++ b/IPython/core/inputsplitter.py
@@ -247,8 +247,6 @@ class InputSplitter(object):
     # synced to the source, so it can be queried at any time to obtain the code
     # object; it will be None if the source doesn't compile to valid Python.
     code = None
-    # Input mode
-    input_mode = 'line'
 
     # Private attributes
 
@@ -261,32 +259,12 @@ class InputSplitter(object):
     # Boolean indicating whether the current block is complete
     _is_complete = None
 
-    def __init__(self, input_mode=None):
+    def __init__(self):
         """Create a new InputSplitter instance.
-
-        Parameters
-        ----------
-        input_mode : str
-
-          One of ['line', 'cell']; default is 'line'.
-
-       The input_mode parameter controls how new inputs are used when fed via
-       the :meth:`push` method:
-
-       - 'line': meant for line-oriented clients, inputs are appended one at a
-         time to the internal buffer and the whole buffer is compiled.
-
-       - 'cell': meant for clients that can edit multi-line 'cells' of text at
-          a time.  A cell can contain one or more blocks that can be compile in
-          'single' mode by Python.  In this mode, each new input new input
-          completely replaces all prior inputs.  Cell mode is thus equivalent
-          to prepending a full reset() to every push() call.
         """
         self._buffer = []
         self._compile = codeop.CommandCompiler()
         self.encoding = get_input_encoding()
-        self.input_mode = InputSplitter.input_mode if input_mode is None \
-                          else input_mode
 
     def reset(self):
         """Reset the input buffer and associated state."""
@@ -326,9 +304,6 @@ class InputSplitter(object):
           this value is also stored as a private attribute (``_is_complete``), so it
           can be queried at any time.
         """
-        if self.input_mode == 'cell':
-            self.reset()
-
         self._store(lines)
         source = self.source
 
@@ -388,39 +363,34 @@ class InputSplitter(object):
         """
 
         # With incomplete input, unconditionally accept more
+        # A syntax error also sets _is_complete to True - see push()
         if not self._is_complete:
+            #print("Not complete")  # debug
             return True
-
-        # If we already have complete input and we're flush left, the answer
-        # depends.  In line mode, if there hasn't been any indentation,
-        # that's it. If we've come back from some indentation, we need
-        # the blank final line to finish.
-        # In cell mode, we need to check how many blocks the input so far
-        # compiles into, because if there's already more than one full
-        # independent block of input, then the client has entered full
-        # 'cell' mode and is feeding lines that each is complete.  In this
-        # case we should then keep accepting. The Qt terminal-like console
-        # does precisely this, to provide the convenience of terminal-like
-        # input of single expressions, but allowing the user (with a
-        # separate keystroke) to switch to 'cell' mode and type multiple
-        # expressions in one shot.
+        
+        # The user can make any (complete) input execute by leaving a blank line
+        last_line = self.source.splitlines()[-1]
+        if (not last_line) or last_line.isspace():
+            #print("Blank line")  # debug
+            return False
+        
+        # If there's just a single AST node, and we're flush left, as is the 
+        # case after a simple statement such as 'a=1', we want to execute it
+        # straight away.
         if self.indent_spaces==0:
-            if self.input_mode=='line':
-                if not self._full_dedent:
-                    return False
+            try:
+                code_ast = ast.parse(u''.join(self._buffer))
+            except Exception:
+                #print("Can't parse AST")  # debug
+                return False
             else:
-                try:
-                    code_ast = ast.parse(u''.join(self._buffer))
-                except Exception:
+                if len(code_ast.body) == 1 and \
+                                    not hasattr(code_ast.body[0], 'body'):
+                    #print("Simple statement")  # debug
                     return False
-                else:
-                    if len(code_ast.body) == 1:
-                        return False
 
-        # When input is complete, then termination is marked by an extra blank
-        # line at the end.
-        last_line = self.source.splitlines()[-1]
-        return bool(last_line and not last_line.isspace())
+        # General fallback - accept more code
+        return True
 
     #------------------------------------------------------------------------
     # Private interface
@@ -510,9 +480,9 @@ class IPythonInputSplitter(InputSplitter):
     # List with lines of raw input accumulated so far.
     _buffer_raw = None
 
-    def __init__(self, input_mode=None, physical_line_transforms=None,
+    def __init__(self, physical_line_transforms=None,
                     logical_line_transforms=None, python_line_transforms=None):
-        super(IPythonInputSplitter, self).__init__(input_mode)
+        super(IPythonInputSplitter, self).__init__()
         self._buffer_raw = []
         self._validate = True
         
@@ -641,44 +611,14 @@ class IPythonInputSplitter(InputSplitter):
         if not lines_list:
             lines_list = ['']
 
-        # Transform logic
-        #
-        # We only apply the line transformers to the input if we have either no
-        # input yet, or complete input, or if the last line of the buffer ends
-        # with ':' (opening an indented block).  This prevents the accidental
-        # transformation of escapes inside multiline expressions like
-        # triple-quoted strings or parenthesized expressions.
-        #
-        # The last heuristic, while ugly, ensures that the first line of an
-        # indented block is correctly transformed.
-        #
-        # FIXME: try to find a cleaner approach for this last bit.
-
-        # If we were in 'block' mode, since we're going to pump the parent
-        # class by hand line by line, we need to temporarily switch out to
-        # 'line' mode, do a single manual reset and then feed the lines one
-        # by one.  Note that this only matters if the input has more than one
-        # line.
-        changed_input_mode = False
-
-        if self.input_mode == 'cell':
-            self.reset()
-            changed_input_mode = True
-            saved_input_mode = 'cell'
-            self.input_mode = 'line'
-
         # Store raw source before applying any transformations to it.  Note
         # that this must be done *after* the reset() call that would otherwise
         # flush the buffer.
         self._store(lines, self._buffer_raw, 'source_raw')
 
-        try:
-            for line in lines_list:
-                out = self.push_line(line)
-        finally:
-            if changed_input_mode:
-                self.input_mode = saved_input_mode
-        
+        for line in lines_list:
+            out = self.push_line(line)
+
         return out
     
     def push_line(self, line):
diff --git a/IPython/core/tests/test_inputsplitter.py b/IPython/core/tests/test_inputsplitter.py
index a351bb0..bdaab48 100644
--- a/IPython/core/tests/test_inputsplitter.py
+++ b/IPython/core/tests/test_inputsplitter.py
@@ -168,9 +168,6 @@ class InputSplitterTestCase(unittest.TestCase):
         self.assertEqual(isp.indent_spaces, 0)
 
     def test_indent2(self):
-        # In cell mode, inputs must be fed in whole blocks, so skip this test
-        if self.isp.input_mode == 'cell': return
-
         isp = self.isp
         isp.push('if 1:')
         self.assertEqual(isp.indent_spaces, 4)
@@ -181,9 +178,6 @@ class InputSplitterTestCase(unittest.TestCase):
         self.assertEqual(isp.indent_spaces, 4)
 
     def test_indent3(self):
-        # In cell mode, inputs must be fed in whole blocks, so skip this test
-        if self.isp.input_mode == 'cell': return
-
         isp = self.isp
         # When a multiline statement contains parens or multiline strings, we
         # shouldn't get confused.
@@ -192,9 +186,6 @@ class InputSplitterTestCase(unittest.TestCase):
         self.assertEqual(isp.indent_spaces, 4)
 
     def test_indent4(self):
-        # In cell mode, inputs must be fed in whole blocks, so skip this test
-        if self.isp.input_mode == 'cell': return
-
         isp = self.isp
         # whitespace after ':' should not screw up indent level
         isp.push('if 1: \n    x=1')
@@ -279,23 +270,12 @@ class InputSplitterTestCase(unittest.TestCase):
         isp.push('  a = 1')
         self.assertFalse(isp.push('b = [1,'))
 
-    def test_replace_mode(self):
-        isp = self.isp
-        isp.input_mode = 'cell'
-        isp.push('x=1')
-        self.assertEqual(isp.source, 'x=1\n')
-        isp.push('x=2')
-        self.assertEqual(isp.source, 'x=2\n')
-
     def test_push_accepts_more(self):
         isp = self.isp
         isp.push('x=1')
         self.assertFalse(isp.push_accepts_more())
 
     def test_push_accepts_more2(self):
-        # In cell mode, inputs must be fed in whole blocks, so skip this test
-        if self.isp.input_mode == 'cell': return
-
         isp = self.isp
         isp.push('if 1:')
         self.assertTrue(isp.push_accepts_more())
@@ -310,9 +290,6 @@ class InputSplitterTestCase(unittest.TestCase):
         self.assertFalse(isp.push_accepts_more())
 
     def test_push_accepts_more4(self):
-        # In cell mode, inputs must be fed in whole blocks, so skip this test
-        if self.isp.input_mode == 'cell': return
-
         isp = self.isp
         # When a multiline statement contains parens or multiline strings, we
         # shouldn't get confused.
@@ -331,14 +308,13 @@ class InputSplitterTestCase(unittest.TestCase):
         self.assertFalse(isp.push_accepts_more())
 
     def test_push_accepts_more5(self):
-        # In cell mode, inputs must be fed in whole blocks, so skip this test
-        if self.isp.input_mode == 'cell': return
-
         isp = self.isp
         isp.push('try:')
         isp.push('    a = 5')
         isp.push('except:')
         isp.push('    raise')
+        # We want to be able to add an else: block at this point, so it should
+        # wait for a blank line.
         self.assertTrue(isp.push_accepts_more())
 
     def test_continuation(self):
@@ -431,7 +407,7 @@ class IPythonInputTestCase(InputSplitterTestCase):
     """
 
     def setUp(self):
-        self.isp = isp.IPythonInputSplitter(input_mode='line')
+        self.isp = isp.IPythonInputSplitter()
 
     def test_syntax(self):
         """Call all single-line syntax tests from the main object"""
@@ -467,32 +443,6 @@ class IPythonInputTestCase(InputSplitterTestCase):
                 self.assertEqual(out.rstrip(), out_t)
                 self.assertEqual(out_raw.rstrip(), raw)
 
-
-class BlockIPythonInputTestCase(IPythonInputTestCase):
-
-    # Deactivate tests that don't make sense for the block mode
-    test_push3 = test_split = lambda s: None
-
-    def setUp(self):
-        self.isp = isp.IPythonInputSplitter(input_mode='cell')
-
-    def test_syntax_multiline(self):
-        isp = self.isp
-        for example in syntax_ml.itervalues():
-            raw_parts = []
-            out_t_parts = []
-            for line_pairs in example:
-                raw_parts, out_t_parts = zip(*line_pairs)
-
-                raw = '\n'.join(r for r in raw_parts if r is not None)
-                out_t = '\n'.join(o for o in out_t_parts if o is not None)
-
-                isp.push(raw)
-                out, out_raw = isp.source_raw_reset()
-                # Match ignoring trailing whitespace
-                self.assertEqual(out.rstrip(), out_t.rstrip())
-                self.assertEqual(out_raw.rstrip(), raw.rstrip())
-
     def test_syntax_multiline_cell(self):
         isp = self.isp
         for example in syntax_ml.itervalues():
diff --git a/IPython/frontend/qt/console/frontend_widget.py b/IPython/frontend/qt/console/frontend_widget.py
index 3fe0203..2fe1cfa 100644
--- a/IPython/frontend/qt/console/frontend_widget.py
+++ b/IPython/frontend/qt/console/frontend_widget.py
@@ -146,7 +146,7 @@ class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
         self._copy_raw_action = QtGui.QAction('Copy (Raw Text)', None)
         self._hidden = False
         self._highlighter = FrontendHighlighter(self)
-        self._input_splitter = self._input_splitter_class(input_mode='cell')
+        self._input_splitter = self._input_splitter_class()
         self._kernel_manager = None
         self._request_info = {}
         self._request_info['execute'] = {};
@@ -204,6 +204,7 @@ class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
             prompt created. When triggered by an Enter/Return key press,
             'interactive' is True; otherwise, it is False.
         """
+        self._input_splitter.reset()
         complete = self._input_splitter.push(source)
         if interactive:
             complete = not self._input_splitter.push_accepts_more()
diff --git a/IPython/frontend/terminal/interactiveshell.py b/IPython/frontend/terminal/interactiveshell.py
index 030b46a..19ce96b 100644
--- a/IPython/frontend/terminal/interactiveshell.py
+++ b/IPython/frontend/terminal/interactiveshell.py
@@ -82,7 +82,7 @@ def get_pasted_lines(sentinel, l_input=py3compat.input):
 class TerminalMagics(Magics):
     def __init__(self, shell):
         super(TerminalMagics, self).__init__(shell)
-        self.input_splitter = IPythonInputSplitter(input_mode='line')
+        self.input_splitter = IPythonInputSplitter()
 
     def cleanup_input(self, block):
         """Apply all possible IPython cleanups to an input block.