diff --git a/IPython/core/displayhook.py b/IPython/core/displayhook.py
index 269ae18..ad3cc27 100644
--- a/IPython/core/displayhook.py
+++ b/IPython/core/displayhook.py
@@ -113,7 +113,7 @@ class DisplayHook(Configurable):
         """
         # Use write, not print which adds an extra space.
         sys.stdout.write(self.shell.separate_out)
-        outprompt = self.shell.prompt_manager.render('out')
+        outprompt = 'Out[{}]: '.format(self.shell.execution_count)
         if self.do_full_cache:
             sys.stdout.write(outprompt)
 
@@ -149,6 +149,9 @@ class DisplayHook(Configurable):
         """
         return self.shell.display_formatter.format(result)
 
+    # This can be set to True by the write_output_prompt method in a subclass
+    prompt_end_newline = False
+
     def write_format_data(self, format_dict, md_dict=None):
         """Write the format data dict to the frontend.
 
@@ -179,8 +182,7 @@ class DisplayHook(Configurable):
             # because the expansion may add ANSI escapes that will interfere
             # with our ability to determine whether or not we should add
             # a newline.
-            prompt_template = self.shell.prompt_manager.out_template
-            if prompt_template and not prompt_template.endswith('\n'):
+            if not self.prompt_end_newline:
                 # But avoid extraneous empty lines.
                 result_repr = '\n' + result_repr
 
diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py
index d081dfd..7c20eed 100644
--- a/IPython/core/interactiveshell.py
+++ b/IPython/core/interactiveshell.py
@@ -56,7 +56,6 @@ from IPython.core.macro import Macro
 from IPython.core.payload import PayloadManager
 from IPython.core.prefilter import PrefilterManager
 from IPython.core.profiledir import ProfileDir
-from IPython.core.prompts import PromptManager
 from IPython.core.usage import default_banner
 from IPython.testing.skipdoctest import skip_doctest_py2, skip_doctest
 from IPython.utils import PyColorize
@@ -664,8 +663,6 @@ class InteractiveShell(SingletonConfigurable):
             io.stderr = io.IOStream(sys.stderr)
 
     def init_prompts(self):
-        self.prompt_manager = PromptManager(shell=self, parent=self)
-        self.configurables.append(self.prompt_manager)
         # Set system prompts, so that scripts can decide if they are running
         # interactively.
         sys.ps1 = 'In : '
@@ -2339,16 +2336,9 @@ class InteractiveShell(SingletonConfigurable):
         """
         if not self.show_rewritten_input:
             return
-        
-        rw = self.prompt_manager.render('rewrite') + cmd
 
-        try:
-            # plain ascii works better w/ pyreadline, on some machines, so
-            # we use it and only print uncolored rewrite if we have unicode
-            rw = str(rw)
-            print(rw)
-        except UnicodeEncodeError:
-            print("------> " + cmd)
+        # This is overridden in TerminalInteractiveShell to use fancy prompts
+        print("------> " + cmd)
 
     #-------------------------------------------------------------------------
     # Things related to extracting values/expressions from kernel and user_ns
@@ -3233,6 +3223,11 @@ class InteractiveShell(SingletonConfigurable):
         self.restore_sys_module_state()
 
 
+    # Overridden in terminal subclass to change prompts
+    def switch_doctest_mode(self, mode):
+        pass
+
+
 class InteractiveShellABC(with_metaclass(abc.ABCMeta, object)):
     """An abstract base class for InteractiveShell."""
 
diff --git a/IPython/core/magics/basic.py b/IPython/core/magics/basic.py
index b42aab9..818a90c 100644
--- a/IPython/core/magics/basic.py
+++ b/IPython/core/magics/basic.py
@@ -356,14 +356,6 @@ Defaulting color scheme to 'NoColor'"""
                 # Will remove this check after switching to prompt_toolkit
                 new_scheme = 'NoColor'
 
-        # Set prompt colors
-        try:
-            shell.prompt_manager.color_scheme = new_scheme
-        except:
-            color_switch_err('prompt')
-        else:
-            shell.colors = \
-                   shell.prompt_manager.color_scheme_table.active_scheme_name
         # Set exception colors
         try:
             shell.InteractiveTB.set_colors(scheme = new_scheme)
@@ -435,7 +427,6 @@ Defaulting color scheme to 'NoColor'"""
 
         # Shorthands
         shell = self.shell
-        pm = shell.prompt_manager
         meta = shell.meta
         disp_formatter = self.shell.display_formatter
         ptformatter = disp_formatter.formatters['text/plain']
@@ -450,23 +441,17 @@ Defaulting color scheme to 'NoColor'"""
         save_dstore('xmode',shell.InteractiveTB.mode)
         save_dstore('rc_separate_out',shell.separate_out)
         save_dstore('rc_separate_out2',shell.separate_out2)
-        save_dstore('rc_prompts_pad_left',pm.justify)
         save_dstore('rc_separate_in',shell.separate_in)
         save_dstore('rc_active_types',disp_formatter.active_types)
-        save_dstore('prompt_templates',(pm.in_template, pm.in2_template, pm.out_template))
 
         if not mode:
             # turn on
-            pm.in_template = '>>> '
-            pm.in2_template = '... '
-            pm.out_template = ''
 
             # Prompt separators like plain python
             shell.separate_in = ''
             shell.separate_out = ''
             shell.separate_out2 = ''
 
-            pm.justify = False
 
             ptformatter.pprint = False
             disp_formatter.active_types = ['text/plain']
@@ -474,22 +459,22 @@ Defaulting color scheme to 'NoColor'"""
             shell.magic('xmode Plain')
         else:
             # turn off
-            pm.in_template, pm.in2_template, pm.out_template = dstore.prompt_templates
-
             shell.separate_in = dstore.rc_separate_in
 
             shell.separate_out = dstore.rc_separate_out
             shell.separate_out2 = dstore.rc_separate_out2
 
-            pm.justify = dstore.rc_prompts_pad_left
-
             ptformatter.pprint = dstore.rc_pprint
             disp_formatter.active_types = dstore.rc_active_types
 
             shell.magic('xmode ' + dstore.xmode)
 
+        # mode here is the state before we switch; switch_doctest_mode takes
+        # the mode we're switching to.
+        shell.switch_doctest_mode(not mode)
+
         # Store new mode and inform
-        dstore.mode = bool(1-int(mode))
+        dstore.mode = bool(not mode)
         mode_label = ['OFF','ON'][dstore.mode]
         print('Doctest mode is:', mode_label)
 
diff --git a/IPython/core/prompts.py b/IPython/core/prompts.py
index 0f42557..7802bc5 100644
--- a/IPython/core/prompts.py
+++ b/IPython/core/prompts.py
@@ -1,37 +1,8 @@
 # -*- coding: utf-8 -*-
-"""Classes for handling input/output prompts."""
+"""Being removed
+"""
 
-# Copyright (c) 2001-2007 Fernando Perez <fperez@colorado.edu>
-# Copyright (c) IPython Development Team.
-# Distributed under the terms of the Modified BSD License.
-
-import os
-import re
-import socket
-import sys
-import time
-
-from string import Formatter
-
-from traitlets.config.configurable import Configurable
-from IPython.core import release
-from IPython.utils import coloransi, py3compat
-from traitlets import Unicode, Instance, Dict, Bool, Int, observe, default
-
-from IPython.utils.PyColorize import LightBGColors, LinuxColors, NoColor
-
-#-----------------------------------------------------------------------------
-# Color schemes for prompts
-#-----------------------------------------------------------------------------
-
-InputColors = coloransi.InputTermColors  # just a shorthand
-Colors = coloransi.TermColors  # just a shorthand
-
-color_lists = dict(normal=Colors(), inp=InputColors(), nocolor=coloransi.NoColors())
-
-#-----------------------------------------------------------------------------
-# Utilities
-#-----------------------------------------------------------------------------
+from IPython.utils import py3compat
 
 class LazyEvaluate(object):
     """This is used for formatting strings with values that need to be updated
@@ -53,360 +24,3 @@ class LazyEvaluate(object):
 
     def __format__(self, format_spec):
         return format(self(), format_spec)
-
-def multiple_replace(dict, text):
-    """ Replace in 'text' all occurrences of any key in the given
-    dictionary by its corresponding value.  Returns the new string."""
-
-    # Function by Xavier Defrang, originally found at:
-    # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
-
-    # Create a regular expression  from the dictionary keys
-    regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
-    # For each match, look-up corresponding value in dictionary
-    return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
-
-#-----------------------------------------------------------------------------
-# Special characters that can be used in prompt templates, mainly bash-like
-#-----------------------------------------------------------------------------
-
-# If $HOME isn't defined (Windows), make it an absurd string so that it can
-# never be expanded out into '~'.  Basically anything which can never be a
-# reasonable directory name will do, we just want the $HOME -> '~' operation
-# to become a no-op.  We pre-compute $HOME here so it's not done on every
-# prompt call.
-
-# FIXME:
-
-# - This should be turned into a class which does proper namespace management,
-# since the prompt specials need to be evaluated in a certain namespace.
-# Currently it's just globals, which need to be managed manually by code
-# below.
-
-# - I also need to split up the color schemes from the prompt specials
-# somehow.  I don't have a clean design for that quite yet.
-
-HOME = py3compat.str_to_unicode(os.environ.get("HOME","//////:::::ZZZZZ,,,~~~"))
-
-# This is needed on FreeBSD, and maybe other systems which symlink /home to
-# /usr/home, but retain the $HOME variable as pointing to /home
-HOME = os.path.realpath(HOME)
-
-# We precompute a few more strings here for the prompt_specials, which are
-# fixed once ipython starts.  This reduces the runtime overhead of computing
-# prompt strings.
-USER           = py3compat.str_to_unicode(os.environ.get("USER",''))
-HOSTNAME       = py3compat.str_to_unicode(socket.gethostname())
-HOSTNAME_SHORT = HOSTNAME.split(".")[0]
-
-# IronPython doesn't currently have os.getuid() even if
-# os.name == 'posix'; 2/8/2014
-ROOT_SYMBOL    = "#" if (os.name=='nt' or sys.platform=='cli' or os.getuid()==0) else "$"
-
-prompt_abbreviations = {
-    # Prompt/history count
-    '%n' : '{color.number}' '{count}' '{color.prompt}',
-    r'\#': '{color.number}' '{count}' '{color.prompt}',
-    # Just the prompt counter number, WITHOUT any coloring wrappers, so users
-    # can get numbers displayed in whatever color they want.
-    r'\N': '{count}',
-
-    # Prompt/history count, with the actual digits replaced by dots or
-    # spaces.  Used mainly in continuation prompts (prompt_in2).
-    r'\D': '{dots}',
-    r'\S': '{spaces}',
-
-    # Current time
-    r'\T' : '{time}',
-    # Current working directory
-    r'\w': '{cwd}',
-    # Basename of current working directory.
-    # (use os.sep to make this portable across OSes)
-    r'\W' : '{cwd_last}',
-    # These X<N> are an extension to the normal bash prompts.  They return
-    # N terms of the path, after replacing $HOME with '~'
-    r'\X0': '{cwd_x[0]}',
-    r'\X1': '{cwd_x[1]}',
-    r'\X2': '{cwd_x[2]}',
-    r'\X3': '{cwd_x[3]}',
-    r'\X4': '{cwd_x[4]}',
-    r'\X5': '{cwd_x[5]}',
-    # Y<N> are similar to X<N>, but they show '~' if it's the directory
-    # N+1 in the list.  Somewhat like %cN in tcsh.
-    r'\Y0': '{cwd_y[0]}',
-    r'\Y1': '{cwd_y[1]}',
-    r'\Y2': '{cwd_y[2]}',
-    r'\Y3': '{cwd_y[3]}',
-    r'\Y4': '{cwd_y[4]}',
-    r'\Y5': '{cwd_y[5]}',
-    # Hostname up to first .
-    r'\h': HOSTNAME_SHORT,
-    # Full hostname
-    r'\H': HOSTNAME,
-    # Username of current user
-    r'\u': USER,
-    # Escaped '\'
-    '\\\\': '\\',
-    # Newline
-    r'\n': '\n',
-    # Carriage return
-    r'\r': '\r',
-    # Release version
-    r'\v': release.version,
-    # Root symbol ($ or #)
-    r'\$': ROOT_SYMBOL,
-    }
-
-#-----------------------------------------------------------------------------
-# More utilities
-#-----------------------------------------------------------------------------
-
-def cwd_filt(depth):
-    """Return the last depth elements of the current working directory.
-
-    $HOME is always replaced with '~'.
-    If depth==0, the full path is returned."""
-
-    cwd = py3compat.getcwd().replace(HOME,"~")
-    out = os.sep.join(cwd.split(os.sep)[-depth:])
-    return out or os.sep
-
-def cwd_filt2(depth):
-    """Return the last depth elements of the current working directory.
-
-    $HOME is always replaced with '~'.
-    If depth==0, the full path is returned."""
-
-    full_cwd = py3compat.getcwd()
-    cwd = full_cwd.replace(HOME,"~").split(os.sep)
-    if '~' in cwd and len(cwd) == depth+1:
-        depth += 1
-    drivepart = ''
-    if sys.platform == 'win32' and len(cwd) > depth:
-        drivepart = os.path.splitdrive(full_cwd)[0]
-    out = drivepart + '/'.join(cwd[-depth:])
-
-    return out or os.sep
-
-#-----------------------------------------------------------------------------
-# Prompt classes
-#-----------------------------------------------------------------------------
-
-lazily_evaluate = {'time': LazyEvaluate(time.strftime, "%H:%M:%S"),
-                   'cwd': LazyEvaluate(py3compat.getcwd),
-                   'cwd_last': LazyEvaluate(lambda: py3compat.getcwd().split(os.sep)[-1]),
-                   'cwd_x': [LazyEvaluate(lambda: py3compat.getcwd().replace(HOME,"~"))] +\
-                            [LazyEvaluate(cwd_filt, x) for x in range(1,6)],
-                   'cwd_y': [LazyEvaluate(cwd_filt2, x) for x in range(6)]
-                   }
-
-def _lenlastline(s):
-    """Get the length of the last line. More intelligent than
-    len(s.splitlines()[-1]).
-    """
-    if not s or s.endswith(('\n', '\r')):
-        return 0
-    return len(s.splitlines()[-1])
-
-
-invisible_chars_re = re.compile('\001[^\001\002]*\002')
-def _invisible_characters(s):
-    """
-    Get the number of invisible ANSI characters in s. Invisible characters
-    must be delimited by \001 and \002.
-    """
-    return _lenlastline(s) - _lenlastline(invisible_chars_re.sub('', s))
-
-class UserNSFormatter(Formatter):
-    """A Formatter that falls back on a shell's user_ns and __builtins__ for name resolution"""
-    def __init__(self, shell):
-        self.shell = shell
-
-    def get_value(self, key, args, kwargs):
-        # try regular formatting first:
-        try:
-            return Formatter.get_value(self, key, args, kwargs)
-        except Exception:
-            pass
-        # next, look in user_ns and builtins:
-        for container in (self.shell.user_ns, __builtins__):
-            if key in container:
-                return container[key]
-        # nothing found, put error message in its place
-        return "<ERROR: '%s' not found>" % key
-
-
-class PromptManager(Configurable):
-    """This is the primary interface for producing IPython's prompts."""
-    shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
-
-    color_scheme_table = Instance(coloransi.ColorSchemeTable, allow_none=True)
-    color_scheme = Unicode('Linux').tag(config=True)
-
-    @observe('color_scheme')
-    def _color_scheme_changed(self, change):
-        self.color_scheme_table.set_active_scheme(change['new'])
-        for pname in ['in', 'in2', 'out', 'rewrite']:
-            # We need to recalculate the number of invisible characters
-            self.update_prompt(pname)
-
-    lazy_evaluate_fields = Dict(help="""
-        This maps field names used in the prompt templates to functions which
-        will be called when the prompt is rendered. This allows us to include
-        things like the current time in the prompts. Functions are only called
-        if they are used in the prompt.
-        """)
-
-    in_template = Unicode('In [\\#]: ',
-        help="Input prompt.  '\\#' will be transformed to the prompt number"
-        ).tag(config=True)
-    in2_template = Unicode('   .\\D.: ',
-        help="Continuation prompt.").tag(config=True)
-    out_template = Unicode('Out[\\#]: ',
-        help="Output prompt. '\\#' will be transformed to the prompt number"
-        ).tag(config=True)
-
-    @default('lazy_evaluate_fields')
-    def _lazy_evaluate_fields_default(self):
-        return lazily_evaluate.copy()
-
-    justify = Bool(True, help="""
-        If True (default), each prompt will be right-aligned with the
-        preceding one.
-        """).tag(config=True)
-
-    # We actually store the expanded templates here:
-    templates = Dict()
-
-    # The number of characters in the last prompt rendered, not including
-    # colour characters.
-    width = Int()
-    txtwidth = Int()   # Not including right-justification
-
-    # The number of characters in each prompt which don't contribute to width
-    invisible_chars = Dict()
-
-    @default('invisible_chars')
-    def _invisible_chars_default(self):
-        return {'in': 0, 'in2': 0, 'out': 0, 'rewrite':0}
-
-    def __init__(self, shell, **kwargs):
-        super(PromptManager, self).__init__(shell=shell, **kwargs)
-
-        # Prepare colour scheme table
-        self.color_scheme_table = coloransi.ColorSchemeTable([NoColor,
-                                    LinuxColors, LightBGColors], self.color_scheme)
-
-        self._formatter = UserNSFormatter(shell)
-        # Prepare templates & numbers of invisible characters
-        self.update_prompt('in', self.in_template)
-        self.update_prompt('in2', self.in2_template)
-        self.update_prompt('out', self.out_template)
-        self.update_prompt('rewrite')
-        self.observe(self._update_prompt_trait,
-            names=['in_template', 'in2_template', 'out_template'])
-
-    def update_prompt(self, name, new_template=None):
-        """This is called when a prompt template is updated. It processes
-        abbreviations used in the prompt template (like \#) and calculates how
-        many invisible characters (ANSI colour escapes) the resulting prompt
-        contains.
-
-        It is also called for each prompt on changing the colour scheme. In both
-        cases, traitlets should take care of calling this automatically.
-        """
-        if new_template is not None:
-            self.templates[name] = multiple_replace(prompt_abbreviations, new_template)
-        # We count invisible characters (colour escapes) on the last line of the
-        # prompt, to calculate the width for lining up subsequent prompts.
-        invis_chars = _invisible_characters(self._render(name, color=True))
-        self.invisible_chars[name] = invis_chars
-
-    def _update_prompt_trait(self, changes):
-        traitname = changes['name']
-        new_template = changes['new']
-        name = traitname[:-9]   # Cut off '_template'
-        self.update_prompt(name, new_template)
-
-    def _render(self, name, color=True, **kwargs):
-        """Render but don't justify, or update the width or txtwidth attributes.
-        """
-        if name == 'rewrite':
-            return self._render_rewrite(color=color)
-
-        if color:
-            scheme = self.color_scheme_table.active_colors
-            if name=='out':
-                colors = color_lists['normal']
-                colors.number, colors.prompt, colors.normal = \
-                        scheme.out_number, scheme.out_prompt, scheme.normal
-            else:
-                colors = color_lists['inp']
-                colors.number, colors.prompt, colors.normal = \
-                        scheme.in_number, scheme.in_prompt, scheme.in_normal
-                if name=='in2':
-                    colors.prompt = scheme.in_prompt2
-        else:
-            # No color
-            colors = color_lists['nocolor']
-            colors.number, colors.prompt, colors.normal = '', '', ''
-
-        count = self.shell.execution_count    # Shorthand
-        # Build the dictionary to be passed to string formatting
-        fmtargs = dict(color=colors, count=count,
-                       dots="."*len(str(count)), spaces=" "*len(str(count)),
-                       width=self.width, txtwidth=self.txtwidth)
-        fmtargs.update(self.lazy_evaluate_fields)
-        fmtargs.update(kwargs)
-
-        # Prepare the prompt
-        prompt = colors.prompt + self.templates[name] + colors.normal
-
-        # Fill in required fields
-        return self._formatter.format(prompt, **fmtargs)
-
-    def _render_rewrite(self, color=True):
-        """Render the ---> rewrite prompt."""
-        if color:
-            scheme = self.color_scheme_table.active_colors
-            # We need a non-input version of these escapes
-            color_prompt = scheme.in_prompt.replace("\001","").replace("\002","")
-            color_normal = scheme.normal
-        else:
-            color_prompt, color_normal = '', ''
-
-        return color_prompt + "-> ".rjust(self.txtwidth, "-") + color_normal
-
-    def render(self, name, color=True, just=None, **kwargs):
-        """
-        Render the selected prompt.
-
-        Parameters
-        ----------
-        name : str
-          Which prompt to render. One of 'in', 'in2', 'out', 'rewrite'
-        color : bool
-          If True (default), include ANSI escape sequences for a coloured prompt.
-        just : bool
-          If True, justify the prompt to the width of the last prompt. The
-          default is stored in self.justify.
-        **kwargs :
-          Additional arguments will be passed to the string formatting operation,
-          so they can override the values that would otherwise fill in the
-          template.
-
-        Returns
-        -------
-        A string containing the rendered prompt.
-        """
-        res = self._render(name, color=color, **kwargs)
-
-        # Handle justification of prompt
-        invis_chars = self.invisible_chars[name] if color else 0
-        self.txtwidth = _lenlastline(res) - invis_chars
-        just = self.justify if (just is None) else just
-        # If the prompt spans more than one line, don't try to justify it:
-        if just and name != 'in' and ('\n' not in res) and ('\r' not in res):
-            res = res.rjust(self.width + invis_chars)
-        self.width = _lenlastline(res) - invis_chars
-        return res
diff --git a/IPython/core/tests/test_prompts.py b/IPython/core/tests/test_prompts.py
index 024ebaa..6595dab 100644
--- a/IPython/core/tests/test_prompts.py
+++ b/IPython/core/tests/test_prompts.py
@@ -3,75 +3,14 @@
 
 import unittest
 
-import os
-
-from IPython.testing import tools as tt, decorators as dec
-from IPython.core.prompts import PromptManager, LazyEvaluate, _invisible_characters
+from IPython.core.prompts import  LazyEvaluate
 from IPython.testing.globalipapp import get_ipython
-from IPython.utils.tempdir import TemporaryWorkingDirectory
-from IPython.utils import py3compat
 from IPython.utils.py3compat import unicode_type
 
 ip = get_ipython()
 
 
 class PromptTests(unittest.TestCase):
-    def setUp(self):
-        self.pm = PromptManager(shell=ip, config=ip.config)
-    
-    def test_multiline_prompt(self):
-        self.pm.in_template = "[In]\n>>>"
-        self.pm.render('in')
-        self.assertEqual(self.pm.width, 3)
-        self.assertEqual(self.pm.txtwidth, 3)
-        
-        self.pm.in_template = '[In]\n'
-        self.pm.render('in')
-        self.assertEqual(self.pm.width, 0)
-        self.assertEqual(self.pm.txtwidth, 0)
-    
-    def test_translate_abbreviations(self):
-        def do_translate(template):
-            self.pm.in_template = template
-            return self.pm.templates['in']
-        
-        pairs = [(r'%n>', '{color.number}{count}{color.prompt}>'),
-                 (r'\T', '{time}'),
-                 (r'\n', '\n')
-                ]
-    
-        tt.check_pairs(do_translate, pairs)
-    
-    def test_user_ns(self):
-        self.pm.color_scheme = 'NoColor'
-        ip.ex("foo='bar'")
-        self.pm.in_template = "In [{foo}]"
-        prompt = self.pm.render('in')
-        self.assertEqual(prompt, u'In [bar]')
-
-    def test_builtins(self):
-        self.pm.color_scheme = 'NoColor'
-        self.pm.in_template = "In [{int}]"
-        prompt = self.pm.render('in')
-        self.assertEqual(prompt, u"In [%r]" % int)
-
-    def test_undefined(self):
-        self.pm.color_scheme = 'NoColor'
-        self.pm.in_template = "In [{foo_dne}]"
-        prompt = self.pm.render('in')
-        self.assertEqual(prompt, u"In [<ERROR: 'foo_dne' not found>]")
-
-    def test_render(self):
-        self.pm.in_template = r'\#>'
-        self.assertEqual(self.pm.render('in',color=False), '%d>' % ip.execution_count)
-    
-    @dec.onlyif_unicode_paths
-    def test_render_unicode_cwd(self):
-        with TemporaryWorkingDirectory(u'ünicødé'):
-            self.pm.in_template = r'\w [\#]'
-            p = self.pm.render('in', color=False)
-            self.assertEqual(p, u"%s [%i]" % (py3compat.getcwd(), ip.execution_count))
-    
     def test_lazy_eval_unicode(self):
         u = u'ünicødé'
         lz = LazyEvaluate(lambda : u)
@@ -95,35 +34,4 @@ class PromptTests(unittest.TestCase):
         self.assertEqual(unicode_type(lz), unicode_type(f))
         self.assertEqual(format(lz), str(f))
         self.assertEqual(format(lz, '.1'), '0.5')
-    
-    @dec.skip_win32
-    def test_cwd_x(self):
-        self.pm.in_template = r"\X0"
-        save = py3compat.getcwd()
-        os.chdir(os.path.expanduser('~'))
-        p = self.pm.render('in', color=False)
-        try:
-            self.assertEqual(p, '~')
-        finally:
-            os.chdir(save)
-
-    def test_invisible_chars(self):
-        self.assertEqual(_invisible_characters('abc'), 0)
-        self.assertEqual(_invisible_characters('\001\033[1;37m\002'), 9)
-        # Sequences must be between \001 and \002 to be counted
-        self.assertEqual(_invisible_characters('\033[1;37m'), 0)
-        # Test custom escape sequences
-        self.assertEqual(_invisible_characters('\001\033]133;A\a\002'), 10)
-
-    def test_width(self):
-        default_in = '\x01\x1b]133;A\x07\x02In [1]: \x01\x1b]133;B\x07\x02'
-        self.pm.in_template = default_in
-        self.pm.render('in')
-        self.assertEqual(self.pm.width, 8)
-        self.assertEqual(self.pm.txtwidth, 8)
 
-        # Test custom escape sequences
-        self.pm.in_template = '\001\033]133;A\a\002' + default_in + '\001\033]133;B\a\002'
-        self.pm.render('in')
-        self.assertEqual(self.pm.width, 8)
-        self.assertEqual(self.pm.txtwidth, 8)
diff --git a/IPython/core/tests/test_run.py b/IPython/core/tests/test_run.py
index 5e64fb2..e3ade57 100644
--- a/IPython/core/tests/test_run.py
+++ b/IPython/core/tests/test_run.py
@@ -205,13 +205,6 @@ class TestMagicRunPass(tt.TempFileMixin):
         _ip = get_ipython()
         self.run_tmpfile()
         nt.assert_equal(type(_ip.user_ns['__builtins__']),type(sys))
-
-    def test_prompts(self):
-        """Test that prompts correctly generate after %run"""
-        self.run_tmpfile()
-        _ip = get_ipython()
-        p2 = _ip.prompt_manager.render('in2').strip()
-        nt.assert_equal(p2[:3], '...')
         
     def test_run_profile( self ):
         """Test that the option -p, which invokes the profiler, do not
diff --git a/IPython/core/tests/test_shellapp.py b/IPython/core/tests/test_shellapp.py
index 6e2e31b..8e15743 100644
--- a/IPython/core/tests/test_shellapp.py
+++ b/IPython/core/tests/test_shellapp.py
@@ -52,10 +52,9 @@ class TestFileToRun(unittest.TestCase, tt.TempFileMixin):
         src = "True\n"
         self.mktmp(src)
 
-        out = 'In [1]: False\n\nIn [2]:'
-        err = SQLITE_NOT_AVAILABLE_ERROR if sqlite_err_maybe else None
-        tt.ipexec_validate(self.fname, out, err, options=['-i'],
+        out, err = tt.ipexec(self.fname, options=['-i'],
                            commands=['"__file__" in globals()', 'exit()'])
+        self.assertIn("False", out)
 
     @dec.skip_win32
     @dec.skipif(PY3)
@@ -64,7 +63,6 @@ class TestFileToRun(unittest.TestCase, tt.TempFileMixin):
         src = "from __future__ import division\n"
         self.mktmp(src)
 
-        out = 'In [1]: float\n\nIn [2]:'
-        err = SQLITE_NOT_AVAILABLE_ERROR if sqlite_err_maybe else None
-        tt.ipexec_validate(self.fname, out, err, options=['-i'],
+        out, err = tt.ipexec(self.fname, options=['-i'],
                            commands=['type(1/2)', 'exit()'])
+        self.assertIn('float', out)
diff --git a/IPython/sphinxext/ipython_directive.py b/IPython/sphinxext/ipython_directive.py
index eb1219f..7c13cd4 100644
--- a/IPython/sphinxext/ipython_directive.py
+++ b/IPython/sphinxext/ipython_directive.py
@@ -898,7 +898,6 @@ class IPythonDirective(Directive):
         if not self.state.document.current_source in self.seen_docs:
             self.shell.IP.history_manager.reset()
             self.shell.IP.execution_count = 1
-            self.shell.IP.prompt_manager.width = 0
             self.seen_docs.add(self.state.document.current_source)
 
         # and attach to shell so we don't have to pass them around
diff --git a/IPython/terminal/interactiveshell.py b/IPython/terminal/interactiveshell.py
index 85f17af..1c1eaef 100644
--- a/IPython/terminal/interactiveshell.py
+++ b/IPython/terminal/interactiveshell.py
@@ -614,7 +614,7 @@ class TerminalInteractiveShell(InteractiveShell):
             self.hooks.pre_prompt_hook()
             if more:
                 try:
-                    prompt = self.prompt_manager.render('in2')
+                    prompt = '   ...: '
                 except:
                     self.showtraceback()
                 if self.autoindent:
@@ -622,7 +622,7 @@ class TerminalInteractiveShell(InteractiveShell):
 
             else:
                 try:
-                    prompt = self.separate_in + self.prompt_manager.render('in')
+                    prompt = self.separate_in + 'In [{}]: '.format(self.execution_count)
                 except:
                     self.showtraceback()
             try:
diff --git a/IPython/terminal/ipapp.py b/IPython/terminal/ipapp.py
index b39eb52..d0470a1 100755
--- a/IPython/terminal/ipapp.py
+++ b/IPython/terminal/ipapp.py
@@ -24,7 +24,6 @@ from IPython.core.completer import IPCompleter
 from IPython.core.crashhandler import CrashHandler
 from IPython.core.formatters import PlainTextFormatter
 from IPython.core.history import HistoryManager
-from IPython.core.prompts import PromptManager
 from IPython.core.application import (
     ProfileDir, BaseIPythonApplication, base_flags, base_aliases
 )
@@ -195,7 +194,6 @@ class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
             InteractiveShellApp, # ShellApp comes before TerminalApp, because
             self.__class__,      # it will also affect subclasses (e.g. QtConsole)
             TerminalInteractiveShell,
-            PromptManager,
             HistoryManager,
             ProfileDir,
             PlainTextFormatter,
diff --git a/IPython/terminal/prompts.py b/IPython/terminal/prompts.py
new file mode 100644
index 0000000..9547128
--- /dev/null
+++ b/IPython/terminal/prompts.py
@@ -0,0 +1,73 @@
+"""Terminal input and output prompts."""
+from __future__ import print_function
+
+from pygments.token import Token
+import sys
+
+from IPython.core.displayhook import DisplayHook
+
+class Prompts(object):
+    def __init__(self, shell):
+        self.shell = shell
+
+    def in_prompt_tokens(self, cli=None):
+        return [
+            (Token.Prompt, 'In ['),
+            (Token.PromptNum, str(self.shell.execution_count)),
+            (Token.Prompt, ']: '),
+        ]
+
+    def _width(self):
+        in_tokens = self.in_prompt_tokens()
+        return sum(len(s) for (t, s) in in_tokens)
+
+    def continuation_prompt_tokens(self, cli=None, width=None):
+        if width is None:
+            width = self._width()
+        return [
+            (Token.Prompt, (' ' * (width - 5)) + '...: '),
+        ]
+
+    def rewrite_prompt_tokens(self):
+        width = self._width()
+        return [
+            (Token.Prompt, ('-' * (width - 2)) + '> '),
+        ]
+
+    def out_prompt_tokens(self):
+        return [
+            (Token.OutPrompt, 'Out['),
+            (Token.OutPromptNum, str(self.shell.execution_count)),
+            (Token.OutPrompt, ']: '),
+        ]
+
+class ClassicPrompts(Prompts):
+    def in_prompt_tokens(self, cli=None):
+        return [
+            (Token.Prompt, '>>> '),
+        ]
+
+    def continuation_prompt_tokens(self, cli=None, width=None):
+        return [
+            (Token.Prompt, '... ')
+        ]
+
+    def rewrite_prompt_tokens(self):
+        return []
+
+    def out_prompt_tokens(self):
+        return []
+
+class RichPromptDisplayHook(DisplayHook):
+    """Subclass of base display hook using coloured prompt"""
+    def write_output_prompt(self):
+        sys.stdout.write(self.shell.separate_out)
+        self.prompt_end_newline = False
+        if self.do_full_cache:
+            tokens = self.shell.prompts.out_prompt_tokens()
+            if tokens and tokens[-1][1].endswith('\n'):
+                self.prompt_end_newline = True
+            if self.shell.pt_cli:
+                self.shell.pt_cli.print_tokens(tokens)
+            else:
+                print(*(s for t, s in tokens), sep='')
diff --git a/IPython/terminal/ptshell.py b/IPython/terminal/ptshell.py
index cb63634..3c34d7c 100644
--- a/IPython/terminal/ptshell.py
+++ b/IPython/terminal/ptshell.py
@@ -11,7 +11,7 @@ from IPython.core.interactiveshell import InteractiveShell
 from IPython.utils.py3compat import cast_unicode_py2, input
 from IPython.utils.terminal import toggle_set_term_title, set_term_title
 from IPython.utils.process import abbrev_cwd
-from traitlets import Bool, Unicode, Dict, Integer, observe
+from traitlets import Bool, Unicode, Dict, Integer, observe, Instance
 
 from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER, EditingMode
 from prompt_toolkit.filters import HasFocus, HasSelection, Condition, ViInsertMode, EmacsInsertMode, IsDone
@@ -29,6 +29,7 @@ from pygments.token import Token
 from .debugger import TerminalPdb, Pdb
 from .pt_inputhooks import get_inputhook_func
 from .interactiveshell import get_default_editor, TerminalMagics
+from .prompts import Prompts, ClassicPrompts, RichPromptDisplayHook
 from .ptutils import IPythonPTCompleter, IPythonPTLexer
 
 _use_simple_prompt = 'IPY_TEST_SIMPLE_PROMPT' in os.environ or not sys.stdin.isatty()
@@ -98,7 +99,19 @@ class TerminalInteractiveShell(InteractiveShell):
     editor = Unicode(get_default_editor(),
         help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
     ).tag(config=True)
-    
+
+    prompts = Instance(Prompts)
+
+    def _prompts_default(self):
+        return Prompts(self)
+
+    @observe('prompts')
+    def _(self, change):
+        self._update_layout()
+
+    def _displayhook_class_default(self):
+        return RichPromptDisplayHook
+
     term_title = Bool(True,
         help="Automatically set the terminal title"
     ).tag(config=True)
@@ -120,18 +133,6 @@ class TerminalInteractiveShell(InteractiveShell):
         else:
             toggle_set_term_title(False)
 
-    def get_prompt_tokens(self, cli):
-        return [
-            (Token.Prompt, 'In ['),
-            (Token.PromptNum, str(self.execution_count)),
-            (Token.Prompt, ']: '),
-        ]
-
-    def get_continuation_tokens(self, cli, width):
-        return [
-            (Token.Prompt, (' ' * (width - 5)) + '...: '),
-        ]
-
     def init_prompt_toolkit_cli(self):
         if self.simple_prompt:
             # Fall back to plain non-interactive output for tests.
@@ -234,6 +235,8 @@ class TerminalInteractiveShell(InteractiveShell):
         style_overrides = {
             Token.Prompt: '#009900',
             Token.PromptNum: '#00ff00 bold',
+            Token.OutPrompt: '#990000',
+            Token.OutPromptNum: '#ff0000 bold',
         }
         if name == 'default':
             style_cls = get_style_by_name('default')
@@ -261,8 +264,8 @@ class TerminalInteractiveShell(InteractiveShell):
         return {
                 'lexer':IPythonPTLexer(),
                 'reserve_space_for_menu':self.space_for_menu,
-                'get_prompt_tokens':self.get_prompt_tokens,
-                'get_continuation_tokens':self.get_continuation_tokens,
+                'get_prompt_tokens':self.prompts.in_prompt_tokens,
+                'get_continuation_tokens':self.prompts.continuation_prompt_tokens,
                 'multiline':True,
                 'display_completions_in_columns': self.display_completions_in_columns,
 
@@ -439,6 +442,29 @@ class TerminalInteractiveShell(InteractiveShell):
     # work correctly.
     system = InteractiveShell.system_raw
 
+    def auto_rewrite_input(self, cmd):
+        """Overridden from the parent class to use fancy rewriting prompt"""
+        if not self.show_rewritten_input:
+            return
+
+        tokens = self.prompts.rewrite_prompt_tokens()
+        if self.pt_cli:
+            self.pt_cli.print_tokens(tokens)
+            print(cmd)
+        else:
+            prompt = ''.join(s for t, s in tokens)
+            print(prompt, cmd, sep='')
+
+    _prompts_before = None
+    def switch_doctest_mode(self, mode):
+        """Switch prompts to classic for %doctest_mode"""
+        if mode:
+            self._prompts_before = self.prompts
+            self.prompts = ClassicPrompts(self)
+        elif self._prompts_before:
+            self.prompts = self._prompts_before
+            self._prompts_before = None
+
 
 if __name__ == '__main__':
     TerminalInteractiveShell.instance().interact()
diff --git a/IPython/testing/tools.py b/IPython/testing/tools.py
index 73f4ee7..bf62f30 100644
--- a/IPython/testing/tools.py
+++ b/IPython/testing/tools.py
@@ -202,13 +202,7 @@ def ipexec(fname, options=None, commands=()):
     """
     if options is None: options = []
 
-    # For these subprocess calls, eliminate all prompt printing so we only see
-    # output from script execution
-    prompt_opts = [ '--PromptManager.in_template=""',
-                    '--PromptManager.in2_template=""',
-                    '--PromptManager.out_template=""'
-    ]
-    cmdargs = default_argv() + prompt_opts + options
+    cmdargs = default_argv() + options
 
     test_dir = os.path.dirname(__file__)
 
diff --git a/docs/source/config/details.rst b/docs/source/config/details.rst
index c8b01c7..3f7414b 100644
--- a/docs/source/config/details.rst
+++ b/docs/source/config/details.rst
@@ -2,52 +2,6 @@
 Specific config details
 =======================
 
-Prompts
-=======
-
-In the terminal, the format of the input and output prompts can be
-customised. This does not currently affect other frontends.
-
-The following codes in the prompt string will be substituted into the
-prompt string:
-
-======  ===================================  =====================================================
-Short   Long                                 Notes
-======  ===================================  =====================================================
-%n,\\#  {color.number}{count}{color.prompt}  history counter with bolding
-\\N     {count}                              history counter without bolding
-\\D     {dots}                               series of dots the same width as the history counter
-\\T     {time}                               current time
-\\w     {cwd}                                current working directory
-\\W     {cwd_last}                           basename of CWD
-\\Xn    {cwd_x[n]}                           Show the last n terms of the CWD. n=0 means show all.
-\\Yn    {cwd_y[n]}                           Like \Xn, but show '~' for $HOME
-\\h                                          hostname, up to the first '.'
-\\H                                          full hostname
-\\u                                          username (from the $USER environment variable)
-\\v                                          IPython version
-\\$                                          root symbol ("$" for normal user or "#" for root)
-``\\``                                       escaped '\\'
-\\n                                          newline
-\\r                                          carriage return
-n/a     {color.<Name>}                       set terminal colour - see below for list of names
-======  ===================================  =====================================================
-
-Available colour names are: Black, BlinkBlack, BlinkBlue, BlinkCyan,
-BlinkGreen, BlinkLightGray, BlinkPurple, BlinkRed, BlinkYellow, Blue,
-Brown, Cyan, DarkGray, Green, LightBlue, LightCyan, LightGray, LightGreen,
-LightPurple, LightRed, Purple, Red, White, Yellow. The selected colour
-scheme also defines the names *prompt* and *number*. Finally, the name
-*normal* resets the terminal to its default colour.
-
-So, this config::
-
-     c.PromptManager.in_template = "{color.LightGreen}{time}{color.Yellow} \u{color.normal}>>>"
-
-will produce input prompts with the time in light green, your username
-in yellow, and a ``>>>`` prompt in the default terminal colour.
-
-
 .. _termcolour:
 
 Terminal Colors
@@ -84,27 +38,10 @@ These have shown problems:
       extensions. Once Gary's readline library is installed, the normal
       WinXP/2k command prompt works perfectly.
 
-Currently the following color schemes are available:
-
-    * NoColor: uses no color escapes at all (all escapes are empty '' ''
-      strings). This 'scheme' is thus fully safe to use in any terminal.
-    * Linux: works well in Linux console type environments: dark
-      background with light fonts. It uses bright colors for
-      information, so it is difficult to read if you have a light
-      colored background.
-    * LightBG: the basic colors are similar to those in the Linux scheme
-      but darker. It is easy to read in terminals with light backgrounds.
-
 IPython uses colors for two main groups of things: prompts and
 tracebacks which are directly printed to the terminal, and the object
 introspection system which passes large sets of data through a pager.
 
-If you are seeing garbage sequences in your terminal and no colour, you
-may need to disable colours: run ``%colors NoColor`` inside IPython, or
-add this to a config file::
-
-    c.InteractiveShell.colors = 'NoColor'
-
 Colors in the pager
 -------------------
 
diff --git a/docs/source/config/intro.rst b/docs/source/config/intro.rst
index f91e701..d3ab800 100644
--- a/docs/source/config/intro.rst
+++ b/docs/source/config/intro.rst
@@ -73,11 +73,6 @@ Example config file
     c.InteractiveShell.editor = 'nano'
     c.InteractiveShell.xmode = 'Context'
 
-    c.PromptManager.in_template  = 'In [\#]: '
-    c.PromptManager.in2_template = '   .\D.: '
-    c.PromptManager.out_template = 'Out[\#]: '
-    c.PromptManager.justify = True
-
     c.PrefilterManager.multi_line_specials = True
 
     c.AliasManager.user_aliases = [
diff --git a/docs/source/interactive/shell.rst b/docs/source/interactive/shell.rst
index 4ba0f54..5724efb 100644
--- a/docs/source/interactive/shell.rst
+++ b/docs/source/interactive/shell.rst
@@ -63,20 +63,46 @@ switching to any of them. Type ``cd?`` for more details.
 Prompt customization
 ====================
 
-Here are some prompt configurations you can try out interactively by using the
-``%config`` magic::
-    
-    %config PromptManager.in_template = r'{color.LightGreen}\u@\h{color.LightBlue}[{color.LightCyan}\Y1{color.LightBlue}]{color.Green}|\#> '
-    %config PromptManager.in2_template = r'{color.Green}|{color.LightGreen}\D{color.Green}> '
-    %config PromptManager.out_template = r'<\#> '
-
-
-You can change the prompt configuration to your liking permanently by editing
-``ipython_config.py``::
-    
-    c.PromptManager.in_template = r'{color.LightGreen}\u@\h{color.LightBlue}[{color.LightCyan}\Y1{color.LightBlue}]{color.Green}|\#> '
-    c.PromptManager.in2_template = r'{color.Green}|{color.LightGreen}\D{color.Green}> '
-    c.PromptManager.out_template = r'<\#> '
+Starting at IPython 5.0 the prompt customisation is done by subclassing :class:`IPython.terminal.prompts.Prompt`.
+
+The custom ``Prompt`` receive the current IPython shell instance as first
+argument, which by default is stored as the ``shell`` attribute of the object.
+The class can implement optional methods for each of the available prompt types:
+
+  - ``in_prompt_tokens(self, cli=None)``, input prompt , default to ``In [1]``
+  - ``continuation_prompt_tokens(self, cli=None, width=None)``, continuation prompt for multi lines (default `...:`)
+  - ``rewrite_prompt_tokens(self)``
+  - ``out_prompt_tokens(self)``
+
+Each of these methods should return a list of `(TokenType, Token)` pairs. See documentation of `prompt_toolkit` and/or `Pygments`. 
+
+Here is an example of Prompt class that will insert the current working directory in front of a prompt:
+
+
+.. codeblock:: python 
+
+    from IPython.terminal.prompts import Prompts, Token
+    import os
+
+    class MyPrompt(Prompts):
+
+         def in_prompt_tokens(self, cli=None):
+             return [(Token, os.getcwd()),
+                     (Token.Prompt, ' >>>')]
+
+To set the new prompt, assign it to the `prompts` attribute of the IPython shell:
+
+.. codeblock:: python
+
+    In[2]: ip = get_ipython()
+      ...: ip.prompts = MyPrompt(ip)
+
+    ~/ >>> # it works
+
+
+See ``IPython/example/utils/cwd_prompt.py`` for an example of how to write an
+extensions that customise prompts. 
+
 
 Read more about the :ref:`configuration system <config_overview>` for details
 on how to find ``ipython_config.py``.
diff --git a/examples/utils/cwd_prompt.py b/examples/utils/cwd_prompt.py
new file mode 100644
index 0000000..1d1b03a
--- /dev/null
+++ b/examples/utils/cwd_prompt.py
@@ -0,0 +1,26 @@
+"""This is an example that shows how to create new prompts for IPython
+"""
+
+from IPython.terminal.prompts import Prompts, Token
+import os
+
+class MyPrompt(Prompts):
+
+     def in_prompt_tokens(self, cli=None):
+         return [(Token, os.getcwd()),
+                 (Token.Prompt, '>>>')]
+
+def load_ipython_extension(shell):
+    new_prompts = MyPrompt(shell)
+    new_prompts.old_prompts = shell.prompts
+    shell.prompts = new_prompts
+
+def unload_ipython_extension(shell):
+    if not hasattr(shell.prompts, 'old_prompts'):
+        print("cannot unload")
+    else:
+        shell.prompts = shell.prompts.old_prompts
+
+
+
+