merge with stable
diff --git a/AUTHORS b/AUTHORS
index 2a9dbba..ce4f4bf 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -3,6 +3,15 @@
 Substantial parts of the templates were written by Armin Ronacher
 <armin.ronacher@active-4.com>.
 
+Other co-maintainers:
+
+* Takayuki Shimizukawa <shimizukawa@gmail.com>
+* Daniel Neuhäuser <@DasIch>
+* Jon Waltman <@jonwaltman>
+* Rob Ruana <@RelentlessIdiot>
+* Robert Lehmann <@lehmannro>
+* Roland Meister <@rolmei>
+
 Other contributors, listed alphabetically, are:
 
 * Andi Albrecht -- agogo theme
@@ -32,6 +41,7 @@
 * Christopher Perkins -- autosummary integration
 * Benjamin Peterson -- unittests
 * T. Powers -- HTML output improvements
+* Rob Ruana -- napoleon extension
 * Stefan Seefeld -- toctree improvements
 * Shibukawa Yoshiki -- pluggable search API and Japanese search
 * Antonio Valentino -- qthelp builder
diff --git a/CHANGES b/CHANGES
index a0aa269..6279c44 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,17 +1,236 @@
-Release 1.2.4 (in development)
-==============================
+Release 1.3 (in development)
+============================
+
+Incompatible changes
+--------------------
+
+* Dropped support for Python 2.5, 3.1 and 3.2.
+* Dropped support for docutils versions up to 0.9.
+* Removed the ``sphinx.ext.oldcmarkup`` extension.
+* The deprecated config values ``exclude_trees``, ``exclude_dirnames`` and
+  ``unused_docs`` have been removed.
+* A new node, ``sphinx.addnodes.literal_strong``, has been added, for text that
+  should appear literally (i.e. no smart quotes) in strong font.  Custom writers
+  will have to be adapted to handle this node.
+* PR#269, #1476: replace `<tt>` tag by `<code>`. User customized stylesheets
+  should be updated If the css contain some styles for `<tt>` tag.
+  Thanks to Takeshi Komiya.
+* #1543: :confval:`templates_path` is automatically added to
+  :confval:`exclude_patterns` to avoid reading autosummary rst templates in the
+  templates directory.
 
 Features added
 --------------
 
+* Add support for Python 3.4.
+* Add support for docutils 0.12
+* Added ``sphinx.ext.napoleon`` extension for NumPy and Google style docstring
+  support.
 * Exception logs now contain the last 10 messages emitted by Sphinx.
+* Added support for extension versions (a string returned by ``setup()``, these
+  can be shown in the traceback log files).  Version requirements for extensions
+  can be specified in projects using the new :confval:`needs_extensions` config
+  value.
+* PR#214: Added stemming support for 14 languages, so that the built-in document
+  search can now handle these.  Thanks to Shibukawa Yoshiki.
+* PR#202: Allow "." and "~" prefixed references in ``:param:`` doc fields
+  for Python.
+* PR#184: Add :confval:`autodoc_mock_imports`, allowing to mock imports of
+  external modules that need not be present when autodocumenting.
+* #925: Allow list-typed config values to be provided on the command line,
+  like ``-D key=val1,val2``.
+* #668: Allow line numbering of ``code-block`` and ``literalinclude`` directives
+  to start at an arbitrary line number, with a new ``lineno-start`` option.
+* PR#172, PR#266: The :rst:dir:`code-block` and :rst:dir:`literalinclude`
+  directives now can have a ``caption`` option that shows a filename before the
+  code in the output. Thanks to Nasimul Haque, Takeshi Komiya.
+* Prompt for the document language in sphinx-quickstart.
+* PR#217: Added config values to suppress UUID and location information in
+  generated gettext catalogs.
+* PR#236, #1456: apidoc: Add a -M option to put module documentation before
+  submodule documentation. Thanks to Wes Turner and Luc Saffre.
+* #1434: Provide non-minified JS files for jquery.js and underscore.js to
+  clarify the source of the minified files.
+* PR#252, #1291: Windows color console support. Thanks to meu31.
+* PR#255: When generating latex references, also insert latex target/anchor
+  for the ids defined on the node. Thanks to Olivier Heurtier.
+* PR#229: Allow registration of other translators. Thanks to Russell Sim.
+* Add app.set_translator() API to register or override a Docutils translator
+  class like :confval:`html_translator_class`.
+* PR#267, #1134: add 'diff' parameter to literalinclude. Thanks to Richard Wall
+  and WAKAYAMA shirou.
+* PR#272: Added 'bizstyle' theme. Thanks to Shoji KUMAGAI.
+* Automatically compile ``*.mo`` files from ``*.po`` files when
+  :confval:`gettext_auto_build` is True (default) and ``*.po`` is newer than
+  ``*.mo`` file.
+* #623: :mod:`~sphinx.ext.viewcode` supports imported function/class aliases.
+* PR#275: :mod:`~sphinx.ext.intersphinx` supports multiple target for the
+  inventory. Thanks to Brigitta Sipocz.
 
 Bugs fixed
 ----------
 
+* #1568: fix a crash when a "centered" directive contains a reference.
 * #1563: :meth:`~sphinx.application.Sphinx.add_search_language` raises
   AssertionError for correct type of argument. Thanks to rikoman.
-* #1568: fix a crash when a "centered" directive contains a reference.  
+* #1174: Fix smart quotes being applied inside roles like :rst:role:`program` or
+  :rst:role:`makevar`.
+* #1335: Fix autosummary template overloading with exclamation prefix like
+  ``{% extends "!autosummary/class.rst" %}`` cause infinite recursive function
+  call. This was caused by PR#181.
+* #1337: Fix autodoc with ``autoclass_content="both"`` uses useless
+  ``object.__init__`` docstring when class does not have ``__init__``.
+  This was caused by a change for #1138.
+* #1340: Can't search alphabetical words on the HTML quick search generated
+  with language='ja'.
+* #1319: Do not crash if the :confval:`html_logo` file does not exist.
+* #603: Do not use the HTML-ized title for building the search index (that
+  resulted in "literal" being found on every page with a literal in the
+  title).
+* #751: Allow production lists longer than a page in LaTeX by using longtable.
+* #764: Always look for stopwords lowercased in JS search.
+* #814: autodoc: Guard against strange type objects that don't have
+  ``__bases__``.
+* #932: autodoc: Do not crash if ``__doc__`` is not a string.
+* #933: Do not crash if an :rst:role:`option` value is malformed (contains
+  spaces but no option name).
+* #908: On Python 3, handle error messages from LaTeX correctly in the pngmath
+  extension.
+* #943: In autosummary, recognize "first sentences" to pull from the docstring
+  if they contain uppercase letters.
+* #923: Take the entire LaTeX document into account when caching
+  pngmath-generated images.  This rebuilds them correctly when
+  :confval:`pngmath_latex_preamble` changes.
+* #901: Emit a warning when using docutils' new "math" markup without a Sphinx
+  math extension active.
+* #845: In code blocks, when the selected lexer fails, display line numbers
+  nevertheless if configured.
+* #929: Support parsed-literal blocks in LaTeX output correctly.
+* #949: Update the tabulary.sty packed with Sphinx.
+* #1050: Add anonymous labels into ``objects.inv`` to be referenced via
+  :mod:`~sphinx.ext.intersphinx`.
+* #1095: Fix print-media stylesheet being included always in the "scrolls"
+  theme.
+* #1085: Fix current classname not getting set if class description has
+  ``:noindex:`` set.
+* #1181: Report option errors in autodoc directives more gracefully.
+* #1155: Fix autodocumenting C-defined methods as attributes in Python 3.
+* #1233: Allow finding both Python classes and exceptions with the "class" and
+  "exc" roles in intersphinx.
+* #1198: Allow "image" for the "figwidth" option of the :rst:dir:`figure`
+  directive as documented by docutils.
+* #1152: Fix pycode parsing errors of Python 3 code by including two grammar
+  versions for Python 2 and 3, and loading the appropriate version for the
+  running Python version.
+* #1017: Be helpful and tell the user when the argument to :rst:dir:`option`
+  does not match the required format.
+* #1345: Fix two bugs with :confval:`nitpick_ignore`; now you don't have to
+  remove the store environment for changes to have effect.
+* #1072: In the JS search, fix issues searching for upper-cased words by
+  lowercasing words before stemming.
+* #1299: Make behavior of the :rst:dir:`math` directive more consistent and
+  avoid producing empty environments in LaTeX output.
+* #1308: Strip HTML tags from the content of "raw" nodes before feeding it
+  to the search indexer.
+* #1249: Fix duplicate LaTeX page numbering for manual documents.
+* #1292: In the linkchecker, retry HEAD requests when denied by HTTP 405.
+  Also make the redirect code apparent and tweak the output a bit to be
+  more obvious.
+* #1285: Avoid name clashes between C domain objects and section titles.
+* #848: Always take the newest code in incremental rebuilds with the
+  :mod:`sphinx.ext.viewcode` extension.
+* #979, #1266: Fix exclude handling in ``sphinx-apidoc``.
+* #1302: Fix regression in :mod:`sphinx.ext.inheritance_diagram` when
+  documenting classes that can't be pickled.
+* #1316: Remove hard-coded ``font-face`` resources from epub theme.
+* #1329: Fix traceback with empty translation msgstr in .po files.
+* #1300: Fix references not working in translated documents in some instances.
+* #1283: Fix a bug in the detection of changed files that would try to access
+  doctrees of deleted documents.
+* #1330: Fix :confval:`exclude_patterns` behavior with subdirectories in the
+  :confval:`html_static_path`.
+* #1323: Fix emitting empty ``<ul>`` tags in the HTML writer, which is not
+  valid HTML.
+* #1147: Don't emit a sidebar search box in the "singlehtml" builder.
+* PR#211: When checking for existence of the :confval:`html_logo` file, check
+  the full relative path and not the basename.
+* #1357: Option names documented by :rst:dir:`option` are now again allowed to
+  not start with a dash or slash, and referencing them will work correctly.
+* #1358: Fix handling of image paths outside of the source directory when using
+  the "wildcard" style reference.
+* #1374: Fix for autosummary generating overly-long summaries if first line
+  doesn't end with a period.
+* #1391: Actually prevent using "pngmath" and "mathjax" extensions at the same
+  time in sphinx-quickstart.
+* #1386: Fix bug preventing more than one theme being added by the entry point
+  mechanism.
+* #1370: Ignore "toctree" nodes in text writer, instead of raising.
+* #1364: Fix 'make gettext' fails when the '.. todolist::' directive is present.
+* #1367: Fix a change of PR#96 that break sphinx.util.docfields.Field.make_field
+  interface/behavior for `item` argument usage.
+* #1363: Fix i18n: missing python domain's cross-references with currentmodule
+  directive or currentclass directive.
+* #1419: Generated i18n sphinx.js files are missing message catalog entries
+  from '.js_t' and '.html'. The issue was introduced in Sphinx 1.1.
+* #636: Keep straight single quotes in literal blocks in the LaTeX build.
+* PR#235: comment db schema of websupport lacked a length of the node_id field.
+  Thanks to solos.
+* #1466,PR#241: Fix failure of the cpp domain parser to parse C+11
+  "variadic templates" declarations. Thanks to Victor Zverovich.
+* #1459,PR#244: Fix default mathjax js path point to `http://` that cause
+  mixed-content error on HTTPS server. Thanks to sbrandtb and robo9k.
+* PR#157: autodoc remove spurious signatures from @property decorated
+  attributes. Thanks to David Ham.
+* PR#159: Add coverage targets to quickstart generated Makefile and make.bat.
+  Thanks to Matthias Troffaes.
+* #1251: When specifying toctree :numbered: option and :tocdepth: metadata,
+  sub section number that is larger depth than `:tocdepth:` is shrinked.
+* PR#260: Encode underscore in citation labels for latex export. Thanks to
+  Lennart Fricke.
+* PR#264: Fix could not resolve xref for figure node with :name: option.
+  Thanks to Takeshi Komiya.
+* PR#265: Fix could not capture caption of graphviz node by xref. Thanks to
+  Takeshi Komiya.
+* PR#263, #1013, #1103: Rewrite of C++ domain. Thanks to Jakob Lykke Andersen.
+
+  * Hyperlinks to all found nested names and template arguments (#1103).
+  * Support for function types everywhere, e.g., in
+    std::function<bool(int, int)> (#1013).
+  * Support for virtual functions.
+  * Changed interpretation of function arguments to following standard
+    prototype declarations, i.e., void f(arg) means that arg is the type of the
+    argument, instead of it being the name.
+  * Updated tests.
+  * Updated documentation with elaborate description of what declarations are
+    supported and how the namespace declarations influence declaration and
+    cross-reference lookup.
+  * Index names may be different now. Elements are indexed by their fully
+    qualified name. It should be rather easy to change this behaviour and
+    potentially index by namespaces/classes as well.
+
+* PR#258, #939: Add dedent option for :rst:dir:`code-block` and
+  :rst:dir:`literal-include`. Thanks to Zafar Siddiqui.
+* PR#268: Fix numbering section does not work at singlehtml mode. It still
+  ad-hoc fix because there is a issue that section IDs are conflicted.
+  Thanks to Takeshi Komiya.
+* PR#273, #1536: Fix RuntimeError with numbered circular toctree. Thanks to
+  Takeshi Komiya.
+* PR#274: Set its URL as a default title value if URL appears in toctree.
+  Thanks to Takeshi Komiya.
+* PR#276, #1381: :rst:role:`rfc` and :rst:role:`pep` roles support custom link
+  text. Thanks to Takeshi Komiya.
+* PR#277, #1513: highlights for function pointers in argument list of
+  :rst:dir:`c:function`. Thanks to Takeshi Komiya.
+* PR#278: Fix section entries were shown twice if toctree has been put under
+  only directive. Thanks to Takeshi Komiya.
+* #1547: pgen2 tokenizer doesn't recognize `...` literal (Ellipsis for py3).
+
+Documentation
+-------------
+
+* Add clarification about the syntax of tags. (:file:`doc/markup/misc.rst`)
+* #1325: Added a "Intersphinx" tutorial section. (:file:`doc/tutorial.rst`)
+* Extended the :ref:`documentation about building extensions <dev-extensions>`.
 
 
 Release 1.2.3 (released Sep 1, 2014)
@@ -420,7 +639,7 @@
   - The :confval:`latex_documents`, :confval:`texinfo_documents`, and
     :confval:`man_pages` configuration values will be set to default values based
     on the :confval:`master_doc` if not explicitly set in :file:`conf.py`.
-    Previously, if these values were not set, no output would be genereted by
+    Previously, if these values were not set, no output would be generated by
     their respective builders.
 
 * Internationalization:
@@ -461,7 +680,7 @@
   - sphinx-build now provides more specific error messages when called with
     invalid options or arguments.
   - sphinx-build now has a verbose option :option:`-v` which can be repeated for
-    greater effect.  A single occurrance provides a slightly more verbose output
+    greater effect.  A single occurrence provides a slightly more verbose output
     than normal.  Two or more occurrences of this option provides more detailed
     output which may be useful for debugging.
 
@@ -921,7 +1140,7 @@
 * #515: Fix tracebacks in the viewcode extension for Python objects
   that do not have a valid signature.
 
-* Fix strange reportings of line numbers for warnings generated from
+* Fix strange reports of line numbers for warnings generated from
   autodoc-included docstrings, due to different behavior depending
   on docutils version.
 
diff --git a/EXAMPLES b/EXAMPLES
index cc4c4de..17143e9 100644
--- a/EXAMPLES
+++ b/EXAMPLES
@@ -22,18 +22,19 @@
 * Cormoran: http://cormoran.nhopkg.org/docs/
 * Director: http://pythonhosted.org/director/
 * Dirigible: http://www.projectdirigible.com/documentation/
-* Elemental: http://elemental.googlecode.com/hg/doc/build/html/index.html
 * F2py: http://f2py.sourceforge.net/docs/
 * GeoDjango: http://geodjango.org/docs/
-* Genomedata: http://noble.gs.washington.edu/proj/genomedata/doc/1.2.2/genomedata.html
+* Genomedata:
+  http://noble.gs.washington.edu/proj/genomedata/doc/1.2.2/genomedata.html
 * gevent: http://www.gevent.org/
-* Google Wave API: http://wave-robot-python-client.googlecode.com/svn/trunk/pydocs/index.html
+* Google Wave API:
+  http://wave-robot-python-client.googlecode.com/svn/trunk/pydocs/index.html
 * GSL Shell: http://www.nongnu.org/gsl-shell/
 * Heapkeeper: http://heapkeeper.org/
-* Hands-on Python Tutorial: http://anh.cs.luc.edu/python/hands-on/3.1/handsonHtml/
+* Hands-on Python Tutorial:
+  http://anh.cs.luc.edu/python/hands-on/3.1/handsonHtml/
 * Hedge: http://documen.tician.de/hedge/
-* Kaa: http://doc.freevo.org/api/kaa/
-* Leo: http://webpages.charter.net/edreamleo/front.html
+* Leo: http://leoeditor.com/
 * Lino: http://lino.saffre-rumma.net/
 * MeshPy: http://documen.tician.de/meshpy/
 * mpmath: http://mpmath.googlecode.com/svn/trunk/doc/build/index.html
@@ -41,13 +42,13 @@
 * OpenGDA: http://www.opengda.org/gdadoc/html/
 * openWNS: http://docs.openwns.org/
 * Paste: http://pythonpaste.org/script/
-* Paver: http://paver.github.com/paver/
+* Paver: http://paver.github.io/paver/
 * Pioneers and Prominent Men of Utah: http://pioneers.rstebbing.com/
 * Pyccuracy: https://github.com/heynemann/pyccuracy/wiki/
 * PyCuda: http://documen.tician.de/pycuda/
 * Pyevolve: http://pyevolve.sourceforge.net/
 * Pylo: http://documen.tician.de/pylo/
-* PyMQI: http://packages.python.org/pymqi/
+* PyMQI: http://pythonhosted.org/pymqi/
 * PyPubSub: http://pubsub.sourceforge.net/
 * pyrticle: http://documen.tician.de/pyrticle/
 * Python: http://docs.python.org/
@@ -59,7 +60,7 @@
 * SimPy: http://simpy.sourceforge.net/SimPyDocs/index.html
 * SymPy: http://docs.sympy.org/
 * WTForms: http://wtforms.simplecodes.com/docs/
-* z3c: http://docs.carduner.net/z3c-tutorial/
+* z3c: http://www.ibiblio.org/paulcarduner/z3ctutorial/
 
 
 Documentation using a customized version of the default theme
@@ -69,16 +70,19 @@
   http://xoomer.virgilio.it/infinity77/AGW_Docs/index.html
 * Bazaar: http://doc.bazaar.canonical.com/en/
 * CakePHP: http://book.cakephp.org/2.0/en/index.html
-* Chaco: http://code.enthought.com/projects/chaco/docs/html/
+* Chaco: http://docs.enthought.com/chaco/
 * Chef: http://docs.opscode.com/
 * Djagios: http://djagios.org/
 * GetFEM++: http://home.gna.org/getfem/
-* Google or-tools: https://or-tools.googlecode.com/svn/trunk/documentation/user_manual/index.html
+* Google or-tools:
+  https://or-tools.googlecode.com/svn/trunk/documentation/user_manual/index.html
 * GPAW: https://wiki.fysik.dtu.dk/gpaw/
 * Grok: http://grok.zope.org/doc/current/
 * IFM: http://fluffybunny.memebot.com/ifm-docs/index.html
+* Kaa: http://api.freevo.org/kaa-base/
 * LEPL: http://www.acooke.org/lepl/
-* Mayavi: http://code.enthought.com/projects/mayavi/docs/development/html/mayavi
+* Mayavi: http://docs.enthought.com/mayavi/mayavi/
+* NICOS: http://trac.frm2.tum.de/nicos/doc/nicos-master/index.html
 * NOC: http://redmine.nocproject.org/projects/noc
 * NumPy: http://docs.scipy.org/doc/numpy/reference/
 * OpenCV: http://docs.opencv.org/
@@ -92,7 +96,7 @@
 * Varnish: https://www.varnish-cache.org/docs/
 * Zentyal: http://doc.zentyal.org/
 * Zope: http://docs.zope.org/zope2/index.html
-* zc.async: http://packages.python.org/zc.async/1.5.0/
+* zc.async: http://pythonhosted.org/zc.async/1.5.0/
 
 
 Documentation using the sphinxdoc theme
@@ -100,20 +104,16 @@
 
 * Fityk: http://fityk.nieto.pl/
 * MapServer: http://mapserver.org/
-* Matplotlib: http://matplotlib.sourceforge.net/
-* Music21: http://mit.edu/music21/doc/html/contents.html
-* MyHDL: http://www.myhdl.org/doc/0.6/
-* NetworkX: http://networkx.lanl.gov/
+* Matplotlib: http://matplotlib.org/
+* Music21: http://web.mit.edu/music21/doc/index.html
+* NetworkX: http://networkx.github.io/
 * Pweave: http://mpastell.com/pweave/
 * Pyre: http://docs.danse.us/pyre/sphinx/
 * Pysparse: http://pysparse.sourceforge.net/
 * PyTango:
   http://www.tango-controls.org/static/PyTango/latest/doc/html/index.html
-* Python Wild Magic:
-  http://python-wild-magic.googlecode.com/svn/doc/html/index.html
+* Python Wild Magic: http://vmlaker.github.io/pythonwildmagic/
 * Reteisi: http://www.reteisi.org/contents.html
-* Satchmo: http://www.satchmoproject.com/docs/dev/
-* Sphinx: http://sphinx-doc.org/
 * Sqlkit: http://sqlkit.argolinux.org/
 * Tau: http://www.tango-controls.org/static/tau/latest/doc/html/index.html
 * Total Open Station: http://tops.berlios.de/
@@ -125,16 +125,17 @@
 -----------------------------------------
 
 * C/C++ Development with Eclipse: http://eclipsebook.in/ (agogo)
-* Distribute: http://packages.python.org/distribute/ (nature)
 * Jinja: http://jinja.pocoo.org/ (scrolls)
 * jsFiddle: http://doc.jsfiddle.net/ (nature)
-* libLAS: http://liblas.org/ (nature)
+* libLAS: http://www.liblas.org/ (nature)
 * MPipe: http://vmlaker.github.io/mpipe/ (sphinx13)
 * pip: http://pip.openplans.org/ (nature)
+* Pyramid web framework:
+  http://docs.pylonsproject.org/projects/pyramid/en/latest/ (pyramid)
 * Programmieren mit PyGTK und Glade (German):
   http://www.florian-diesch.de/doc/python-und-glade/online/ (agogo)
-* Spring Python: http://springpython.webfactional.com/current/sphinx/index.html
-  (nature)
+* Setuptools: http://pythonhosted.org/setuptools/ (nature)
+* Spring Python: http://docs.spring.io/spring-python/1.2.x/sphinx/html/ (nature)
 * sqlparse: http://python-sqlparse.googlecode.com/svn/docs/api/index.html
   (agogo)
 * Sylli: http://sylli.sourceforge.net/ (nature)
@@ -151,35 +152,42 @@
 * Classy: http://classy.pocoo.org/
 * DEAP: http://deap.gel.ulaval.ca/doc/0.8/index.html
 * Django: http://docs.djangoproject.com/
-* Enterprise Toolkit for Acrobat products: http://www.adobe.com/devnet-docs/acrobatetk/
+* Elemental: http://libelemental.org/documentation/dev/index.html
+* Enterprise Toolkit for Acrobat products:
+  http://www.adobe.com/devnet-docs/acrobatetk/
 * e-cidadania: http://e-cidadania.readthedocs.org/en/latest/
 * Flask: http://flask.pocoo.org/docs/
-* Flask-OpenID: http://packages.python.org/Flask-OpenID/
+* Flask-OpenID: http://pythonhosted.org/Flask-OpenID/
 * Gameduino: http://excamera.com/sphinx/gameduino/
 * GeoServer: http://docs.geoserver.org/
 * Glashammer: http://glashammer.org/
-* Istihza (Turkish Python documentation project): http://www.istihza.com/py2/icindekiler_python.html
+* Istihza (Turkish Python documentation project):
+  http://www.istihza.com/py2/icindekiler_python.html
+* Lasso: http://lassoguide.com/
 * MathJax: http://docs.mathjax.org/en/latest/
 * MirrorBrain: http://mirrorbrain.org/docs/
-* nose: http://somethingaboutorange.com/mrl/projects/nose/
+* MyHDL: http://docs.myhdl.org/en/latest/
+* nose: http://nose.readthedocs.org/en/latest/
 * NoTex: https://notex.ch/overview/
-* ObjectListView: http://objectlistview.sourceforge.net/python
+* ObjectListView: http://objectlistview.sourceforge.net/python/
 * Open ERP: http://doc.openerp.com/
 * OpenCV: http://docs.opencv.org/
-* Open Dylan: http://opendylan.org/documentation/ and also provides
+* Open Dylan: http://opendylan.org/documentation/ and also provides a
   `dylan domain <https://github.com/dylan-lang/sphinx-extensions/blob/master/dylandomain/reference.rst>`__
 * OpenLayers: http://docs.openlayers.org/
 * PyEphem: http://rhodesmill.org/pyephem/
 * German Plone user manual: http://www.hasecke.com/plone-benutzerhandbuch/
 * PSI4: http://sirius.chem.vt.edu/psi4manual/latest/index.html
-* Pylons: http://pylonshq.com/docs/en/0.9.7/
-* PyMOTW: http://www.doughellmann.com/PyMOTW/
+* Pylons: http://docs.pylonsproject.org/projects/pylons-webframework/en/latest/
+* PyMOTW: http://pymotw.com/2/
 * pypol: http://pypol.altervista.org/ (celery)
-* QGIS: http://qgis.org/
-* qooxdoo: http://manual.qooxdoo.org/current
+* QGIS: http://qgis.org/en/docs/index.html
+* qooxdoo: http://manual.qooxdoo.org/current/
 * Roundup: http://www.roundup-tracker.org/
-* Selenium: http://seleniumhq.org/docs/
+* Satchmo: http://docs.satchmoproject.com/en/latest/
+* Selenium: http://docs.seleniumhq.org/docs/
 * Self: http://selflanguage.org/
+* Substance D: http://docs.pylonsproject.org/projects/substanced/en/latest/
 * Tablib: http://tablib.org/
 * SQLAlchemy: http://www.sqlalchemy.org/docs/
 * tinyTiM: http://tinytim.sourceforge.net/docs/2.0/
@@ -198,7 +206,8 @@
 * lunarsite: http://lunaryorn.de/
 * Red Hot Chili Python: http://redhotchilipython.com/
 * The Wine Cellar Book: http://www.thewinecellarbook.com/doc/en/
-* Uni. Berkeley Advanced Control Systems course: http://www.me.berkeley.edu/ME233/sp14/
+* UC Berkeley Advanced Control Systems course:
+  http://www.me.berkeley.edu/ME233/sp14/
 * VOR: http://www.vor-cycling.be/
 
 
@@ -224,6 +233,8 @@
   https://www.varnish-software.com/static/book/
 * "Learning Sphinx" (in Japanese):
   http://www.oreilly.co.jp/books/9784873116488/
+* "LassoGuide":
+  http://www.lassosoft.com/Lasso-Documentation
 
 
 Thesis using Sphinx
diff --git a/LICENSE b/LICENSE
index 7aa7620..c8a7928 100644
--- a/LICENSE
+++ b/LICENSE
@@ -244,3 +244,37 @@
 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 OTHER DEALINGS IN THE SOFTWARE.
+
+-------------------------------------------------------------------------------
+
+The included implementation of NumpyDocstring._parse_numpydoc_see_also_section
+was derived from code under the following license:
+
+-------------------------------------------------------------------------------
+
+Copyright (C) 2008 Stefan van der Walt <stefan@mentat.za.net>, Pauli Virtanen <pav@iki.fi>
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-------------------------------------------------------------------------------
diff --git a/MANIFEST.in b/MANIFEST.in
index 5db26b8..4cafcdc 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -19,7 +19,6 @@
 recursive-include sphinx/ext/autosummary/templates *
 recursive-include tests *
 recursive-include utils *
-recursive-include custom_fixers *
 include sphinx/pycode/Grammar-py2.txt
 include sphinx/pycode/Grammar-py3.txt
 
diff --git a/README.rst b/README.rst
index 5963a0a..9b22008 100644
--- a/README.rst
+++ b/README.rst
@@ -39,4 +39,17 @@
 Contributing
 ============
 
-Send wishes, comments, patches, etc. to sphinx-dev@googlegroups.com.
+#. Check for open issues or open a fresh issue to start a discussion around a
+   feature idea or a bug. There are Non Assigned issues:
+   https://bitbucket.org/birkenfeld/sphinx/issues?status=new&status=open&responsible=
+#. If you feel uncomfortable or uncertain about an issue or your changes, feel
+   free to email sphinx-dev@googlegroups.com.
+#. Fork the repository on Bitbucket https://bitbucket.org/birkenfeld/sphinx
+   to start making your changes to the **default** branch for next major
+   version, or **stable** branch for next minor version.
+#. Write a test which shows that the bug was fixed or that the feature works
+   as expected.
+#. Send a pull request and bug the maintainer until it gets merged and
+   published. Make sure to add yourself to AUTHORS
+   <https://bitbucket.org/birkenfeld/sphinx/src/tip/AUTHORS> and the change to
+   CHANGES <https://bitbucket.org/birkenfeld/sphinx/src/tip/CHANGES>.
diff --git a/custom_fixers/__init__.py b/custom_fixers/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/custom_fixers/__init__.py
+++ /dev/null
diff --git a/custom_fixers/fix_alt_unicode.py b/custom_fixers/fix_alt_unicode.py
deleted file mode 100644
index 55175e9..0000000
--- a/custom_fixers/fix_alt_unicode.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from lib2to3.fixer_base import BaseFix
-from lib2to3.fixer_util import Name
-
-class FixAltUnicode(BaseFix):
-    PATTERN = """
-    func=funcdef< 'def' name='__unicode__'
-                  parameters< '(' NAME ')' > any+ >
-    """
-
-    def transform(self, node, results):
-        name = results['name']
-        name.replace(Name('__str__', prefix=name.prefix))
diff --git a/doc/_static/bookcover.png b/doc/_static/bookcover.png
index 1c91f91..5b521b6 100644
--- a/doc/_static/bookcover.png
+++ b/doc/_static/bookcover.png
Binary files differ
diff --git a/doc/_static/pocoo.png b/doc/_static/pocoo.png
index eeb18ea..67663b9 100644
--- a/doc/_static/pocoo.png
+++ b/doc/_static/pocoo.png
Binary files differ
diff --git a/doc/_static/sphinx.png b/doc/_static/sphinx.png
index a4a3e1a..4bd9c75 100644
--- a/doc/_static/sphinx.png
+++ b/doc/_static/sphinx.png
Binary files differ
diff --git a/doc/_templates/index.html b/doc/_templates/index.html
index e6ef917..45581e0 100644
--- a/doc/_templates/index.html
+++ b/doc/_templates/index.html
@@ -97,4 +97,14 @@
     powerful built-in search that exceeds the possibilities of Sphinx' JavaScript-based
     offline search.{%endtrans%}</p>
 
+  <h2>{%trans%}Contributor Guide{%endtrans%}</h2>
+
+  <p>{%trans%}If you want to contribute to the project,
+    this part of the documentation is for you.{%endtrans%}</p>
+
+    <ul>
+      <li>{%trans path=pathto("devguide")%}<a href="{{ path }}">Sphinx Developer’s Guide</a></li>{%endtrans%}
+      <li>{%trans path=pathto("authors")%}<a href="{{ path }}">Sphinx Authors</a></li>{%endtrans%}
+    </ul>
+
 {% endblock %}
diff --git a/doc/_templates/indexsidebar.html b/doc/_templates/indexsidebar.html
index 4a350ae..019b20f 100644
--- a/doc/_templates/indexsidebar.html
+++ b/doc/_templates/indexsidebar.html
@@ -14,7 +14,7 @@
 <p>{%trans%}Current version: <b>{{ version }}</b>{%endtrans%}</p>
 <p>{%trans%}Get Sphinx from the <a href="http://pypi.python.org/pypi/Sphinx">Python Package
 Index</a>, or install it with:{%endtrans%}</p>
-<pre>easy_install -U Sphinx</pre>
+<pre>pip install -U Sphinx</pre>
 <p>{%trans%}Latest <a href="http://sphinx-doc.org/latest/">development version docs</a>
 are also available.{%endtrans%}</p>
 {% endif %}
diff --git a/doc/_themes/sphinx13/static/bodybg.png b/doc/_themes/sphinx13/static/bodybg.png
index 506b6f9..ebe92f6 100644
--- a/doc/_themes/sphinx13/static/bodybg.png
+++ b/doc/_themes/sphinx13/static/bodybg.png
Binary files differ
diff --git a/doc/_themes/sphinx13/static/footerbg.png b/doc/_themes/sphinx13/static/footerbg.png
index d1922b4..df783e2 100644
--- a/doc/_themes/sphinx13/static/footerbg.png
+++ b/doc/_themes/sphinx13/static/footerbg.png
Binary files differ
diff --git a/doc/_themes/sphinx13/static/headerbg.png b/doc/_themes/sphinx13/static/headerbg.png
index 6d3e1d5..22830f9 100644
--- a/doc/_themes/sphinx13/static/headerbg.png
+++ b/doc/_themes/sphinx13/static/headerbg.png
Binary files differ
diff --git a/doc/_themes/sphinx13/static/relbg.png b/doc/_themes/sphinx13/static/relbg.png
index 4722585..2006af7 100644
--- a/doc/_themes/sphinx13/static/relbg.png
+++ b/doc/_themes/sphinx13/static/relbg.png
Binary files differ
diff --git a/doc/_themes/sphinx13/static/sphinxheader.png b/doc/_themes/sphinx13/static/sphinxheader.png
index 2b33f09..12988c3 100644
--- a/doc/_themes/sphinx13/static/sphinxheader.png
+++ b/doc/_themes/sphinx13/static/sphinxheader.png
Binary files differ
diff --git a/doc/authors.rst b/doc/authors.rst
new file mode 100644
index 0000000..04c8b2b
--- /dev/null
+++ b/doc/authors.rst
@@ -0,0 +1,9 @@
+:tocdepth: 2

+

+.. _authors:

+

+Sphinx authors

+==============

+

+.. include:: ../AUTHORS

+

diff --git a/doc/builders.rst b/doc/builders.rst
index 333750e..3c6f6b9 100644
--- a/doc/builders.rst
+++ b/doc/builders.rst
@@ -153,11 +153,6 @@
 
    .. autoattribute:: supported_image_types
 
-   .. note::
-
-      This builder requires the docutils manual page writer, which is only
-      available as of docutils 0.6.
-
    .. versionadded:: 1.0
 
 
@@ -282,8 +277,8 @@
 .. class:: ChangesBuilder
 
    This builder produces an HTML overview of all :rst:dir:`versionadded`,
-   :rst:dir:`versionchanged` and :rst:dir:`deprecated` directives for the current
-   :confval:`version`.  This is useful to generate a ChangeLog file, for
+   :rst:dir:`versionchanged` and :rst:dir:`deprecated` directives for the
+   current :confval:`version`.  This is useful to generate a ChangeLog file, for
    example.
 
    .. autoattribute:: name
diff --git a/doc/conf.py b/doc/conf.py
index 9640e2e..3ae9482 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -5,6 +5,7 @@
 import re
 import sphinx
 
+
 extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo',
               'sphinx.ext.autosummary', 'sphinx.ext.extlinks']
 
diff --git a/doc/config.rst b/doc/config.rst
index 26079e6..cc35a75 100644
--- a/doc/config.rst
+++ b/doc/config.rst
@@ -45,7 +45,8 @@
 * There is a special object named ``tags`` available in the config file.
   It can be used to query and change the tags (see :ref:`tags`).  Use
   ``tags.has('tag')`` to query, ``tags.add('tag')`` and ``tags.remove('tag')``
-  to change.
+  to change. Only tags set via the ``-t`` command-line option or via
+  ``tags.add('tag')`` can be queried using ``tags.has('tag')``.
   Note that the current builder tag is not available in ``conf.py``, as it is
   created *after* the builder is initialized.
 
@@ -115,44 +116,16 @@
 
    .. versionadded:: 1.0
 
-.. confval:: unused_docs
-
-   A list of document names that are present, but not currently included in the
-   toctree.  Use this setting to suppress the warning that is normally emitted
-   in that case.
-
-   .. deprecated:: 1.0
-      Use :confval:`exclude_patterns` instead.
-
-.. confval:: exclude_trees
-
-   A list of directory paths, relative to the source directory, that are to be
-   recursively excluded from the search for source files, that is, their
-   subdirectories won't be searched too.  The default is ``[]``.
-
-   .. versionadded:: 0.4
-
-   .. deprecated:: 1.0
-      Use :confval:`exclude_patterns` instead.
-
-.. confval:: exclude_dirnames
-
-   A list of directory names that are to be excluded from any recursive
-   operation Sphinx performs (e.g. searching for source files or copying static
-   files).  This is useful, for example, to exclude version-control-specific
-   directories like ``'CVS'``.  The default is ``[]``.
-
-   .. versionadded:: 0.5
-
-   .. deprecated:: 1.0
-      Use :confval:`exclude_patterns` instead.
-
 .. confval:: templates_path
 
    A list of paths that contain extra templates (or templates that overwrite
    builtin/theme-specific templates).  Relative paths are taken as relative to
    the configuration directory.
 
+   .. versionchanged:: 1.3
+      As these files are not meant to be built, they are automatically added to
+      :confval:`exclude_patterns`.
+
 .. confval:: template_bridge
 
    A string with the fully-qualified name of a callable (or simply a class) that
@@ -228,6 +201,19 @@
 
    .. versionadded:: 1.0
 
+.. confval:: needs_extensions
+
+   This value can be a dictionary specifying version requirements for extensions
+   in :confval:`extensions`, e.g. ``needs_extensions =
+   {'sphinxcontrib.something': '1.5'}``.  The version strings should be in the
+   form ``major.minor``.  Requirements do not have to be specified for all
+   extensions, only for those you want to check.
+
+   This requires that the extension specifies its version to Sphinx (see
+   :ref:`dev-extensions` for how to do that).
+
+   .. versionadded:: 1.3
+
 .. confval:: nitpicky
 
    If true, Sphinx will warn about *all* references where the target cannot be
@@ -341,8 +327,8 @@
    If true, doctest flags (comments looking like ``# doctest: FLAG, ...``) at
    the ends of lines and ``<BLANKLINE>`` markers are removed for all code
    blocks showing interactive Python sessions (i.e. doctests).  Default is
-   true.  See the extension :mod:`~sphinx.ext.doctest` for more possibilities
-   of including doctests.
+   ``True``.  See the extension :mod:`~sphinx.ext.doctest` for more
+   possibilities of including doctests.
 
    .. versionadded:: 1.0
    .. versionchanged:: 1.1
@@ -354,7 +340,7 @@
 Options for internationalization
 --------------------------------
 
-These options influence Sphinx' *Native Language Support*.  See the
+These options influence Sphinx's *Native Language Support*.  See the
 documentation on :ref:`intl` for details.
 
 .. confval:: language
@@ -435,6 +421,32 @@
    By default, the document ``markup/code.rst`` ends up in the ``markup`` text
    domain.  With this option set to ``False``, it is ``markup/code``.
 
+.. confval:: gettext_uuid
+
+   If true, Sphinx generates uuid information for version tracking in message
+   catalogs.
+
+   The default is ``True``.
+
+   .. versionadded:: 1.3
+
+.. confval:: gettext_location
+
+   If true, Sphinx generates location information for messages in message
+   catalogs.
+
+   The default is ``True``.
+
+   .. versionadded:: 1.3
+
+.. confval:: gettext_auto_build
+
+   If true, Sphinx builds mo file for each translation catalog files.
+
+   The default is ``True``.
+
+   .. versionadded:: 1.3
+
 
 .. _html-options:
 
@@ -442,7 +454,7 @@
 -----------------------
 
 These options influence HTML as well as HTML Help output, and other builders
-that use Sphinx' HTMLWriter class.
+that use Sphinx's HTMLWriter class.
 
 .. confval:: html_theme
 
@@ -470,14 +482,14 @@
 .. confval:: html_style
 
    The style sheet to use for HTML pages.  A file of that name must exist either
-   in Sphinx' :file:`static/` path, or in one of the custom paths given in
+   in Sphinx's :file:`static/` path, or in one of the custom paths given in
    :confval:`html_static_path`.  Default is the stylesheet given by the selected
    theme.  If you only want to add or override a few things compared to the
    theme's stylesheet, use CSS ``@import`` to import the theme's stylesheet.
 
 .. confval:: html_title
 
-   The "title" for HTML documentation generated with Sphinx' own templates.
+   The "title" for HTML documentation generated with Sphinx's own templates.
    This is appended to the ``<title>`` tag of individual pages, and used in the
    navigation bar as the "topmost" element.  It defaults to :samp:`'{<project>}
    v{<revision>} documentation'` (with the values coming from the config
@@ -513,9 +525,10 @@
 .. confval:: html_favicon
 
    If given, this must be the name of an image file (path relative to the
-   :term:`configuration directory`) that is the favicon of the docs.  Modern browsers use this
-   as icon for tabs, windows and bookmarks.  It should be a Windows-style icon
-   file (``.ico``), which is 16x16 or 32x32 pixels large.  Default: ``None``.
+   :term:`configuration directory`) that is the favicon of the docs.  Modern
+   browsers use this as the icon for tabs, windows and bookmarks.  It should
+   be a Windows-style icon file (``.ico``), which is 16x16 or 32x32
+   pixels large.  Default: ``None``.
 
    .. versionadded:: 0.4
       The image file will be copied to the ``_static`` directory of the output
@@ -557,8 +570,9 @@
 
 .. confval:: html_use_smartypants
 
-   If true, *SmartyPants* will be used to convert quotes and dashes to
-   typographically correct entities.  Default: ``True``.
+   If true, `SmartyPants <http://daringfireball.net/projects/smartypants/>`_
+   will be used to convert quotes and dashes to typographically correct
+   entities.  Default: ``True``.
 
 .. confval:: html_add_permalinks
 
@@ -600,7 +614,8 @@
 
    Builtin sidebar templates that can be rendered are:
 
-   * **localtoc.html** -- a fine-grained table of contents of the current document
+   * **localtoc.html** -- a fine-grained table of contents of the current
+     document
    * **globaltoc.html** -- a coarse-grained table of contents for the whole
      documentation set, collapsed
    * **relations.html** -- two links to the previous and next documents
@@ -717,13 +732,16 @@
 .. confval:: html_translator_class
 
    A string with the fully-qualified name of a HTML Translator class, that is, a
-   subclass of Sphinx' :class:`~sphinx.writers.html.HTMLTranslator`, that is used
-   to translate document trees to HTML.  Default is ``None`` (use the builtin
-   translator).
+   subclass of Sphinx's :class:`~sphinx.writers.html.HTMLTranslator`, that is
+   used to translate document trees to HTML.  Default is ``None`` (use the
+   builtin translator).
+
+   .. seealso::  :meth:`~sphinx.application.Sphinx.set_translator`
 
 .. confval:: html_show_copyright
 
-   If true, "(C) Copyright ..." is shown in the HTML footer. Default is ``True``.
+   If true, "(C) Copyright ..." is shown in the HTML footer. Default is
+   ``True``.
 
    .. versionadded:: 1.0
 
@@ -766,10 +784,37 @@
 
    Support is present for these languages:
 
+   * ``da`` -- Danish
+   * ``nl`` -- Dutch
    * ``en`` -- English
+   * ``fi`` -- Finnish
+   * ``fr`` -- French
+   * ``de`` -- German
+   * ``hu`` -- Hungarian
+   * ``it`` -- Italian
    * ``ja`` -- Japanese
+   * ``no`` -- Norwegian
+   * ``pr`` -- Portuguese
+   * ``ro`` -- Romanian
+   * ``ru`` -- Russian
+   * ``es`` -- Spanish
+   * ``sv`` -- Swedish
+   * ``tr`` -- Turkish
+
+   .. admonition:: Accelerating build speed
+
+      Each language (except Japanese) provides its own stemming algorithm.
+      Sphinx uses a Python implementation by default.  You can use a C
+      implementation to accelerate building the index file.
+
+      * `PorterStemmer <https://pypi.python.org/pypi/PorterStemmer>`_ (``en``)
+      * `PyStemmer <https://pypi.python.org/pypi/PyStemmer>`_ (all languages)
 
    .. versionadded:: 1.1
+      With support for ``en`` and ``ja``.
+
+   .. versionchanged:: 1.3
+      Added additional languages.
 
 .. confval:: html_search_options
 
@@ -791,7 +836,7 @@
 
 .. confval:: html_search_scorer
 
-   The name of a javascript file (relative to the configuration directory) that
+   The name of a JavaScript file (relative to the configuration directory) that
    implements a search results scorer.  If empty, the default will be used.
 
    .. XXX describe interface for scorer here
@@ -900,7 +945,7 @@
    the optional guide information. See the OPF documentation
    at `<http://idpf.org/epub>`_ for details. If possible, default entries
    for the *cover* and *toc* types are automatically inserted. However,
-   the types can be explicitely overwritten if the default entries are not
+   the types can be explicitly overwritten if the default entries are not
    appropriate. Example::
 
       epub_guide = (('cover', 'cover.html', u'Cover Page'),)
@@ -940,8 +985,8 @@
 .. confval:: epub_tocdup
 
    This flag determines if a toc entry is inserted again at the beginning of
-   it's nested toc listing.  This allows easier navitation to the top of
-   a chapter, but can be confusing because it mixes entries of differnet
+   its nested toc listing.  This allows easier navigation to the top of
+   a chapter, but can be confusing because it mixes entries of different
    depth in one list.  The default value is ``True``.
 
 .. confval:: epub_tocscope
@@ -1024,11 +1069,11 @@
      ``'John \and Sarah'``.
    * *documentclass*: Normally, one of ``'manual'`` or ``'howto'`` (provided by
      Sphinx).  Other document classes can be given, but they must include the
-     "sphinx" package in order to define Sphinx' custom LaTeX commands.
-     "howto" documents will not get appendices.  Also, howtos will have a simpler
-     title page.
+     "sphinx" package in order to define Sphinx's custom LaTeX commands. "howto"
+     documents will not get appendices.  Also, howtos will have a simpler title
+     page.
 
-   * *toctree_only*: Must be ``True`` or ``False``.  If ``True``, the *startdoc*
+   * *toctree_only*: Must be ``True`` or ``False``.  If true, the *startdoc*
      document itself is not included in the output, only the documents
      referenced by it via TOC trees.  With this option, you can put extra stuff
      in the master document that shows up in the HTML, but not the LaTeX output.
@@ -1135,6 +1180,12 @@
         "Rejne".  You can also set this to ``''`` to disable fncychap.
      ``'preamble'``
         Additional preamble content, default empty.
+     ``'figure_align'``
+        Latex figure float alignment, default 'htbp' (here, top, bottom, page).
+        Whenever an image doesn't fit into the current page, it will be
+        'floated' into the next page but may be preceded by any other text.
+        If you don't like this behavior, use 'H' which will disable floating
+        and position figures strictly in the order they appear in the source.
      ``'footer'``
         Additional footer content (before the indices), default empty.
 
@@ -1167,7 +1218,8 @@
         ``'\\printindex'``.  Override if you want to generate the index
         differently or append some content after the index.
 
-   * Keys that are set by other options and therefore should not be overridden are:
+   * Keys that are set by other options and therefore should not be overridden
+     are:
 
      ``'docclass'``
      ``'classoptions'``
@@ -1324,7 +1376,7 @@
      file.
    * *category*: Specifies the section which this entry will appear in the
      top-level ``DIR`` menu file.
-   * *toctree_only*: Must be ``True`` or ``False``.  If ``True``, the *startdoc*
+   * *toctree_only*: Must be ``True`` or ``False``.  If true, the *startdoc*
      document itself is not included in the output, only the documents
      referenced by it via TOC trees.  With this option, you can put extra stuff
      in the master document that shows up in the HTML, but not the Texinfo
@@ -1400,7 +1452,6 @@
      ``'project'``
      ``'release'``
      ``'title'``
-     ``'direntry'``
 
    .. versionadded:: 1.1
 
@@ -1434,9 +1485,9 @@
 
 .. confval:: linkcheck_anchors
 
-   True or false, whether to check the validity of ``#anchor``\ s in links.
-   Since this requires downloading the whole document, it's considerably slower
-   when enabled.  Default is ``True``.
+   If true, check the validity of ``#anchor``\ s in links. Since this requires
+   downloading the whole document, it's considerably slower when enabled.
+   Default is ``True``.
 
    .. versionadded:: 1.2
 
@@ -1446,7 +1497,7 @@
 
 .. confval:: xml_pretty
 
-   If True, pretty-print the XML.  Default is ``True``.
+   If true, pretty-print the XML.  Default is ``True``.
 
    .. versionadded:: 1.2
 
diff --git a/doc/contents.rst b/doc/contents.rst
index d3fd3c8..a51910b 100644
--- a/doc/contents.rst
+++ b/doc/contents.rst
@@ -26,6 +26,7 @@
    devguide
    changes
    examples
+   authors
 
 
 Indices and tables
diff --git a/doc/develop.rst b/doc/develop.rst
index aad3ff1..5110aa3 100644
--- a/doc/develop.rst
+++ b/doc/develop.rst
@@ -55,6 +55,7 @@
 - hyphenator: client-side hyphenation of HTML using hyphenator_
 - inlinesyntaxhighlight_: inline syntax highlighting
 - lassodomain: a domain for documenting Lasso_ source code
+- libreoffice: an extension to include any drawing supported by LibreOffice (e.g. odg, vsd...).
 - lilypond: an extension inserting music scripts from Lilypond_ in PNG format.
 - makedomain_: a domain for `GNU Make`_
 - matlabdomain: document MATLAB_ code.
@@ -68,7 +69,8 @@
 - paverutils: an alternate integration of Sphinx with Paver_.
 - phpdomain: an extension for PHP support
 - plantuml: embed UML diagram by using PlantUML_
-- py_directive: Execute python code in a ``py`` directive and return a math node.
+- py_directive: Execute python code in a ``py`` directive and return a math
+  node.
 - rawfiles: copy raw files, like a CNAME.
 - requirements: declare requirements wherever you need (e.g. in test
   docstrings), mark statuses and collect them in a single list
diff --git a/doc/devguide.rst b/doc/devguide.rst
index fccdd3f..885d52b 100644
--- a/doc/devguide.rst
+++ b/doc/devguide.rst
@@ -54,6 +54,23 @@
 committing the changes.  The pull request will then need to be approved by one
 of the core developers before it is merged into the main repository.
 
+#. Check for open issues or open a fresh issue to start a discussion around a
+   feature idea or a bug. There are `Non Assigned`_ issues.
+#. If you feel uncomfortable or uncertain about an issue or your changes, feel
+   free to email sphinx-dev@googlegroups.com.
+#. Fork `the repository`_ on Bitbucket to start making your changes to the
+   **default** branch for next major version, or **stable** branch for next
+   minor version.
+#. Write a test which shows that the bug was fixed or that the feature works
+   as expected.
+#. Send a pull request and bug the maintainer until it gets merged and
+   published. Make sure to add yourself to AUTHORS_ and the change to
+   CHANGES_.
+
+.. _`the repository`: https://bitbucket.org/birkenfeld/sphinx
+.. _AUTHORS: https://bitbucket.org/birkenfeld/sphinx/src/tip/AUTHORS
+.. _CHANGES: https://bitbucket.org/birkenfeld/sphinx/src/tip/CHANGES
+.. _Non Assigned: https://bitbucket.org/birkenfeld/sphinx/issues?status=new&status=open&responsible=
 
 Getting Started
 ~~~~~~~~~~~~~~~
@@ -113,8 +130,8 @@
    * For bug fixes, first add a test that fails without your changes and passes
      after they are applied.
 
-#. Please add a bullet point to :file:`CHANGES` if the fix or feature is not trivial
-   (small doc updates, typo fixes).  Then commit::
+#. Please add a bullet point to :file:`CHANGES` if the fix or feature is not
+   trivial (small doc updates, typo fixes).  Then commit::
 
        hg commit -m '#42: Add useful new feature that does this.'
 
@@ -191,9 +208,9 @@
 values for :confval:`language` in ``doc/config.rst``.
 
 The Sphinx core messages can also be translated on `Transifex
-<https://www.transifex.com/>`_.  There exists a client tool named ``tx`` in the Python
-package "transifex_client", which can be used to pull translations in ``.po``
-format from Transifex.  To do this, go to ``sphinx/locale`` and then run
+<https://www.transifex.com/>`_.  There exists a client tool named ``tx`` in the
+Python package "transifex_client", which can be used to pull translations in
+``.po`` format from Transifex.  To do this, go to ``sphinx/locale`` and then run
 ``tx pull -f -l LANG`` where LANG is an existing language identifier.  It is
 good practice to run ``python setup.py update_catalog`` afterwards to make sure
 the ``.po`` file has the canonical Babel formatting.
@@ -235,11 +252,23 @@
 * Use ``node.pformat()`` and ``node.asdom().toxml()`` to generate a printable
   representation of the document structure.
 
-* Set the configuration variable :confval:`keep_warnings` to True so warnings
-  will be displayed in the generated output.
+* Set the configuration variable :confval:`keep_warnings` to ``True`` so
+  warnings will be displayed in the generated output.
 
-* Set the configuration variable :confval:`nitpicky` to True so that Sphinx
+* Set the configuration variable :confval:`nitpicky` to ``True`` so that Sphinx
   will complain about references without a known target.
 
 * Set the debugging options in the `Docutils configuration file
   <http://docutils.sourceforge.net/docs/user/config.html>`_.
+
+* JavaScript stemming algorithms in `sphinx/search/*.py` (except `en.py`) are
+  generated by this
+  `modified snowballcode generator <https://github.com/shibukawa/snowball>`_.
+  Generated `JSX <http://jsx.github.io/>`_ files are
+  in `this repository <https://github.com/shibukawa/snowball-stemmer.jsx>`_.
+  You can get the resulting JavaScript files using the following command:
+
+  .. code-block:: bash
+
+     $ npm install
+     $ node_modules/.bin/grunt build # -> dest/*.global.js
diff --git a/doc/domains.rst b/doc/domains.rst
index 4b5a903..4bfc91e 100644
--- a/doc/domains.rst
+++ b/doc/domains.rst
@@ -127,7 +127,8 @@
 
    This directive marks the beginning of the description of a module (or package
    submodule, in which case the name should be fully qualified, including the
-   package name).  It does not create content (like e.g. :rst:dir:`py:class` does).
+   package name).  It does not create content (like e.g. :rst:dir:`py:class`
+   does).
 
    This directive will also cause an entry in the global module index.
 
@@ -157,17 +158,6 @@
 
 The following directives are provided for module and class contents:
 
-.. rst:directive:: .. py:data:: name
-
-   Describes global data in a module, including both variables and values used
-   as "defined constants."  Class and object attributes are not documented
-   using this environment.
-
-.. rst:directive:: .. py:exception:: name
-
-   Describes an exception class.  The signature can, but need not include
-   parentheses with constructor arguments.
-
 .. rst:directive:: .. py:function:: name(parameters)
 
    Describes a module-level function.  The signature should include the
@@ -178,11 +168,23 @@
 
    For methods you should use :rst:dir:`py:method`.
 
-   The description should include information about the parameters required and
-   how they are used (especially whether mutable objects passed as parameters
-   are modified), side effects, and possible exceptions.  This information can
-   optionally be given in a structured form, see :ref:`info-field-lists`.  A
-   small example may be provided.
+   The description normally includes information about the parameters required
+   and how they are used (especially whether mutable objects passed as
+   parameters are modified), side effects, and possible exceptions.
+
+   This information can (in any ``py`` directive) optionally be given in a
+   structured form, see :ref:`info-field-lists`.
+
+.. rst:directive:: .. py:data:: name
+
+   Describes global data in a module, including both variables and values used
+   as "defined constants."  Class and object attributes are not documented
+   using this environment.
+
+.. rst:directive:: .. py:exception:: name
+
+   Describes an exception class.  The signature can, but need not include
+   parentheses with constructor arguments.
 
 .. rst:directive:: .. py:class:: name
                    .. py:class:: name(parameters)
@@ -374,7 +376,7 @@
    Reference a Python function; dotted names may be used.  The role text needs
    not include trailing parentheses to enhance readability; they will be added
    automatically by Sphinx if the :confval:`add_function_parentheses` config
-   value is true (the default).
+   value is ``True`` (the default).
 
 .. rst:role:: py:data
 
@@ -518,23 +520,26 @@
 
 The C++ domain (name **cpp**) supports documenting C++ projects.
 
-The following directives are available:
+The following directives are available. All declarations can start with a visibility statement
+(``public``, ``private`` or ``protected``).
 
-.. rst:directive:: .. cpp:class:: signatures
-               .. cpp:function:: signatures
-               .. cpp:member:: signatures
-               .. cpp:type:: signatures
+.. rst:directive:: .. cpp:class:: class speicifer
 
-   Describe a C++ object.  Full signature specification is supported -- give the
-   signature as you would in the declaration.  Here some examples::
+   Describe a class/struct, possibly with specification of inheritance, e.g.,::
+   
+      .. cpp:class:: SomeName::SomeClass : public MyBase, MyOtherBase
+
+.. rst:directive:: .. cpp:function:: (member-)function prototype
+
+   Describe a function or member function, e.g.,::
 
       .. cpp:function:: bool namespaced::theclass::method(int arg1, std::string arg2)
 
          Describes a method with parameters and types.
 
-      .. cpp:function:: bool namespaced::theclass::method(arg1, arg2)
+      .. cpp:function:: bool namespaced::theclass::method(T1, T2)
 
-         Describes a method without types.
+         Describes a method with unnamed parameters.
 
       .. cpp:function:: const T &array<T>::operator[]() const
 
@@ -548,43 +553,41 @@
 
          Describe a constexpr function here.
 
-      .. cpp:member:: std::string theclass::name
+      .. cpp:function:: MyClass::MyClass(const MyClass&) = default
 
-      .. cpp:member:: std::string theclass::name[N][M]
+         Describe a copy constructor with default implementation.
 
-      .. cpp:type:: theclass::const_iterator
+.. rst:directive:: .. cpp:member:: variable or member declaration
 
-   Will be rendered like this:
-
-      .. cpp:function:: bool namespaced::theclass::method(int arg1, std::string arg2)
-
-         Describes a method with parameters and types.
-
-      .. cpp:function:: bool namespaced::theclass::method(arg1, arg2)
-
-         Describes a method without types.
-
-      .. cpp:function:: const T &array<T>::operator[]() const
-
-         Describes the constant indexing operator of a templated array.
-
-      .. cpp:function:: operator bool() const
-
-         Describe a casting operator here.
-
-      .. cpp:function:: constexpr void foo(std::string &bar[2]) noexcept
-
-         Describe a constexpr function here.
+   Describe a varible or member variable, e.g.,::
 
       .. cpp:member:: std::string theclass::name
 
       .. cpp:member:: std::string theclass::name[N][M]
 
+.. rst:directive:: .. cpp:type:: typedef-like declaration
+                   .. cpp:type:: name
+
+   Describe a type as in a typedef declaration, or the name of a type with unspecified type, e.g.,::
+
+      .. cpp:type:: std::vector<int> MyList
+
+         A typedef-like declaration of a type.
+
       .. cpp:type:: theclass::const_iterator
 
+         Declaration of a type alias with unspecified type.
+
 .. rst:directive:: .. cpp:namespace:: namespace
 
-   Select the current C++ namespace for the following objects.
+   Select the current namespace for the following objects. Note that the namespace
+   does not need to correspond to C++ namespaces, but can end in names of classes, e.g.,::
+
+      .. cpp:namespace:: Namespace1::Namespace2::SomeClass::AnInnerClass
+
+   All following objects will be defined as if their name were declared with the namespace
+   prepended. The following cross-references will be search for by both their specified name
+   and with the namespace prepended.
 
 
 .. _cpp-roles:
@@ -596,12 +599,12 @@
           cpp:member
           cpp:type
 
-   Reference a C++ object.  You can give the full signature (and need to, for
+   Reference a C++ object.  You can give the full specification (and need to, for
    overloaded functions.)
 
    .. note::
 
-      Sphinx' syntax to give references a custom title can interfere with
+      Sphinx's syntax to give references a custom title can interfere with
       linking to template classes, if nothing follows the closing angle
       bracket, i.e. if the link looks like this: ``:cpp:class:`MyClass<T>```.
       This is interpreted as a link to ``T`` with a title of ``MyClass``.
@@ -617,6 +620,12 @@
    specific overload.  Currently Sphinx will link to the first overloaded
    version of the method / function.
 
+.. admonition:: Note on Template Delcarations
+
+   The C++ domain currently does not support template classes/functions/aliases/variables
+   (e.g., ``template<typename T> MyClass``), only template instantiations
+   (e.g., ``MyClass<T>``).
+
 
 The Standard Domain
 -------------------
@@ -654,9 +663,9 @@
 
 .. rst:directive:: .. program:: name
 
-   Like :rst:dir:`py:currentmodule`, this directive produces no output.  Instead, it
-   serves to notify Sphinx that all following :rst:dir:`option` directives
-   document options for the program called *name*.
+   Like :rst:dir:`py:currentmodule`, this directive produces no output.
+   Instead, it serves to notify Sphinx that all following :rst:dir:`option`
+   directives document options for the program called *name*.
 
    If you use :rst:dir:`program`, you have to qualify the references in your
    :rst:role:`option` roles by the program name, so if you have the following
diff --git a/doc/ext/autodoc.rst b/doc/ext/autodoc.rst
index 7f64698..844c636 100644
--- a/doc/ext/autodoc.rst
+++ b/doc/ext/autodoc.rst
@@ -35,6 +35,16 @@
 two locations for documentation, while at the same time avoiding
 auto-generated-looking pure API documentation.
 
+If you prefer `NumPy`_ or `Google`_ style docstrings over reStructuredText,
+you can also enable the :mod:`napoleon <sphinx.ext.napoleon>` extension.
+:mod:`napoleon <sphinx.ext.napoleon>` is a preprocessor that converts your
+docstrings to correct reStructuredText before :mod:`autodoc` processes them.
+
+.. _Google:
+   http://google-styleguide.googlecode.com/svn/trunk/pyguide.html#Comments
+.. _NumPy:
+   https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
+
 :mod:`autodoc` provides several directives that are versions of the usual
 :rst:dir:`py:module`, :rst:dir:`py:class` and so forth.  On parsing time, they
 import the corresponding module and extract the docstring of the given objects,
@@ -204,6 +214,12 @@
 
      .. versionadded:: 1.2
 
+   * Add a list of modules in the :confval:`autodoc_mock_imports` to prevent
+     import errors to halt the building process when some external dependencies
+     are not importable at build time.
+
+     .. versionadded:: 1.3
+
 
 .. rst:directive:: autofunction
                    autodata
@@ -258,13 +274,14 @@
               """Docstring for instance attribute spam."""
 
    .. versionchanged:: 0.6
-      :rst:dir:`autodata` and :rst:dir:`autoattribute` can now extract docstrings.
+      :rst:dir:`autodata` and :rst:dir:`autoattribute` can now extract
+      docstrings.
    .. versionchanged:: 1.1
       Comment docs are now allowed on the same line after an assignment.
 
    .. versionchanged:: 1.2
-      :rst:dir:`autodata` and :rst:dir:`autoattribute` have
-      an ``annotation`` option
+      :rst:dir:`autodata` and :rst:dir:`autoattribute` have an ``annotation``
+      option.
 
    .. note::
 
@@ -344,6 +361,14 @@
 
    .. versionadded:: 1.1
 
+.. confval:: autodoc_mock_imports
+
+   This value contains a list of modules to be mocked up. This is useful when
+   some external dependencies are not met at build time and break the building
+   process.
+
+   .. versionadded:: 1.3
+
 
 Docstring preprocessing
 -----------------------
@@ -389,8 +414,8 @@
       ``noindex`` that are true if the flag option of same name was given to the
       auto directive
    :param signature: function signature, as a string of the form
-      ``"(parameter_1, parameter_2)"``, or ``None`` if introspection didn't succeed
-      and signature wasn't specified in the directive.
+      ``"(parameter_1, parameter_2)"``, or ``None`` if introspection didn't
+      succeed and signature wasn't specified in the directive.
    :param return_annotation: function return annotation as a string of the form
       ``" -> annotation"``, or ``None`` if there is no return annotation
 
@@ -421,8 +446,8 @@
       ``"attribute"``)
    :param name: the fully qualified name of the object
    :param obj: the object itself
-   :param skip: a boolean indicating if autodoc will skip this member if the user
-      handler does not override the decision
+   :param skip: a boolean indicating if autodoc will skip this member if the
+      user handler does not override the decision
    :param options: the options given to the directive: an object with attributes
       ``inherited_members``, ``undoc_members``, ``show_inheritance`` and
       ``noindex`` that are true if the flag option of same name was given to the
diff --git a/doc/ext/autosummary.rst b/doc/ext/autosummary.rst
index e3de183..8548fbd 100644
--- a/doc/ext/autosummary.rst
+++ b/doc/ext/autosummary.rst
@@ -15,15 +15,15 @@
 
 The :mod:`sphinx.ext.autosummary` extension does this in two parts:
 
-1. There is an :rst:dir:`autosummary` directive for generating summary listings that
-   contain links to the documented items, and short summary blurbs extracted
-   from their docstrings.
+1. There is an :rst:dir:`autosummary` directive for generating summary listings
+   that contain links to the documented items, and short summary blurbs
+   extracted from their docstrings.
 
 2. Optionally, the convenience script :program:`sphinx-autogen` or the new
    :confval:`autosummary_generate` config value can be used to generate short
    "stub" files for the entries listed in the :rst:dir:`autosummary` directives.
-   These files by default contain only the corresponding :mod:`sphinx.ext.autodoc`
-   directive, but can be customized with templates.
+   These files by default contain only the corresponding
+   :mod:`sphinx.ext.autodoc` directive, but can be customized with templates.
 
 
 .. rst:directive:: autosummary
@@ -62,8 +62,8 @@
 
    **Options**
 
-   * If you want the :rst:dir:`autosummary` table to also serve as a :rst:dir:`toctree`
-     entry, use the ``toctree`` option, for example::
+   * If you want the :rst:dir:`autosummary` table to also serve as a
+     :rst:dir:`toctree` entry, use the ``toctree`` option, for example::
 
          .. autosummary::
             :toctree: DIRNAME
@@ -78,8 +78,8 @@
      directory. If no argument is given, output is placed in the same directory
      as the file that contains the directive.
 
-   * If you don't want the :rst:dir:`autosummary` to show function signatures in the
-     listing, include the ``nosignatures`` option::
+   * If you don't want the :rst:dir:`autosummary` to show function signatures in
+     the listing, include the ``nosignatures`` option::
 
          .. autosummary::
             :nosignatures:
@@ -112,8 +112,8 @@
 
     $ sphinx-autogen -o generated *.rst
 
-will read all :rst:dir:`autosummary` tables in the :file:`*.rst` files that have the
-``:toctree:`` option set, and output corresponding stub pages in directory
+will read all :rst:dir:`autosummary` tables in the :file:`*.rst` files that have
+the ``:toctree:`` option set, and output corresponding stub pages in directory
 ``generated`` for all documented items.  The generated pages by default contain
 text of the form::
 
diff --git a/doc/ext/doctest.rst b/doc/ext/doctest.rst
index 554987e..9b1b4e6 100644
--- a/doc/ext/doctest.rst
+++ b/doc/ext/doctest.rst
@@ -142,8 +142,8 @@
 
 
 The following is an example for the usage of the directives.  The test via
-:rst:dir:`doctest` and the test via :rst:dir:`testcode` and :rst:dir:`testoutput` are
-equivalent. ::
+:rst:dir:`doctest` and the test via :rst:dir:`testcode` and
+:rst:dir:`testoutput` are equivalent. ::
 
    The parrot module
    =================
@@ -236,5 +236,5 @@
    Note though that you can't have blank lines in reST doctest blocks.  They
    will be interpreted as one block ending and another one starting.  Also,
    removal of ``<BLANKLINE>`` and ``# doctest:`` options only works in
-   :rst:dir:`doctest` blocks, though you may set :confval:`trim_doctest_flags` to
-   achieve that in all code blocks with Python console content.
+   :rst:dir:`doctest` blocks, though you may set :confval:`trim_doctest_flags`
+   to achieve that in all code blocks with Python console content.
diff --git a/doc/ext/example_google.py b/doc/ext/example_google.py
new file mode 100644
index 0000000..c94dcdf
--- /dev/null
+++ b/doc/ext/example_google.py
@@ -0,0 +1,223 @@
+# -*- coding: utf-8 -*-
+"""Example Google style docstrings.
+
+This module demonstrates documentation as specified by the `Google Python
+Style Guide`_. Docstrings may extend over multiple lines. Sections are created
+with a section header and a colon followed by a block of indented text.
+
+Example:
+  Examples can be given using either the ``Example`` or ``Examples``
+  sections. Sections support any reStructuredText formatting, including
+  literal blocks::
+
+      $ python example_google.py
+
+Section breaks are created by simply resuming unindented text. Section breaks
+are also implicitly created anytime a new section starts.
+
+Attributes:
+  module_level_variable (int): Module level variables may be documented in
+    either the ``Attributes`` section of the module docstring, or in an
+    inline docstring immediately following the variable.
+
+    Either form is acceptable, but the two should not be mixed. Choose
+    one convention to document module level variables and be consistent
+    with it.
+
+.. _Google Python Style Guide:
+   http://google-styleguide.googlecode.com/svn/trunk/pyguide.html
+
+"""
+
+module_level_variable = 12345
+
+
+def module_level_function(param1, param2=None, *args, **kwargs):
+    """This is an example of a module level function.
+
+    Function parameters should be documented in the ``Args`` section. The name
+    of each parameter is required. The type and description of each parameter
+    is optional, but should be included if not obvious.
+
+    If the parameter itself is optional, it should be noted by adding
+    ", optional" to the type. If \*args or \*\*kwargs are accepted, they
+    should be listed as \*args and \*\*kwargs.
+
+    The format for a parameter is::
+
+        name (type): description
+          The description may span multiple lines. Following
+          lines should be indented.
+
+          Multiple paragraphs are supported in parameter
+          descriptions.
+
+    Args:
+      param1 (int): The first parameter.
+      param2 (str, optional): The second parameter. Defaults to None.
+        Second line of description should be indented.
+      *args: Variable length argument list.
+      **kwargs: Arbitrary keyword arguments.
+
+    Returns:
+      bool: True if successful, False otherwise.
+
+      The return type is optional and may be specified at the beginning of
+      the ``Returns`` section followed by a colon.
+
+      The ``Returns`` section may span multiple lines and paragraphs.
+      Following lines should be indented to match the first line.
+
+      The ``Returns`` section supports any reStructuredText formatting,
+      including literal blocks::
+
+          {
+              'param1': param1,
+              'param2': param2
+          }
+
+    Raises:
+      AttributeError: The ``Raises`` section is a list of all exceptions
+        that are relevant to the interface.
+      ValueError: If `param2` is equal to `param1`.
+
+    """
+    if param1 == param2:
+        raise ValueError('param1 may not be equal to param2')
+    return True
+
+
+def example_generator(n):
+    """Generators have a ``Yields`` section instead of a ``Returns`` section.
+
+    Args:
+      n (int): The upper limit of the range to generate, from 0 to `n` - 1
+
+    Yields:
+      int: The next number in the range of 0 to `n` - 1
+
+    Examples:
+      Examples should be written in doctest format, and should illustrate how
+      to use the function.
+
+      >>> print [i for i in example_generator(4)]
+      [0, 1, 2, 3]
+
+    """
+    for i in range(n):
+        yield i
+
+
+class ExampleError(Exception):
+    """Exceptions are documented in the same way as classes.
+
+    The __init__ method may be documented in either the class level
+    docstring, or as a docstring on the __init__ method itself.
+
+    Either form is acceptable, but the two should not be mixed. Choose one
+    convention to document the __init__ method and be consistent with it.
+
+    Note:
+      Do not include the `self` parameter in the ``Args`` section.
+
+    Args:
+      msg (str): Human readable string describing the exception.
+      code (int, optional): Error code, defaults to 2.
+
+    Attributes:
+      msg (str): Human readable string describing the exception.
+      code (int): Exception error code.
+
+    """
+    def __init__(self, msg, code=2):
+        self.msg = msg
+        self.code = code
+
+
+class ExampleClass(object):
+    """The summary line for a class docstring should fit on one line.
+
+    If the class has public attributes, they should be documented here
+    in an ``Attributes`` section and follow the same formatting as a
+    function's ``Args`` section.
+
+    Attributes:
+      attr1 (str): Description of `attr1`.
+      attr2 (list of str): Description of `attr2`.
+      attr3 (int): Description of `attr3`.
+
+    """
+    def __init__(self, param1, param2, param3=0):
+        """Example of docstring on the __init__ method.
+
+        The __init__ method may be documented in either the class level
+        docstring, or as a docstring on the __init__ method itself.
+
+        Either form is acceptable, but the two should not be mixed. Choose one
+        convention to document the __init__ method and be consistent with it.
+
+        Note:
+          Do not include the `self` parameter in the ``Args`` section.
+
+        Args:
+          param1 (str): Description of `param1`.
+          param2 (list of str): Description of `param2`. Multiple
+            lines are supported.
+          param3 (int, optional): Description of `param3`, defaults to 0.
+
+        """
+        self.attr1 = param1
+        self.attr2 = param2
+        self.attr3 = param3
+
+    def example_method(self, param1, param2):
+        """Class methods are similar to regular functions.
+
+        Note:
+          Do not include the `self` parameter in the ``Args`` section.
+
+        Args:
+          param1: The first parameter.
+          param2: The second parameter.
+
+        Returns:
+          True if successful, False otherwise.
+
+        """
+        return True
+
+    def __special__(self):
+        """By default special members with docstrings are included.
+
+        Special members are any methods or attributes that start with and
+        end with a double underscore. Any special member with a docstring
+        will be included in the output.
+
+        This behavior can be disabled by changing the following setting in
+        Sphinx's conf.py::
+
+            napoleon_include_special_with_doc = False
+
+        """
+        pass
+
+    def __special_without_docstring__(self):
+        pass
+
+    def _private(self):
+        """By default private members are not included.
+
+        Private members are any methods or attributes that start with an
+        underscore and are *not* special. By default they are not included
+        in the output.
+
+        This behavior can be changed such that private members *are* included
+        by changing the following setting in Sphinx's conf.py::
+
+            napoleon_include_private_with_doc = True
+
+        """
+        pass
+
+    def _private_without_docstring(self):
+        pass
diff --git a/doc/ext/example_google.rst b/doc/ext/example_google.rst
new file mode 100644
index 0000000..0650808
--- /dev/null
+++ b/doc/ext/example_google.rst
@@ -0,0 +1,15 @@
+:orphan:
+
+.. _example_google:
+
+Example Google Style Python Docstrings
+======================================
+
+.. seealso::
+
+   :ref:`example_numpy`
+
+Download: :download:`example_google.py <example_google.py>`
+
+.. literalinclude:: example_google.py
+   :language: python
diff --git a/doc/ext/example_numpy.py b/doc/ext/example_numpy.py
new file mode 100644
index 0000000..df1d20e
--- /dev/null
+++ b/doc/ext/example_numpy.py
@@ -0,0 +1,272 @@
+# -*- coding: utf-8 -*-
+"""Example NumPy style docstrings.
+
+This module demonstrates documentation as specified by the `NumPy
+Documentation HOWTO`_. Docstrings may extend over multiple lines. Sections
+are created with a section header followed by an underline of equal length.
+
+Example
+-------
+Examples can be given using either the ``Example`` or ``Examples``
+sections. Sections support any reStructuredText formatting, including
+literal blocks::
+
+    $ python example_numpy.py
+
+
+Section breaks are created with two blank lines. Section breaks are also
+implicitly created anytime a new section starts. Section bodies *may* be
+indented:
+
+Notes
+-----
+    This is an example of an indented section. It's like any other section,
+    but the body is indented to help it stand out from surrounding text.
+
+If a section is indented, then a section break is created simply by
+resuming unindented text.
+
+Attributes
+----------
+module_level_variable : int
+    Module level variables may be documented in either the ``Attributes``
+    section of the module docstring, or in an inline docstring immediately
+    following the variable.
+
+    Either form is acceptable, but the two should not be mixed. Choose
+    one convention to document module level variables and be consistent
+    with it.
+
+.. _NumPy Documentation HOWTO:
+   https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
+
+"""
+
+module_level_variable = 12345
+
+
+def module_level_function(param1, param2=None, *args, **kwargs):
+    """This is an example of a module level function.
+
+    Function parameters should be documented in the ``Parameters`` section.
+    The name of each parameter is required. The type and description of each
+    parameter is optional, but should be included if not obvious.
+
+    If the parameter itself is optional, it should be noted by adding
+    ", optional" to the type. If \*args or \*\*kwargs are accepted, they
+    should be listed as \*args and \*\*kwargs.
+
+    The format for a parameter is::
+
+        name : type
+            description
+
+            The description may span multiple lines. Following lines
+            should be indented to match the first line of the description.
+
+            Multiple paragraphs are supported in parameter
+            descriptions.
+
+    Parameters
+    ----------
+    param1 : int
+        The first parameter.
+    param2 : str, optional
+        The second parameter, defaults to None.
+    *args
+        Variable length argument list.
+    **kwargs
+        Arbitrary keyword arguments.
+
+    Returns
+    -------
+    bool
+        True if successful, False otherwise.
+
+        The return type is not optional. The ``Returns`` section may span
+        multiple lines and paragraphs. Following lines should be indented to
+        match the first line of the description.
+
+        The ``Returns`` section supports any reStructuredText formatting,
+        including literal blocks::
+
+            {
+                'param1': param1,
+                'param2': param2
+            }
+
+    Raises
+    ------
+    AttributeError
+        The ``Raises`` section is a list of all exceptions
+        that are relevant to the interface.
+    ValueError
+        If `param2` is equal to `param1`.
+
+    """
+    if param1 == param2:
+        raise ValueError('param1 may not be equal to param2')
+    return True
+
+
+def example_generator(n):
+    """Generators have a ``Yields`` section instead of a ``Returns`` section.
+
+    Parameters
+    ----------
+    n : int
+        The upper limit of the range to generate, from 0 to `n` - 1
+
+    Yields
+    ------
+    int
+        The next number in the range of 0 to `n` - 1
+
+    Examples
+    --------
+    Examples should be written in doctest format, and should illustrate how
+    to use the function.
+
+    >>> print [i for i in example_generator(4)]
+    [0, 1, 2, 3]
+
+    """
+    for i in range(n):
+        yield i
+
+
+class ExampleError(Exception):
+    """Exceptions are documented in the same way as classes.
+
+    The __init__ method may be documented in either the class level
+    docstring, or as a docstring on the __init__ method itself.
+
+    Either form is acceptable, but the two should not be mixed. Choose one
+    convention to document the __init__ method and be consistent with it.
+
+    Note
+    ----
+    Do not include the `self` parameter in the ``Parameters`` section.
+
+    Parameters
+    ----------
+    msg : str
+        Human readable string describing the exception.
+    code : int, optional
+        Error code, defaults to 2.
+
+    Attributes
+    ----------
+    msg : str
+        Human readable string describing the exception.
+    code : int
+        Exception error code.
+
+    """
+    def __init__(self, msg, code=2):
+        self.msg = msg
+        self.code = code
+
+
+class ExampleClass(object):
+    """The summary line for a class docstring should fit on one line.
+
+    If the class has public attributes, they should be documented here
+    in an ``Attributes`` section and follow the same formatting as a
+    function's ``Parameters`` section.
+
+    Attributes
+    ----------
+    attr1 : str
+        Description of `attr1`.
+    attr2 : list of str
+        Description of `attr2`.
+    attr3 : int
+        Description of `attr3`.
+
+    """
+    def __init__(self, param1, param2, param3=0):
+        """Example of docstring on the __init__ method.
+
+        The __init__ method may be documented in either the class level
+        docstring, or as a docstring on the __init__ method itself.
+
+        Either form is acceptable, but the two should not be mixed. Choose one
+        convention to document the __init__ method and be consistent with it.
+
+        Note
+        ----
+        Do not include the `self` parameter in the ``Parameters`` section.
+
+        Parameters
+        ----------
+        param1 : str
+            Description of `param1`.
+        param2 : list of str
+            Description of `param2`. Multiple
+            lines are supported.
+        param3 : int, optional
+            Description of `param3`, defaults to 0.
+
+        """
+        self.attr1 = param1
+        self.attr2 = param2
+        self.attr3 = param3
+
+    def example_method(self, param1, param2):
+        """Class methods are similar to regular functions.
+
+        Note
+        ----
+        Do not include the `self` parameter in the ``Parameters`` section.
+
+        Parameters
+        ----------
+        param1
+            The first parameter.
+        param2
+            The second parameter.
+
+        Returns
+        -------
+        bool
+            True if successful, False otherwise.
+
+        """
+        return True
+
+    def __special__(self):
+        """By default special members with docstrings are included.
+
+        Special members are any methods or attributes that start with and
+        end with a double underscore. Any special member with a docstring
+        will be included in the output.
+
+        This behavior can be disabled by changing the following setting in
+        Sphinx's conf.py::
+
+            napoleon_include_special_with_doc = False
+
+        """
+        pass
+
+    def __special_without_docstring__(self):
+        pass
+
+    def _private(self):
+        """By default private members are not included.
+
+        Private members are any methods or attributes that start with an
+        underscore and are *not* special. By default they are not included
+        in the output.
+
+        This behavior can be changed such that private members *are* included
+        by changing the following setting in Sphinx's conf.py::
+
+            napoleon_include_private_with_doc = True
+
+        """
+        pass
+
+    def _private_without_docstring(self):
+        pass
diff --git a/doc/ext/example_numpy.rst b/doc/ext/example_numpy.rst
new file mode 100644
index 0000000..a3b4161
--- /dev/null
+++ b/doc/ext/example_numpy.rst
@@ -0,0 +1,15 @@
+:orphan:
+
+.. _example_numpy:
+
+Example NumPy Style Python Docstrings
+======================================
+
+.. seealso::
+
+   :ref:`example_google`
+
+Download: :download:`example_numpy.py <example_numpy.py>`
+
+.. literalinclude:: example_numpy.py
+   :language: python
diff --git a/doc/ext/intersphinx.rst b/doc/ext/intersphinx.rst
index 7997472..94047f8 100644
--- a/doc/ext/intersphinx.rst
+++ b/doc/ext/intersphinx.rst
@@ -88,7 +88,7 @@
 
    This will download the corresponding :file:`objects.inv` file from the
    Internet and generate links to the pages under the given URI.  The downloaded
-   inventory is cached in the Sphinx environment, so it must be redownloaded
+   inventory is cached in the Sphinx environment, so it must be re-downloaded
    whenever you do a full rebuild.
 
    A second example, showing the meaning of a non-``None`` value of the second
@@ -99,8 +99,22 @@
 
    This will read the inventory from :file:`python-inv.txt` in the source
    directory, but still generate links to the pages under
-   ``http://docs.python.org/3.2``.  It is up to you to update the inventory file as
-   new objects are added to the Python documentation.
+   ``http://docs.python.org/3.2``.  It is up to you to update the inventory file
+   as new objects are added to the Python documentation.
+
+   **Multiple target for the inventory**
+
+   .. versionadded:: 1.3
+
+   Alternative files can be specified for each inventory. One can give a
+   tuple for the second inventory tuple item as shown in the following
+   example. This will read the inventory iterating through the (second)
+   tuple items until the first successful fetch. The primary use case for
+   this to specify mirror sites for server downtime of the primary
+   inventory::
+
+      intersphinx_mapping = {'python': ('http://docs.python.org/3.2',
+                                        (None, 'python-inv.txt'))}
 
 .. confval:: intersphinx_cache_limit
 
diff --git a/doc/ext/linkcode.rst b/doc/ext/linkcode.rst
index a69a5b1..05d2cc6 100644
--- a/doc/ext/linkcode.rst
+++ b/doc/ext/linkcode.rst
@@ -31,7 +31,8 @@
    - ``py``: ``module`` (name of the module), ``fullname`` (name of the object)
    - ``c``: ``names`` (list of names for the object)
    - ``cpp``: ``names`` (list of names for the object)
-   - ``javascript``: ``object`` (name of the object), ``fullname`` (name of the item)
+   - ``javascript``: ``object`` (name of the object), ``fullname``
+     (name of the item)
 
    Example:
 
diff --git a/doc/ext/math.rst b/doc/ext/math.rst
index 8b2924c..4c15461 100644
--- a/doc/ext/math.rst
+++ b/doc/ext/math.rst
@@ -169,8 +169,8 @@
 
 .. confval:: pngmath_add_tooltips
 
-   Default: true.  If false, do not add the LaTeX code as an "alt" attribute for
-   math images.
+   Default: ``True``.  If false, do not add the LaTeX code as an "alt" attribute
+   for math images.
 
    .. versionadded:: 1.1
 
@@ -197,7 +197,7 @@
 
    The default is the ``http://`` URL that loads the JS files from the `MathJax
    CDN <http://docs.mathjax.org/en/latest/start.html>`_.  If you want MathJax to
-   be available offline, you have to donwload it and set this value to a
+   be available offline, you have to download it and set this value to a
    different path.
 
    The path can be absolute or relative; if it is relative, it is relative to
diff --git a/doc/ext/napoleon.rst b/doc/ext/napoleon.rst
new file mode 100644
index 0000000..8d4a931
--- /dev/null
+++ b/doc/ext/napoleon.rst
@@ -0,0 +1,380 @@
+:mod:`sphinx.ext.napoleon` -- Support for NumPy and Google style docstrings
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. module:: sphinx.ext.napoleon
+   :synopsis: Support for NumPy and Google style docstrings
+
+.. moduleauthor:: Rob Ruana
+
+.. versionadded:: 1.3
+
+Napoleon - *Marching toward legible docstrings*
+===============================================
+
+Are you tired of writing docstrings that look like this::
+
+    :param path: The path of the file to wrap
+    :type path: str
+    :param field_storage: The :class:`FileStorage` instance to wrap
+    :type field_storage: FileStorage
+    :param temporary: Whether or not to delete the file when the File
+       instance is destructed
+    :type temporary: bool
+    :returns: A buffered writable file descriptor
+    :rtype: BufferedFileStorage
+
+`ReStructuredText`_ is great, but it creates visually dense, hard to read
+`docstrings`_. Compare the jumble above to the same thing rewritten
+according to the `Google Python Style Guide`_::
+
+    Args:
+        path (str): The path of the file to wrap
+        field_storage (FileStorage): The :class:`FileStorage` instance to wrap
+        temporary (bool): Whether or not to delete the file when the File
+           instance is destructed
+
+    Returns:
+        BufferedFileStorage: A buffered writable file descriptor
+
+Much more legible, no?
+
+Napoleon is a :doc:`../extensions` that enables Sphinx to parse both `NumPy`_
+and `Google`_ style docstrings - the style recommended by `Khan Academy`_.
+
+Napoleon is a pre-processor that parses `NumPy`_ and `Google`_ style
+docstrings and converts them to reStructuredText before Sphinx attempts to
+parse them. This happens in an intermediate step while Sphinx is processing
+the documentation, so it doesn't modify any of the docstrings in your actual
+source code files.
+
+.. _ReStructuredText: http://docutils.sourceforge.net/rst.html
+.. _docstrings: http://www.python.org/dev/peps/pep-0287/
+.. _Google Python Style Guide:
+   http://google-styleguide.googlecode.com/svn/trunk/pyguide.html
+.. _Google:
+   http://google-styleguide.googlecode.com/svn/trunk/pyguide.html#Comments
+.. _NumPy:
+   https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
+.. _Khan Academy:
+   https://sites.google.com/a/khanacademy.org/forge/for-developers/styleguide/python#TOC-Docstrings
+
+Getting Started
+---------------
+
+1. After :doc:`setting up Sphinx <../tutorial>` to build your docs, enable
+   napoleon in the Sphinx `conf.py` file::
+
+       # conf.py
+
+       # Add autodoc and napoleon to the extensions list
+       extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon']
+
+2. Use `sphinx-apidoc` to build your API documentation::
+
+       $ sphinx-apidoc -f -o docs/source projectdir
+
+
+Docstrings
+----------
+
+Napoleon interprets every docstring that :mod:`autodoc <sphinx.ext.autodoc>`
+can find, including docstrings on: ``modules``, ``classes``, ``attributes``,
+``methods``, ``functions``, and ``variables``. Inside each docstring,
+specially formatted `Sections`_ are parsed and converted to
+reStructuredText.
+
+All standard reStructuredText formatting still works as expected.
+
+
+.. _Sections:
+
+Docstring Sections
+------------------
+
+All of the following section headers are supported:
+
+    * ``Args`` *(alias of Parameters)*
+    * ``Arguments`` *(alias of Parameters)*
+    * ``Attributes``
+    * ``Example``
+    * ``Examples``
+    * ``Keyword Args`` *(alias of Keyword Arguments)*
+    * ``Keyword Arguments``
+    * ``Methods``
+    * ``Note``
+    * ``Notes``
+    * ``Other Parameters``
+    * ``Parameters``
+    * ``Return`` *(alias of Returns)*
+    * ``Returns``
+    * ``Raises``
+    * ``References``
+    * ``See Also``
+    * ``Warning``
+    * ``Warnings`` *(alias of Warning)*
+    * ``Warns``
+    * ``Yields``
+
+Google vs NumPy
+---------------
+
+Napoleon supports two styles of docstrings: `Google`_ and `NumPy`_. The
+main difference between the two styles is that Google uses indention to
+separate sections, whereas NumPy uses underlines.
+
+Google style::
+
+    def func(arg1, arg2):
+        """Summary line.
+
+        Extended description of function.
+
+        Args:
+            arg1 (int): Description of arg1
+            arg2 (str): Description of arg2
+
+        Returns:
+            bool: Description of return value
+
+        """
+        return True
+
+NumPy style::
+
+    def func(arg1, arg2):
+        """Summary line.
+
+        Extended description of function.
+
+        Parameters
+        ----------
+        arg1 : int
+            Description of arg1
+        arg2 : str
+            Description of arg2
+
+        Returns
+        -------
+        bool
+            Description of return value
+
+        """
+        return True
+
+NumPy style tends to require more vertical space, whereas Google style
+tends to use more horizontal space. Google style tends to be easier to
+read for short and simple docstrings, whereas NumPy style tends be easier
+to read for long and in-depth docstrings.
+
+The `Khan Academy`_ recommends using Google style.
+
+The choice between styles is largely aesthetic, but the two styles should
+not be mixed. Choose one style for your project and be consistent with it.
+
+.. seealso::
+
+   For complete examples:
+
+   * :ref:`example_google`
+   * :ref:`example_numpy`
+
+
+Configuration
+=============
+
+Listed below are all the settings used by napoleon and their default
+values. These settings can be changed in the Sphinx `conf.py` file. Make
+sure that both "sphinx.ext.autodoc" and "sphinx.ext.napoleon" are
+enabled in `conf.py`::
+
+    # conf.py
+
+    # Add any Sphinx extension module names here, as strings
+    extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon']
+
+    # Napoleon settings
+    napoleon_google_docstring = True
+    napoleon_numpy_docstring = True
+    napoleon_include_private_with_doc = False
+    napoleon_include_special_with_doc = True
+    napoleon_use_admonition_for_examples = False
+    napoleon_use_admonition_for_notes = False
+    napoleon_use_admonition_for_references = False
+    napoleon_use_ivar = False
+    napoleon_use_param = True
+    napoleon_use_rtype = True
+
+.. _Google style:
+   http://google-styleguide.googlecode.com/svn/trunk/pyguide.html
+.. _NumPy style:
+   https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
+
+
+
+.. confval:: napoleon_google_docstring
+
+   True to parse `Google style`_ docstrings. False to disable support
+   for Google style docstrings. *Defaults to True.*
+
+.. confval:: napoleon_numpy_docstring
+
+   True to parse `NumPy style`_ docstrings. False to disable support
+   for NumPy style docstrings. *Defaults to True.*
+
+.. confval:: napoleon_include_private_with_doc
+
+   True to include private members (like ``_membername``) with docstrings
+   in the documentation. False to fall back to Sphinx's default behavior.
+   *Defaults to False.*
+
+   **If True**::
+
+       def _included(self):
+           """
+           This will be included in the docs because it has a docstring
+           """
+           pass
+
+       def _skipped(self):
+           # This will NOT be included in the docs
+           pass
+
+.. confval:: napoleon_include_special_with_doc
+
+   True to include special members (like ``__membername__``) with
+   docstrings in the documentation. False to fall back to Sphinx's
+   default behavior. *Defaults to True.*
+
+   **If True**::
+
+       def __str__(self):
+           """
+           This will be included in the docs because it has a docstring
+           """
+           return unicode(self).encode('utf-8')
+
+       def __unicode__(self):
+           # This will NOT be included in the docs
+           return unicode(self.__class__.__name__)
+
+.. confval:: napoleon_use_admonition_for_examples
+
+   True to use the ``.. admonition::`` directive for the **Example** and
+   **Examples** sections. False to use the ``.. rubric::`` directive
+   instead. One may look better than the other depending on what HTML
+   theme is used. *Defaults to False.*
+
+   This `NumPy style`_ snippet will be converted as follows::
+
+       Example
+       -------
+       This is just a quick example
+
+   **If True**::
+
+       .. admonition:: Example
+
+          This is just a quick example
+
+   **If False**::
+
+       .. rubric:: Example
+
+       This is just a quick example
+
+.. confval:: napoleon_use_admonition_for_notes
+
+   True to use the ``.. admonition::`` directive for **Notes** sections.
+   False to use the ``.. rubric::`` directive instead. *Defaults to False.*
+
+   .. note:: The singular **Note** section will always be converted to a
+      ``.. note::`` directive.
+
+   .. seealso::
+
+      :attr:`napoleon_use_admonition_for_examples`
+
+.. confval:: napoleon_use_admonition_for_references
+
+   True to use the ``.. admonition::`` directive for **References**
+   sections. False to use the ``.. rubric::`` directive instead.
+   *Defaults to False.*
+
+   .. seealso::
+
+      :attr:`napoleon_use_admonition_for_examples`
+
+.. confval:: napoleon_use_ivar
+
+   True to use the ``:ivar:`` role for instance variables. False to use
+   the ``.. attribute::`` directive instead. *Defaults to False.*
+
+   This `NumPy style`_ snippet will be converted as follows::
+
+       Attributes
+       ----------
+       attr1 : int
+           Description of `attr1`
+
+   **If True**::
+
+       :ivar attr1: Description of `attr1`
+       :vartype attr1: int
+
+   **If False**::
+
+       .. attribute:: attr1
+
+          *int*
+
+          Description of `attr1`
+
+.. confval:: napoleon_use_param
+
+   True to use a ``:param:`` role for each function parameter. False to
+   use a single ``:parameters:`` role for all the parameters.
+   *Defaults to True.*
+
+   This `NumPy style`_ snippet will be converted as follows::
+
+       Parameters
+       ----------
+       arg1 : str
+           Description of `arg1`
+       arg2 : int, optional
+           Description of `arg2`, defaults to 0
+
+   **If True**::
+
+       :param arg1: Description of `arg1`
+       :type arg1: str
+       :param arg2: Description of `arg2`, defaults to 0
+       :type arg2: int, optional
+
+   **If False**::
+
+       :parameters: * **arg1** (*str*) --
+                      Description of `arg1`
+                    * **arg2** (*int, optional*) --
+                      Description of `arg2`, defaults to 0
+
+.. confval:: napoleon_use_rtype
+
+   True to use the ``:rtype:`` role for the return type. False to output
+   the return type inline with the description. *Defaults to True.*
+
+   This `NumPy style`_ snippet will be converted as follows::
+
+       Returns
+       -------
+       bool
+           True if successful, False otherwise
+
+   **If True**::
+
+       :returns: True if successful, False otherwise
+       :rtype: bool
+
+   **If False**::
+
+       :returns: *bool* -- True if successful, False otherwise
diff --git a/doc/ext/oldcmarkup.rst b/doc/ext/oldcmarkup.rst
deleted file mode 100644
index 0fdd9fe..0000000
--- a/doc/ext/oldcmarkup.rst
+++ /dev/null
@@ -1,35 +0,0 @@
-:mod:`sphinx.ext.oldcmarkup` -- Compatibility extension for old C markup
-========================================================================
-
-.. module:: sphinx.ext.oldcmarkup
-   :synopsis: Allow further use of the pre-domain C markup
-.. moduleauthor:: Georg Brandl
-
-.. versionadded:: 1.0
-
-
-This extension is a transition helper for projects that used the old
-(pre-domain) C markup, i.e. the directives like ``cfunction`` and roles like
-``cfunc``.  Since the introduction of domains, they must be called by their
-fully-qualified name (``c:function`` and ``c:func``, respectively) or, with the
-default domain set to ``c``, by their new name (``function`` and ``func``).
-(See :ref:`c-domain` for the details.)
-
-If you activate this extension, it will register the old names, and you can
-use them like before Sphinx 1.0.  The directives are:
-
-- ``cfunction``
-- ``cmember``
-- ``cmacro``
-- ``ctype``
-- ``cvar``
-
-The roles are:
-
-- ``cdata``
-- ``cfunc``
-- ``cmacro``
-- ``ctype``
-
-However, it is advised to migrate to the new markup -- this extension is a
-compatibility convenience and will disappear in a future version of Sphinx.
diff --git a/doc/ext/todo.rst b/doc/ext/todo.rst
index 349d286..c0d94ba 100644
--- a/doc/ext/todo.rst
+++ b/doc/ext/todo.rst
@@ -13,18 +13,19 @@
 
    Use this directive like, for example, :rst:dir:`note`.
 
-   It will only show up in the output if :confval:`todo_include_todos` is true.
+   It will only show up in the output if :confval:`todo_include_todos` is
+   ``True``.
 
 
 .. rst:directive:: todolist
 
    This directive is replaced by a list of all todo directives in the whole
-   documentation, if :confval:`todo_include_todos` is true.
+   documentation, if :confval:`todo_include_todos` is ``True``.
 
 
 There is also an additional config value:
 
 .. confval:: todo_include_todos
 
-   If this is ``True``, :rst:dir:`todo` and :rst:dir:`todolist` produce output, else
-   they produce nothing.  The default is ``False``.
+   If this is ``True``, :rst:dir:`todo` and :rst:dir:`todolist` produce output,
+   else they produce nothing.  The default is ``False``.
diff --git a/doc/ext/viewcode.rst b/doc/ext/viewcode.rst
index ba6c8f8..f2b6c92 100644
--- a/doc/ext/viewcode.rst
+++ b/doc/ext/viewcode.rst
@@ -16,4 +16,25 @@
 from the source to the description will also be inserted.
 
 There are currently no configuration values for this extension; you just need to
-add ``'sphinx.ext.viewcode'`` to your :confval:`extensions` value for it to work.
+add ``'sphinx.ext.viewcode'`` to your :confval:`extensions` value for it to
+work.
+
+There is also an additional config value:
+
+.. confval:: viewcode_import
+
+   If this is ``True``, viewcode extension will follow alias objects that
+   imported from another module such as functions, classes and attributes.
+   As side effects, this option
+   else they produce nothing.  The default is ``True``.
+
+   .. warning::
+
+      :confval:`viewcode_import` **imports** the modules to be followed real
+      location.  If any modules have side effects on import, these will be
+      executed by ``viewcode`` when ``sphinx-build`` is run.
+
+      If you document scripts (as opposed to library modules), make sure their
+      main routine is protected by a ``if __name__ == '__main__'`` condition.
+
+   .. versionadded:: 1.3
diff --git a/doc/extdev/appapi.rst b/doc/extdev/appapi.rst
index 0321f5e..8df8194 100644
--- a/doc/extdev/appapi.rst
+++ b/doc/extdev/appapi.rst
@@ -82,16 +82,31 @@
 
    Register an event called *name*.  This is needed to be able to emit it.
 
+.. method:: Sphinx.set_translator(name, translator_class)
+               
+   Register or override a Docutils translator class. This is used to register
+   a custom output translator or to replace a builtin translator.
+   This allows extensions to use custom translator and define custom
+   nodes for the translator (see :meth:`add_node`).
+
+   This is a API version of :confval:`html_translator_class` for all other
+   builders. Note that if :confval:`html_translator_class` is specified and
+   this API is called for html related builders, API overriding takes
+   precedence.
+
+   .. versionadded:: 1.3
+
 .. method:: Sphinx.add_node(node, **kwds)
 
    Register a Docutils node class.  This is necessary for Docutils internals.
    It may also be used in the future to validate nodes in the parsed documents.
 
    Node visitor functions for the Sphinx HTML, LaTeX, text and manpage writers
-   can be given as keyword arguments: the keyword must be one or more of
-   ``'html'``, ``'latex'``, ``'text'``, ``'man'``, ``'texinfo'``, the value a
-   2-tuple of ``(visit, depart)`` methods.  ``depart`` can be ``None`` if the
-   ``visit`` function raises :exc:`docutils.nodes.SkipNode`.  Example:
+   can be given as keyword arguments: the keyword should be one or more of
+   ``'html'``, ``'latex'``, ``'text'``, ``'man'``, ``'texinfo'`` or any other
+   supported translators, the value a 2-tuple of ``(visit, depart)`` methods.
+   ``depart`` can be ``None`` if the ``visit`` function raises
+   :exc:`docutils.nodes.SkipNode`.  Example:
 
    .. code-block:: python
 
@@ -131,8 +146,8 @@
      The directive class must inherit from the class
      ``docutils.parsers.rst.Directive``.
 
-   For example, the (already existing) :rst:dir:`literalinclude` directive would be
-   added like this:
+   For example, the (already existing) :rst:dir:`literalinclude` directive would
+   be added like this:
 
    .. code-block:: python
 
@@ -212,10 +227,13 @@
       .. index:: pair: function; directive
 
    The reference node will be of class ``literal`` (so it will be rendered in a
-   proportional font, as appropriate for code) unless you give the *ref_nodeclass*
-   argument, which must be a docutils node class (most useful are
-   ``docutils.nodes.emphasis`` or ``docutils.nodes.strong`` -- you can also use
-   ``docutils.nodes.generated`` if you want no further text decoration).
+   proportional font, as appropriate for code) unless you give the
+   *ref_nodeclass* argument, which must be a docutils node class.  Most useful
+   are ``docutils.nodes.emphasis`` or ``docutils.nodes.strong`` -- you can also
+   use ``docutils.nodes.generated`` if you want no further text decoration.  If
+   the text should be treated as literal (e.g. no smart quote replacement), but
+   not have typewriter styling, use ``sphinx.addnodes.literal_emphasis`` or
+   ``sphinx.addnodes.literal_strong``.
 
    For the role content, you have the same syntactical possibilities as for
    standard Sphinx roles (see :ref:`xref-syntax`).
@@ -229,8 +247,8 @@
    directive it generates must be empty, and will produce no output.
 
    That means that you can add semantic targets to your sources, and refer to
-   them using custom roles instead of generic ones (like :rst:role:`ref`).  Example
-   call::
+   them using custom roles instead of generic ones (like :rst:role:`ref`).
+   Example call::
 
       app.add_crossref_type('topic', 'topic', 'single: %s', docutils.nodes.emphasis)
 
diff --git a/doc/extdev/index.rst b/doc/extdev/index.rst
index b76928c..a82f33a 100644
--- a/doc/extdev/index.rst
+++ b/doc/extdev/index.rst
@@ -18,6 +18,11 @@
 notifies Sphinx of everything the extension offers -- see the extension tutorial
 for examples.
 
+.. versionadded:: 1.3
+   The ``setup()`` function can return a string, this is treated by Sphinx as
+   the version of the extension and used for informational purposes such as the
+   traceback file when an exception occurs.
+
 The configuration file itself can be treated as an extension if it contains a
 ``setup()`` function.  All other extensions to load must be listed in the
 :confval:`extensions` configuration value.
diff --git a/doc/extdev/tutorial.rst b/doc/extdev/tutorial.rst
index a03d6e0..8f1773c 100644
--- a/doc/extdev/tutorial.rst
+++ b/doc/extdev/tutorial.rst
@@ -45,7 +45,7 @@
    parsed documents into an output format, or otherwise process them (e.g. check
    external links).
 
-   If you have the application object, the environment is available as
+   If you have the application object, the builder is available as
    ``app.builder``.
 
 **Config**
@@ -162,6 +162,8 @@
        app.connect('doctree-resolved', process_todo_nodes)
        app.connect('env-purge-doc', purge_todos)
 
+       return '0.1'   # identifies the version of our extension
+
 The calls in this function refer to classes and functions not yet written.  What
 the individual calls do is the following:
 
diff --git a/doc/extensions.rst b/doc/extensions.rst
index b2adbc1..b0d98e3 100644
--- a/doc/extensions.rst
+++ b/doc/extensions.rst
@@ -31,7 +31,7 @@
    ext/extlinks
    ext/viewcode
    ext/linkcode
-   ext/oldcmarkup
+   ext/napoleon
 
 
 Third-party extensions
diff --git a/doc/faq.rst b/doc/faq.rst
index 7aa35d1..7a49aed 100644
--- a/doc/faq.rst
+++ b/doc/faq.rst
@@ -10,9 +10,9 @@
 -----------
 
 ... create PDF files without LaTeX?
-   You can use `rst2pdf <http://rst2pdf.googlecode.com>`_ version 0.12 or greater
-   which comes with built-in Sphinx integration.  See the :ref:`builders`
-   section for details.
+   You can use `rst2pdf <http://rst2pdf.googlecode.com>`_ version 0.12 or
+   greater which comes with built-in Sphinx integration.  See the
+   :ref:`builders` section for details.
 
 ... get section numbers?
    They are automatic in LaTeX output; for HTML, give a ``:numbered:`` option to
@@ -32,9 +32,9 @@
    See the :ref:`extension tutorial <exttut>`.
 
 ... convert from my existing docs using MoinMoin markup?
-   The easiest way is to convert to xhtml, then convert `xhtml to reST`_.  You'll
-   still need to mark up classes and such, but the headings and code examples
-   come through cleanly.
+   The easiest way is to convert to xhtml, then convert `xhtml to reST`_.
+   You'll still need to mark up classes and such, but the headings and code
+   examples come through cleanly.
 
 ... create HTML slides from Sphinx documents?
    See the "Hieroglyph" package at https://github.com/nyergler/hieroglyph.
@@ -50,10 +50,11 @@
 --------------------
 
 Read the Docs
-    https://readthedocs.org is a documentation hosting service based around Sphinx.
-    They will host sphinx documentation, along with supporting a number of other
-    features including version support, PDF generation, and more. The `Getting
-    Started <http://read-the-docs.readthedocs.org/en/latest/getting_started.html>`_
+    https://readthedocs.org is a documentation hosting service based around
+    Sphinx. They will host sphinx documentation, along with supporting a number
+    of other features including version support, PDF generation, and more. The
+    `Getting Started
+    <http://read-the-docs.readthedocs.org/en/latest/getting_started.html>`_
     guide is a good place to start.
 
 Epydoc
@@ -70,8 +71,8 @@
 
 PyPI
    Jannis Leidel wrote a `setuptools command
-   <https://pypi.python.org/pypi/Sphinx-PyPI-upload>`_ that automatically uploads
-   Sphinx documentation to the PyPI package documentation area at
+   <https://pypi.python.org/pypi/Sphinx-PyPI-upload>`_ that automatically
+   uploads Sphinx documentation to the PyPI package documentation area at
    http://pythonhosted.org/.
 
 GitHub Pages
diff --git a/doc/glossary.rst b/doc/glossary.rst
index 8bc393e..3ef1623 100644
--- a/doc/glossary.rst
+++ b/doc/glossary.rst
@@ -12,7 +12,7 @@
       use the builder builders that e.g. check for broken links in the
       documentation, or build coverage information.
 
-      See :ref:`builders` for an overview over Sphinx' built-in builders.
+      See :ref:`builders` for an overview over Sphinx's built-in builders.
 
    configuration directory
       The directory containing :file:`conf.py`.  By default, this is the same as
@@ -37,11 +37,11 @@
    document name
       Since reST source files can have different extensions (some people like
       ``.txt``, some like ``.rst`` -- the extension can be configured with
-      :confval:`source_suffix`) and different OSes have different path separators,
-      Sphinx abstracts them: :dfn:`document names` are always relative to the
-      :term:`source directory`, the extension is stripped, and path separators
-      are converted to slashes.  All values, parameters and such referring to
-      "documents" expect such document names.
+      :confval:`source_suffix`) and different OSes have different path
+      separators, Sphinx abstracts them: :dfn:`document names` are always
+      relative to the :term:`source directory`, the extension is stripped, and
+      path separators are converted to slashes.  All values, parameters and such
+      referring to "documents" expect such document names.
 
       Examples for document names are ``index``, ``library/zipfile``, or
       ``reference/datamodel/types``.  Note that there is no leading or trailing
@@ -70,8 +70,8 @@
 
    object
       The basic building block of Sphinx documentation.  Every "object
-      directive" (e.g. :rst:dir:`function` or :rst:dir:`object`) creates such a block;
-      and most objects can be cross-referenced to.
+      directive" (e.g. :rst:dir:`function` or :rst:dir:`object`) creates such a
+      block; and most objects can be cross-referenced to.
 
    role
       A reStructuredText markup element that allows marking a piece of text.
diff --git a/doc/install.rst b/doc/install.rst
index bf65387..71e37e9 100644
--- a/doc/install.rst
+++ b/doc/install.rst
@@ -4,7 +4,7 @@
 =================
 
 Since Sphinx is written in the Python language, you need to install Python
-(the required version is at least 2.5) and Sphinx.
+(the required version is at least 2.6) and Sphinx.
 
 Sphinx packages are available on the `Python Package Index
 <https://pypi.python.org/pypi/Sphinx>`_.
@@ -79,8 +79,8 @@
 
 .. note::
 
-   Currently, Python offers two major versions, 2.x and 3.x. Sphinx 1.2 can run
-   under Python 2.5 to 2.7 and 3.1 to 3.3, with the recommended version being
+   Currently, Python offers two major versions, 2.x and 3.x. Sphinx 1.3 can run
+   under Python 2.6, 2.7, 3.2, 3.3, with the recommended version being
    2.7.  This chapter assumes you have installed Python 2.7.
 
 Follow the Windows installer for Python.
diff --git a/doc/intl.rst b/doc/intl.rst
index 3363dc5..c4859d0 100644
--- a/doc/intl.rst
+++ b/doc/intl.rst
@@ -38,9 +38,9 @@
 way to do that.
 
 After Sphinx successfully ran the
-:class:`~sphinx.builders.gettext.MessageCatalogBuilder` you will find a collection
-of ``.pot`` files in your output directory.  These are **catalog templates**
-and contain messages in your original language *only*.
+:class:`~sphinx.builders.gettext.MessageCatalogBuilder` you will find a
+collection of ``.pot`` files in your output directory.  These are **catalog
+templates** and contain messages in your original language *only*.
 
 They can be delivered to translators which will transform them to ``.po`` files
 --- so called **message catalogs** --- containing a mapping from the original
@@ -202,10 +202,13 @@
 
    .. code-block:: bash
 
-      $ tx init --user=<transifex-username> --pass=<transifex-password>
+      $ tx init
       Creating .tx folder...
       Transifex instance [https://www.transifex.com]:
       ...
+      Please enter your transifex username: <transifex-username>
+      Password: <transifex-password>
+      ...
       Done.
 
 #. Upload pot files to transifex service
@@ -285,7 +288,7 @@
 
 .. rubric:: Footnotes
 
-.. [1] See the `GNU gettext utilites
+.. [1] See the `GNU gettext utilities
        <http://www.gnu.org/software/gettext/manual/gettext.html#Introduction>`_
        for details on that software suite.
 .. [2] Because nobody expects the Spanish Inquisition!
diff --git a/doc/intro.rst b/doc/intro.rst
index 66d0c58..a796d93 100644
--- a/doc/intro.rst
+++ b/doc/intro.rst
@@ -54,8 +54,8 @@
 Prerequisites
 -------------
 
-Sphinx needs at least **Python 2.5** or **Python 3.1** to run, as well as the
-docutils_ and Jinja2_ libraries.  Sphinx should work with docutils version 0.7
+Sphinx needs at least **Python 2.6** or **Python 3.2** to run, as well as the
+docutils_ and Jinja2_ libraries.  Sphinx should work with docutils version 0.10
 or some (not broken) SVN trunk snapshot.  If you like to have source code
 highlighting support, you must also install the Pygments_ library.
 
diff --git a/doc/invocation.rst b/doc/invocation.rst
index 654921b..d347f50 100644
--- a/doc/invocation.rst
+++ b/doc/invocation.rst
@@ -83,8 +83,8 @@
 
 .. option:: -t tag
 
-   Define the tag *tag*.  This is relevant for :rst:dir:`only` directives that only
-   include their content if this tag is set.
+   Define the tag *tag*.  This is relevant for :rst:dir:`only` directives that
+   only include their content if this tag is set.
 
    .. versionadded:: 0.6
 
@@ -124,13 +124,22 @@
 .. option:: -D setting=value
 
    Override a configuration value set in the :file:`conf.py` file.  The value
-   must be a string or dictionary value.  For the latter, supply the setting
-   name and key like this: ``-D latex_elements.docclass=scrartcl``.  For boolean
-   values, use ``0`` or ``1`` as the value.
+   must be a number, string, list or dictionary value.
+
+   For lists, you can separate elements with a comma like this: ``-D
+   html_theme_path=path1,path2``.
+
+   For dictionary values, supply the setting name and key like this:
+   ``-D latex_elements.docclass=scrartcl``.
+
+   For boolean values, use ``0`` or ``1`` as the value.
 
    .. versionchanged:: 0.6
       The value can now be a dictionary value.
 
+   .. versionchanged:: 1.3
+      The value can now also be a list value.
+
 .. option:: -A name=value
 
    Make the *name* assigned to *value* in the HTML templates.
@@ -145,8 +154,7 @@
 
 .. option:: -N
 
-   Do not emit colored output.  (On Windows, colored output is disabled in any
-   case.)
+   Do not emit colored output.
 
 .. option:: -v
 
diff --git a/doc/man/sphinx-build.rst b/doc/man/sphinx-build.rst
index aa1d71c..13564ff 100644
--- a/doc/man/sphinx-build.rst
+++ b/doc/man/sphinx-build.rst
@@ -102,12 +102,14 @@
                       Configuration can only be set with the -D option.
 -D <setting=value>    Override a setting from the configuration file.
 -t <tag>              Define *tag* for use in "only" blocks.
--A <name=value>       Pass a value into the HTML templates (only for HTML builders).
+-A <name=value>       Pass a value into the HTML templates (only for HTML
+                      builders).
 -n                    Run in nit-picky mode, warn about all missing references.
 -v                    Increase verbosity (can be repeated).
 -N                    Prevent colored output.
 -q                    Quiet operation, just print warnings and errors on stderr.
--Q                    Very quiet operation, don't print anything except for errors.
+-Q                    Very quiet operation, don't print anything except for
+                      errors.
 -w <file>             Write warnings and errors into the given file, in addition
                       to stderr.
 -W                    Turn warnings into errors.
diff --git a/doc/markup/code.rst b/doc/markup/code.rst
index 957774f..f69bb16 100644
--- a/doc/markup/code.rst
+++ b/doc/markup/code.rst
@@ -79,14 +79,22 @@
 
 This will produce line numbers for all code blocks longer than five lines.
 
-For :rst:dir:`code-block` blocks, a ``linenos`` flag option can be given to switch
-on line numbers for the individual block::
+For :rst:dir:`code-block` blocks, a ``linenos`` flag option can be given to
+switch on line numbers for the individual block::
 
    .. code-block:: ruby
       :linenos:
 
       Some more Ruby code.
 
+The first line number can be selected with the ``lineno-start`` option.  If
+present, ``linenos`` is automatically activated as well.
+
+   .. code-block:: ruby
+      :lineno-start: 10
+
+      Some more Ruby code, with line numbering starting at 10.
+
 Additionally, an ``emphasize-lines`` option can be given to have Pygments
 emphasize particular lines::
 
@@ -102,16 +110,19 @@
 .. versionchanged:: 1.1
    ``emphasize-lines`` has been added.
 
+.. versionchanged:: 1.3
+   ``lineno-start`` has been added.
+
 
 Includes
 ^^^^^^^^
 
 .. rst:directive:: .. literalinclude:: filename
 
-   Longer displays of verbatim text may be included by storing the example text in
-   an external file containing only plain text.  The file may be included using the
-   ``literalinclude`` directive. [1]_ For example, to include the Python source file
-   :file:`example.py`, use::
+   Longer displays of verbatim text may be included by storing the example text
+   in an external file containing only plain text.  The file may be included
+   using the ``literalinclude`` directive. [1]_ For example, to include the
+   Python source file :file:`example.py`, use::
 
       .. literalinclude:: example.py
 
@@ -122,10 +133,11 @@
    Tabs in the input are expanded if you give a ``tab-width`` option with the
    desired tab width.
 
-   The directive also supports the ``linenos`` flag option to switch on line
-   numbers, the ``emphasize-lines`` option to emphasize particular lines, and
-   a ``language`` option to select a language different from the current
-   file's standard language.  Example with options::
+   Like :rst:dir:`code-block`, the directive supports the ``linenos`` flag
+   option to switch on line numbers, the ``lineno-start`` option to select the
+   first line number, the ``emphasize-lines`` option to emphasize particular
+   lines, and a ``language`` option to select a language different from the
+   current file's standard language.  Example with options::
 
       .. literalinclude:: example.rb
          :language: ruby
@@ -168,6 +180,16 @@
    ``prepend`` and ``append`` option, respectively.  This is useful e.g. for
    highlighting PHP code that doesn't include the ``<?php``/``?>`` markers.
 
+
+   If you want to show the diff of the code, you can specify the old
+   file by giving a ``diff`` option::
+
+      .. literalinclude:: example.py
+         :diff: example.py.orig
+
+   This shows the diff between example.py and example.py.orig with unified diff format.
+
+
    .. versionadded:: 0.4.3
       The ``encoding`` option.
    .. versionadded:: 0.6
@@ -175,6 +197,43 @@
       as well as support for absolute filenames.
    .. versionadded:: 1.0
       The ``prepend`` and ``append`` options, as well as ``tab-width``.
+   .. versionadded:: 1.3
+      The ``diff`` option.
+
+
+Showing a file name
+^^^^^^^^^^^^^^^^^^^
+
+.. versionadded:: 1.3
+
+A ``caption`` option can be given to show that name before the code block.  For
+example::
+
+   .. code-block:: python
+      :caption: this.py
+
+      print 'Explicit is better than implicit.'
+
+
+:rst:dir:`literalinclude` also supports the ``caption`` option, with the
+additional feature that if you leave the value empty, the shown filename will be
+exactly the one given as an argument.
+
+
+Dedent
+^^^^^^
+
+.. versionadded:: 1.3
+
+A ``dedent`` option can be given to strip a precedence characters from the code
+block. For example::
+
+   .. literalinclude:: example.rb
+      :language: ruby
+      :dedent: 4
+      :lines: 10-15
+
+:rst:dir:`code-block` also supports the ``dedent`` option.
 
 
 .. rubric:: Footnotes
diff --git a/doc/markup/inline.rst b/doc/markup/inline.rst
index 69dd832..0cc97f4 100644
--- a/doc/markup/inline.rst
+++ b/doc/markup/inline.rst
@@ -24,7 +24,7 @@
 
 Cross-references are generated by many semantic interpreted text roles.
 Basically, you only need to write ``:role:`target```, and a link will be created
-to the item named *target* of the type indicated by *role*.  The links's text
+to the item named *target* of the type indicated by *role*.  The link's text
 will be the same as *target*.
 
 There are some additional facilities, however, that make cross-referencing roles
@@ -102,9 +102,10 @@
      to, but you must give the link an explicit title, using this syntax:
      ``:ref:`Link title <label-name>```.
 
-   Using :rst:role:`ref` is advised over standard reStructuredText links to sections
-   (like ```Section title`_``) because it works across files, when section
-   headings are changed, and for all builders that support cross-references.
+   Using :rst:role:`ref` is advised over standard reStructuredText links to
+   sections (like ```Section title`_``) because it works across files, when
+   section headings are changed, and for all builders that support
+   cross-references.
 
 
 Cross-referencing documents
@@ -349,8 +350,8 @@
 Substitutions
 ~~~~~~~~~~~~~
 
-The documentation system provides three substitutions that are defined by default.
-They are set in the build configuration file.
+The documentation system provides three substitutions that are defined by
+default. They are set in the build configuration file.
 
 .. describe:: |release|
 
diff --git a/doc/markup/misc.rst b/doc/markup/misc.rst
index 5a391d0..fd31480 100644
--- a/doc/markup/misc.rst
+++ b/doc/markup/misc.rst
@@ -52,16 +52,16 @@
 
    By default, this markup isn't reflected in the output in any way (it helps
    keep track of contributions), but you can set the configuration value
-   :confval:`show_authors` to True to make them produce a paragraph in the
+   :confval:`show_authors` to ``True`` to make them produce a paragraph in the
    output.
 
 
 .. rst:directive:: .. codeauthor:: name <email>
 
-   The :rst:dir:`codeauthor` directive, which can appear multiple times, names the
-   authors of the described code, just like :rst:dir:`sectionauthor` names the
-   author(s) of a piece of documentation.  It too only produces output if the
-   :confval:`show_authors` configuration value is True.
+   The :rst:dir:`codeauthor` directive, which can appear multiple times, names
+   the authors of the described code, just like :rst:dir:`sectionauthor` names
+   the author(s) of a piece of documentation.  It too only produces output if
+   the :confval:`show_authors` configuration value is ``True``.
 
 
 Index-generating markup
@@ -189,6 +189,14 @@
    These standard tags are set *after* the configuration file is read, so they
    are not available there.
 
+   All tags must follow the standard Python identifier syntax as set out in
+   the `Identifiers and keywords
+   <https://docs.python.org/reference/lexical_analysis.html#identifiers>`_
+   documentation.  That is, a tag expression may only consist of tags that
+   conform to the syntax of Python variables.  In ASCII, this consists of the
+   uppercase and lowercase letters ``A`` through ``Z``, the underscore ``_``
+   and, except for the first character, the digits ``0`` through ``9``.
+
    .. versionadded:: 0.6
    .. versionchanged:: 1.2
       Added the name of the builder and the prefixes.
diff --git a/doc/markup/para.rst b/doc/markup/para.rst
index b532bc6..c6a49b1 100644
--- a/doc/markup/para.rst
+++ b/doc/markup/para.rst
@@ -70,12 +70,12 @@
    external documents.  These lists are created using the :rst:dir:`seealso`
    directive.
 
-   The :rst:dir:`seealso` directive is typically placed in a section just before any
-   sub-sections.  For the HTML output, it is shown boxed off from the main flow
-   of the text.
+   The :rst:dir:`seealso` directive is typically placed in a section just before
+   any subsections.  For the HTML output, it is shown boxed off from the main
+   flow of the text.
 
-   The content of the :rst:dir:`seealso` directive should be a reST definition list.
-   Example::
+   The content of the :rst:dir:`seealso` directive should be a reST definition
+   list. Example::
 
       .. seealso::
 
@@ -206,8 +206,8 @@
    continuation line must begin with a colon placed at the same column as in the
    first line.
 
-   The argument to :rst:dir:`productionlist` serves to distinguish different sets of
-   production lists that belong to different grammars.
+   The argument to :rst:dir:`productionlist` serves to distinguish different
+   sets of production lists that belong to different grammars.
 
    Blank lines are not allowed within ``productionlist`` directive arguments.
 
diff --git a/doc/more.png b/doc/more.png
index 3eb7b05..a27a0fc 100644
--- a/doc/more.png
+++ b/doc/more.png
Binary files differ
diff --git a/doc/pythonorg.png b/doc/pythonorg.png
index 83b54df..32f0787 100644
--- a/doc/pythonorg.png
+++ b/doc/pythonorg.png
Binary files differ
diff --git a/doc/rest.rst b/doc/rest.rst
index b5efbf9..c6a4ada 100644
--- a/doc/rest.rst
+++ b/doc/rest.rst
@@ -312,7 +312,7 @@
   - :dudir:`default-role` (set a new default role)
   - :dudir:`role` (create a new role)
 
-  Since these are only per-file, better use Sphinx' facilities for setting the
+  Since these are only per-file, better use Sphinx's facilities for setting the
   :confval:`default_role`.
 
 Do *not* use the directives :dudir:`sectnum`, :dudir:`header` and
@@ -485,5 +485,6 @@
 
 .. rubric:: Footnotes
 
-.. [1] When the default domain contains a :rst:dir:`class` directive, this directive
-       will be shadowed.  Therefore, Sphinx re-exports it as :rst:dir:`rst-class`.
+.. [1] When the default domain contains a :rst:dir:`class` directive, this
+       directive will be shadowed.  Therefore, Sphinx re-exports it as
+       :rst:dir:`rst-class`.
diff --git a/doc/templating.rst b/doc/templating.rst
index b9561b6..fde00ef 100644
--- a/doc/templating.rst
+++ b/doc/templating.rst
@@ -11,8 +11,8 @@
 excellent documentation for those who need to make themselves familiar with it.
 
 
-Do I need to use Sphinx' templates to produce HTML?
----------------------------------------------------
+Do I need to use Sphinx's templates to produce HTML?
+----------------------------------------------------
 
 No.  You have several other options:
 
@@ -50,7 +50,7 @@
 template is evaluated, **tags**, which control the logic of the template and
 **blocks** which are used for template inheritance.
 
-Sphinx' *basic* theme provides base templates with a couple of blocks it will
+Sphinx's *basic* theme provides base templates with a couple of blocks it will
 fill with data.  These are located in the :file:`themes/basic` subdirectory of
 the Sphinx installation directory, and used by all builtin Sphinx themes.
 Templates with the same name in the :confval:`templates_path` override templates
@@ -273,7 +273,7 @@
 .. data:: has_source
 
    True if the reST document sources are copied (if :confval:`html_copy_source`
-   is true).
+   is ``True``).
 
 .. data:: last_updated
 
@@ -333,7 +333,7 @@
 
 .. data:: show_source
 
-   True if :confval:`html_show_sourcelink` is true.
+   True if :confval:`html_show_sourcelink` is ``True``.
 
 .. data:: sphinx_version
 
@@ -372,7 +372,7 @@
 .. data:: sourcename
 
    The name of the copied source file for the current document.  This is only
-   nonempty if the :confval:`html_copy_source` value is true.
+   nonempty if the :confval:`html_copy_source` value is ``True``.
 
 .. data:: toc
 
@@ -384,14 +384,14 @@
    A callable yielding the global TOC tree containing the current page, rendered
    as HTML bullet lists.  Optional keyword arguments:
 
-   * ``collapse`` (true by default): if true, all TOC entries that are not
+   * ``collapse`` (``True`` by default): if true, all TOC entries that are not
      ancestors of the current page are collapsed
 
    * ``maxdepth`` (defaults to the max depth selected in the toctree directive):
      the maximum depth of the tree; set it to ``-1`` to allow unlimited depth
 
-   * ``titles_only`` (false by default): if true, put only toplevel document
+   * ``titles_only`` (``False`` by default): if true, put only toplevel document
      titles in the tree
 
-   * ``includehidden`` (false by default): if true, the TOC tree will also
+   * ``includehidden`` (``False`` by default): if true, the TOC tree will also
      contain hidden entries.
diff --git a/doc/themes/agogo.png b/doc/themes/agogo.png
index d29aa45..453a1f7 100644
--- a/doc/themes/agogo.png
+++ b/doc/themes/agogo.png
Binary files differ
diff --git a/doc/themes/bizstyle.png b/doc/themes/bizstyle.png
new file mode 100644
index 0000000..4deae9a
--- /dev/null
+++ b/doc/themes/bizstyle.png
Binary files differ
diff --git a/doc/themes/default.png b/doc/themes/default.png
index 93d8526..6989ebe 100644
--- a/doc/themes/default.png
+++ b/doc/themes/default.png
Binary files differ
diff --git a/doc/themes/fullsize/agogo.png b/doc/themes/fullsize/agogo.png
index 93fadfc..bfdba3a 100644
--- a/doc/themes/fullsize/agogo.png
+++ b/doc/themes/fullsize/agogo.png
Binary files differ
diff --git a/doc/themes/fullsize/bizstyle.png b/doc/themes/fullsize/bizstyle.png
new file mode 100644
index 0000000..d917e2f
--- /dev/null
+++ b/doc/themes/fullsize/bizstyle.png
Binary files differ
diff --git a/doc/themes/fullsize/default.png b/doc/themes/fullsize/default.png
index b6af8bc..9c00f68 100644
--- a/doc/themes/fullsize/default.png
+++ b/doc/themes/fullsize/default.png
Binary files differ
diff --git a/doc/themes/fullsize/haiku.png b/doc/themes/fullsize/haiku.png
index 1590da5..8d807f4 100644
--- a/doc/themes/fullsize/haiku.png
+++ b/doc/themes/fullsize/haiku.png
Binary files differ
diff --git a/doc/themes/fullsize/nature.png b/doc/themes/fullsize/nature.png
index d42957e..02d8743 100644
--- a/doc/themes/fullsize/nature.png
+++ b/doc/themes/fullsize/nature.png
Binary files differ
diff --git a/doc/themes/fullsize/pyramid.png b/doc/themes/fullsize/pyramid.png
index 429a8b7..961cb89 100644
--- a/doc/themes/fullsize/pyramid.png
+++ b/doc/themes/fullsize/pyramid.png
Binary files differ
diff --git a/doc/themes/fullsize/scrolls.png b/doc/themes/fullsize/scrolls.png
index 7d46f7e..4e5c45f 100644
--- a/doc/themes/fullsize/scrolls.png
+++ b/doc/themes/fullsize/scrolls.png
Binary files differ
diff --git a/doc/themes/fullsize/sphinxdoc.png b/doc/themes/fullsize/sphinxdoc.png
index 722fb90..b746334 100644
--- a/doc/themes/fullsize/sphinxdoc.png
+++ b/doc/themes/fullsize/sphinxdoc.png
Binary files differ
diff --git a/doc/themes/fullsize/traditional.png b/doc/themes/fullsize/traditional.png
index 103fd3c..da69efe 100644
--- a/doc/themes/fullsize/traditional.png
+++ b/doc/themes/fullsize/traditional.png
Binary files differ
diff --git a/doc/themes/haiku.png b/doc/themes/haiku.png
index a8ae855..78a2570 100644
--- a/doc/themes/haiku.png
+++ b/doc/themes/haiku.png
Binary files differ
diff --git a/doc/themes/nature.png b/doc/themes/nature.png
index 3d4f587..cbe773d 100644
--- a/doc/themes/nature.png
+++ b/doc/themes/nature.png
Binary files differ
diff --git a/doc/themes/pyramid.png b/doc/themes/pyramid.png
index b16095c..eb13cd5 100644
--- a/doc/themes/pyramid.png
+++ b/doc/themes/pyramid.png
Binary files differ
diff --git a/doc/themes/scrolls.png b/doc/themes/scrolls.png
index 8073c10..30ccc8d 100644
--- a/doc/themes/scrolls.png
+++ b/doc/themes/scrolls.png
Binary files differ
diff --git a/doc/themes/sphinxdoc.png b/doc/themes/sphinxdoc.png
index f4b59ec..31512d8 100644
--- a/doc/themes/sphinxdoc.png
+++ b/doc/themes/sphinxdoc.png
Binary files differ
diff --git a/doc/themes/traditional.png b/doc/themes/traditional.png
index 4ad2b5c..5ff44f8 100644
--- a/doc/themes/traditional.png
+++ b/doc/themes/traditional.png
Binary files differ
diff --git a/doc/theming.rst b/doc/theming.rst
index 73ec9f2..0a2d726 100644
--- a/doc/theming.rst
+++ b/doc/theming.rst
@@ -102,6 +102,10 @@
 |                    |                    |
 | *haiku*            | *pyramid*          |
 +--------------------+--------------------+
+| |bizstyle|         |                    |
+|                    |                    |
+| *bizstyle*         |                    |
++--------------------+--------------------+
 
 .. |default|     image:: themes/default.png
 .. |sphinxdoc|   image:: themes/sphinxdoc.png
@@ -111,6 +115,7 @@
 .. |nature|      image:: themes/nature.png
 .. |haiku|       image:: themes/haiku.png
 .. |pyramid|     image:: themes/pyramid.png
+.. |bizstyle|    image:: themes/bizstyle.png
 
 Sphinx comes with a selection of themes to choose from.
 
@@ -122,7 +127,7 @@
   these options (which are inherited by the other themes):
 
   - **nosidebar** (true or false): Don't include the sidebar.  Defaults to
-    false.
+    ``False``.
 
   - **sidebarwidth** (an integer): Width of the sidebar in pixels.  (Do not
     include ``px`` in the value.)  Defaults to 230 pixels.
@@ -132,18 +137,18 @@
   options:
 
   - **rightsidebar** (true or false): Put the sidebar on the right side.
-    Defaults to false.
+    Defaults to ``False``.
 
   - **stickysidebar** (true or false): Make the sidebar "fixed" so that it
     doesn't scroll out of view for long body content.  This may not work well
-    with all browsers.  Defaults to false.
+    with all browsers.  Defaults to ``False``.
 
   - **collapsiblesidebar** (true or false): Add an *experimental* JavaScript
     snippet that makes the sidebar collapsible via a button on its side.
-    *Doesn't work with "stickysidebar".* Defaults to false.
+    *Doesn't work with "stickysidebar".* Defaults to ``False``.
 
   - **externalrefs** (true or false): Display external links differently from
-    internal links.  Defaults to false.
+    internal links.  Defaults to ``False``.
 
   There are also various color and font options that can change the color scheme
   without having to write a custom stylesheet:
@@ -152,7 +157,7 @@
   - **footertextcolor** (CSS color): Text color for the footer line.
   - **sidebarbgcolor** (CSS color): Background color for the sidebar.
   - **sidebarbtncolor** (CSS color): Background color for the sidebar collapse
-    button (used when *collapsiblesidebar* is true).
+    button (used when *collapsiblesidebar* is ``True``).
   - **sidebartextcolor** (CSS color): Text color for the sidebar.
   - **sidebarlinkcolor** (CSS color): Link color for the sidebar.
   - **relbarbgcolor** (CSS color): Background color for the relation bar.
@@ -218,10 +223,10 @@
   <http://www.haiku-os.org/docs/userguide/en/contents.html>`_.  The following
   options are supported:
 
-  - **full_logo** (true or false, default false): If this is true, the header
-    will only show the :confval:`html_logo`.  Use this for large logos.  If this
-    is false, the logo (if present) will be shown floating right, and the
-    documentation title will be put in the header.
+  - **full_logo** (true or false, default ``False``): If this is true, the
+    header will only show the :confval:`html_logo`.  Use this for large logos.
+    If this is false, the logo (if present) will be shown floating right, and
+    the documentation title will be put in the header.
   - **textcolor**, **headingcolor**, **linkcolor**, **visitedlinkcolor**,
     **hoverlinkcolor** (CSS colors): Colors for various body elements.
 
@@ -232,10 +237,20 @@
   space which is a sparse resource on ebook readers.  The following options
   are supported:
 
-  - **relbar1** (true or false, default true): If this is true, the
+  - **relbar1** (true or false, default ``True``): If this is true, the
     `relbar1` block is inserted in the epub output, otherwise it is omitted.
-  - **footer**  (true or false, default true): If this is true, the
-    `footer` block is inserted in the epub output, otherwise it is ommitted.
+  - **footer**  (true or false, default ``True``): If this is true, the
+    `footer` block is inserted in the epub output, otherwise it is omitted.
+
+- **bizstyle** -- A simple bluish theme. The following options are supported
+  beyond *nosidebar* and *sidebarwidth*:
+
+  - **rightsidebar** (true or false): Put the sidebar on the right side.
+    Defaults to ``False``.
+
+.. versionadded:: 1.3
+   'bizstyle' theme.
+
 
 Creating themes
 ---------------
@@ -318,4 +333,3 @@
 .. [1] It is not an executable Python file, as opposed to :file:`conf.py`,
        because that would pose an unnecessary security risk if themes are
        shared.
-
diff --git a/doc/translation.png b/doc/translation.png
index aa368b6..347e287 100644
--- a/doc/translation.png
+++ b/doc/translation.png
Binary files differ
diff --git a/doc/tutorial.rst b/doc/tutorial.rst
index cae4c8d..0a12a27 100644
--- a/doc/tutorial.rst
+++ b/doc/tutorial.rst
@@ -10,6 +10,15 @@
 the described task.
 
 
+Install Sphinx
+--------------
+
+Install Sphinx, either from a distribution package or from
+`PyPI <https://pypi.python.org/pypi/Sphinx>`_ with ::
+
+   $ pip install Sphinx
+
+
 Setting up the documentation sources
 ------------------------------------
 
@@ -138,7 +147,7 @@
 Documenting objects
 -------------------
 
-One of Sphinx' main objectives is easy documentation of :dfn:`objects` (in a
+One of Sphinx's main objectives is easy documentation of :dfn:`objects` (in a
 very general sense) in any :dfn:`domain`.  A domain is a collection of object
 types that belong together, complete with markup to create and reference
 descriptions of these objects.
@@ -200,7 +209,7 @@
 your documents.  In that file, which is executed as a Python source file, you
 assign configuration values.  For advanced users: since it is executed by
 Sphinx, you can do non-trivial tasks in it, like extending :data:`sys.path` or
-importing a module to find out the version your are documenting.
+importing a module to find out the version you are documenting.
 
 The config values that you probably want to change are already put into the
 :file:`conf.py` by :program:`sphinx-quickstart` and initially commented out
@@ -300,7 +309,7 @@
 
 .. rubric:: Footnotes
 
-.. [#] This is the usual lay-out.  However, :file:`conf.py` can also live in
+.. [#] This is the usual layout.  However, :file:`conf.py` can also live in
        another directory, the :term:`configuration directory`.  See
        :ref:`invocation`.
 
diff --git a/doc/web/quickstart.rst b/doc/web/quickstart.rst
index 1bcd217..eab1919 100644
--- a/doc/web/quickstart.rst
+++ b/doc/web/quickstart.rst
@@ -45,7 +45,7 @@
                         search='xapian')
 
 You'll only need one of these for each set of documentation you will be working
-with.  You can then call it's :meth:`~.WebSupport.get_document` method to access
+with.  You can then call its :meth:`~.WebSupport.get_document` method to access
 individual documents::
 
    contents = support.get_document('contents')
@@ -56,8 +56,8 @@
 * **sidebar**: The sidebar of the document as HTML
 * **relbar**: A div containing links to related documents
 * **title**: The title of the document
-* **css**: Links to css files used by Sphinx
-* **js**: Javascript containing comment options
+* **css**: Links to CSS files used by Sphinx
+* **js**: JavaScript containing comment options
 
 This dict can then be used as context for templates.  The goal is to be easy to
 integrate with your existing templating system.  An example using `Jinja2
@@ -109,8 +109,8 @@
    support.update_username(old_username, new_username)
 
 *username* should be a unique string which identifies a user, and *moderator*
-should be a boolean representing whether the user has moderation privilieges.
-The default value for *moderator* is *False*.
+should be a boolean representing whether the user has moderation privileges.
+The default value for *moderator* is ``False``.
 
 An example `Flask <http://flask.pocoo.org/>`_ function that checks whether a
 user is logged in and then retrieves a document is::
diff --git a/setup.py b/setup.py
index 9872226..9e000d5 100644
--- a/setup.py
+++ b/setup.py
@@ -41,27 +41,21 @@
 * Setuptools integration
 '''
 
-requires = ['Pygments>=1.2', 'docutils>=0.7']
-
-if sys.version_info[:3] >= (3, 3, 0):
-    requires[1] = 'docutils>=0.10'
-
 if sys.version_info < (2, 6) or (3, 0) <= sys.version_info < (3, 3):
-    requires.append('Jinja2>=2.3,<2.7')
-else:
-    requires.append('Jinja2>=2.3')
-
-if sys.version_info < (2, 5):
-    print('ERROR: Sphinx requires at least Python 2.5 to run.')
+    print('ERROR: Sphinx requires at least Python 2.6 or 3.3 to run.')
     sys.exit(1)
 
-# tell distribute to use 2to3 with our own fixers
-extra = {}
-if sys.version_info >= (3, 0):
-    extra.update(
-        use_2to3=True,
-        use_2to3_fixers=['custom_fixers']
-    )
+requires = [
+    'six>=1.4',
+    'Jinja2>=2.3',
+    'Pygments>=1.2',
+    'docutils>=0.10',
+    'snowballstemmer>=1.1',
+    'babel',
+]
+
+if sys.platform == 'win32':
+    requires.append('colorama')
 
 # Provide a "compile_catalog" command that also creates the translated
 # JavaScript files if Babel is available.
@@ -185,7 +179,7 @@
         'Topic :: Utilities',
     ],
     platforms='any',
-    packages=find_packages(exclude=['custom_fixers', 'test']),
+    packages=find_packages(exclude=['test']),
     include_package_data=True,
     entry_points={
         'console_scripts': [
@@ -200,5 +194,4 @@
     },
     install_requires=requires,
     cmdclass=cmdclass,
-    **extra
 )
diff --git a/sphinx/__init__.py b/sphinx/__init__.py
index 49bbc28..cd8baee 100644
--- a/sphinx/__init__.py
+++ b/sphinx/__init__.py
@@ -15,12 +15,12 @@
 import sys
 from os import path
 
-__version__  = '1.2.3+'
-__released__ = '1.2.3'  # used when Sphinx builds its own docs
+__version__  = '1.3a0'
+__released__ = '1.3a0'  # used when Sphinx builds its own docs
 # version info for better programmatic use
 # possible values for 3rd element: 'alpha', 'beta', 'rc', 'final'
 # 'final' has 0 as the last element
-version_info = (1, 2, 3, 'final', 0)
+version_info = (1, 3, 0, 'alpha', 0)
 
 package_dir = path.abspath(path.dirname(__file__))
 
@@ -49,8 +49,9 @@
 
 def build_main(argv=sys.argv):
     """Sphinx build "main" command-line entry."""
-    if sys.version_info[:3] < (2, 5, 0):
-        sys.stderr.write('Error: Sphinx requires at least Python 2.5 to run.\n')
+    if (sys.version_info[:3] < (2, 6, 0) or
+       (3, 0, 0) <= sys.version_info[:3] < (3, 3, 0)):
+        sys.stderr.write('Error: Sphinx requires at least Python 2.6 to run.\n')
         return 1
     try:
         from sphinx import cmdline
@@ -78,12 +79,12 @@
                 sys.stderr.write(hint)
             return 1
         raise
-    if sys.version_info[:3] >= (3, 3, 0):
-        from sphinx.util.compat import docutils_version
-        if docutils_version < (0, 10):
-            sys.stderr.write('Error: Sphinx requires at least '
-                             'Docutils 0.10 for Python 3.3 and above.\n')
-            return 1
+
+    from sphinx.util.compat import docutils_version
+    if docutils_version < (0, 10):
+        sys.stderr.write('Error: Sphinx requires at least Docutils 0.10 to '
+                         'run.\n')
+        return 1
     return cmdline.main(argv)
 
 
diff --git a/sphinx/__main__.py b/sphinx/__main__.py
new file mode 100644
index 0000000..270bc4e
--- /dev/null
+++ b/sphinx/__main__.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.__main__
+    ~~~~~~~~~~~~~~~
+
+    The Sphinx documentation toolchain.
+
+    :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+import sys
+from sphinx import main
+
+sys.exit(main(sys.argv))
diff --git a/sphinx/addnodes.py b/sphinx/addnodes.py
index 2806a05..55abdb0 100644
--- a/sphinx/addnodes.py
+++ b/sphinx/addnodes.py
@@ -168,6 +168,11 @@
     applied (e.g. smartypants for HTML output).
     """
 
+class literal_strong(nodes.strong):
+    """Node that behaves like `strong`, but further text processors are not
+    applied (e.g. smartypants for HTML output).
+    """
+
 class abbreviation(nodes.Inline, nodes.TextElement):
     """Node for abbreviations with explanations."""
 
diff --git a/sphinx/apidoc.py b/sphinx/apidoc.py
index 755ea5e..f716286 100644
--- a/sphinx/apidoc.py
+++ b/sphinx/apidoc.py
@@ -14,6 +14,8 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
+from __future__ import print_function
+
 import os
 import sys
 import optparse
@@ -53,12 +55,12 @@
     """Write the output file for module/package <name>."""
     fname = path.join(opts.destdir, '%s.%s' % (name, opts.suffix))
     if opts.dryrun:
-        print 'Would create file %s.' % fname
+        print('Would create file %s.' % fname)
         return
     if not opts.force and path.isfile(fname):
-        print 'File %s already exists, skipping.' % fname
+        print('File %s already exists, skipping.' % fname)
     else:
-        print 'Creating file %s.' % fname
+        print('Creating file %s.' % fname)
         f = open(fname, 'w')
         try:
             f.write(text)
@@ -95,6 +97,10 @@
     """Build the text of the file and write the file."""
     text = format_heading(1, '%s package' % makename(master_package, subroot))
 
+    if opts.modulefirst:
+        text += format_directive(subroot, master_package)
+        text += '\n'
+
     # build a list of directories that are szvpackages (contain an INITPY file)
     subs = [sub for sub in subs if path.isfile(path.join(root, sub, INITPY))]
     # if there are some package directories, add a TOC for theses subpackages
@@ -134,8 +140,9 @@
                 text += '\n'
         text += '\n'
 
-    text += format_heading(2, 'Module contents')
-    text += format_directive(subroot, master_package)
+    if not opts.modulefirst:
+        text += format_heading(2, 'Module contents')
+        text += format_directive(subroot, master_package)
 
     write_file(makename(master_package, subroot), text, opts)
 
@@ -287,6 +294,10 @@
                       help='Don\'t create headings for the module/package '
                            'packages (e.g. when the docstrings already contain '
                            'them)')
+    parser.add_option('-M', '--module-first', action='store_true',
+                      dest='modulefirst',
+                      help='Put module documentation before submodule '
+                      'documentation')
     parser.add_option('-s', '--suffix', action='store', dest='suffix',
                       help='file suffix (default: rst)', default='rst')
     parser.add_option('-F', '--full', action='store_true', dest='full',
@@ -307,7 +318,7 @@
     (opts, args) = parser.parse_args(argv[1:])
 
     if opts.show_version:
-        print 'Sphinx (sphinx-apidoc) %s' %  __version__
+        print('Sphinx (sphinx-apidoc) %s' %  __version__)
         return 0
 
     if not args:
@@ -321,7 +332,7 @@
     if opts.suffix.startswith('.'):
         opts.suffix = opts.suffix[1:]
     if not path.isdir(rootpath):
-        print >>sys.stderr, '%s is not a directory.' % rootpath
+        print('%s is not a directory.' % rootpath, file=sys.stderr)
         sys.exit(1)
     if not path.isdir(opts.destdir):
         if not opts.dryrun:
diff --git a/sphinx/application.py b/sphinx/application.py
index 7113b60..fe87040 100644
--- a/sphinx/application.py
+++ b/sphinx/application.py
@@ -10,15 +10,18 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
+from __future__ import print_function
 
 import os
 import sys
 import types
 import posixpath
+import traceback
 from os import path
-from cStringIO import StringIO
 from collections import deque
 
+from six import iteritems, itervalues
+from six.moves import cStringIO
 from docutils import nodes
 from docutils.parsers.rst import convert_directive_function, \
     directives, roles
@@ -38,6 +41,8 @@
 from sphinx.util.osutil import ENOENT
 from sphinx.util.console import bold, lightgray, darkgray
 
+if hasattr(sys, 'intern'):
+    intern = sys.intern
 
 # List of all known core events. Maps name to arguments description.
 events = {
@@ -67,6 +72,7 @@
         self.verbosity = verbosity
         self.next_listener_id = 0
         self._extensions = {}
+        self._extension_versions = {}
         self._listeners = {}
         self.domains = BUILTIN_DOMAINS.copy()
         self.builderclasses = BUILTIN_BUILDERS.copy()
@@ -81,20 +87,21 @@
         self.parallel = parallel
 
         if status is None:
-            self._status = StringIO()
+            self._status = cStringIO()
             self.quiet = True
         else:
             self._status = status
             self.quiet = False
 
         if warning is None:
-            self._warning = StringIO()
+            self._warning = cStringIO()
         else:
             self._warning = warning
         self._warncount = 0
         self.warningiserror = warningiserror
 
         self._events = events.copy()
+        self._translators = {}
 
         # keep last few messages for traceback
         self.messagelog = deque(maxlen=10)
@@ -116,8 +123,6 @@
         if self.confdir is None:
             self.confdir = self.srcdir
 
-        # backwards compatibility: activate old C markup
-        self.setup_extension('sphinx.ext.oldcmarkup')
         # load all user-given extension modules
         for extension in self.config.extensions:
             self.setup_extension(extension)
@@ -134,7 +139,7 @@
                 )
 
         # now that we know all config values, collect them from conf.py
-        self.config.init_values()
+        self.config.init_values(self.warn)
 
         # check the Sphinx version if requested
         if self.config.needs_sphinx and \
@@ -143,6 +148,21 @@
                 'This project needs at least Sphinx v%s and therefore cannot '
                 'be built with this version.' % self.config.needs_sphinx)
 
+        # check extension versions if requested
+        if self.config.needs_extensions:
+            for extname, needs_ver in self.config.needs_extensions.items():
+                if extname not in self._extensions:
+                    self.warn('needs_extensions config value specifies a '
+                              'version requirement for extension %s, but it is '
+                              'not loaded' % extname)
+                    continue
+                has_ver = self._extension_versions[extname]
+                if has_ver == 'unknown version' or needs_ver > has_ver:
+                    raise VersionRequirementError(
+                        'This project needs the extension %s at least in '
+                        'version %s and therefore cannot be built with the '
+                        'loaded version (%s).' % (extname, needs_ver, has_ver))
+
         # set up translation infrastructure
         self._init_i18n()
         # set up the build environment
@@ -187,7 +207,7 @@
                     # this can raise if the data version doesn't fit
                     self.env.domains[domain] = self.domains[domain](self.env)
                 self.info('done')
-            except Exception, err:
+            except Exception as err:
                 if type(err) is IOError and err.errno == ENOENT:
                     self.info('not yet created')
                 else:
@@ -198,7 +218,7 @@
 
     def _init_builder(self, buildername):
         if buildername is None:
-            print >>self._status, 'No builder selected, using default: html'
+            print('No builder selected, using default: html', file=self._status)
             buildername = 'html'
         if buildername not in self.builderclasses:
             raise SphinxError('Builder name %s not registered' % buildername)
@@ -217,12 +237,15 @@
     def build(self, force_all=False, filenames=None):
         try:
             if force_all:
+                self.builder.compile_all_catalogs()
                 self.builder.build_all()
             elif filenames:
+                self.builder.compile_specific_catalogs(filenames)
                 self.builder.build_specific(filenames)
             else:
+                self.builder.compile_update_catalogs()
                 self.builder.build_update()
-        except Exception, err:
+        except Exception as err:
             # delete the saved env to force a fresh build next time
             envfile = path.join(self.doctreedir, ENV_PICKLE_FILENAME)
             if path.isfile(envfile):
@@ -336,22 +359,27 @@
             return
         try:
             mod = __import__(extension, None, None, ['setup'])
-        except ImportError, err:
+        except ImportError as err:
+            self.verbose('Original exception:\n' + traceback.format_exc())
             raise ExtensionError('Could not import extension %s' % extension,
                                  err)
         if not hasattr(mod, 'setup'):
             self.warn('extension %r has no setup() function; is it really '
                       'a Sphinx extension module?' % extension)
+            version = None
         else:
             try:
-                mod.setup(self)
-            except VersionRequirementError, err:
+                version = mod.setup(self)
+            except VersionRequirementError as err:
                 # add the extension name to the version required
                 raise VersionRequirementError(
                     'The %s extension used by this project needs at least '
                     'Sphinx v%s; it therefore cannot be built with this '
                     'version.' % (extension, err))
+        if version is None:
+            version = 'unknown version'
         self._extensions[extension] = mod
+        self._extension_versions[extension] = version
 
     def require_sphinx(self, version):
         # check the Sphinx version if requested
@@ -362,17 +390,17 @@
         """Import an object from a 'module.name' string."""
         try:
             module, name = objname.rsplit('.', 1)
-        except ValueError, err:
+        except ValueError as err:
             raise ExtensionError('Invalid full object name %s' % objname +
                                  (source and ' (needed for %s)' % source or ''),
                                  err)
         try:
             return getattr(__import__(module, None, None, [name]), name)
-        except ImportError, err:
+        except ImportError as err:
             raise ExtensionError('Could not import %s' % module +
                                  (source and ' (needed for %s)' % source or ''),
                                  err)
-        except AttributeError, err:
+        except AttributeError as err:
             raise ExtensionError('Could not find %s' % objname +
                                  (source and ' (needed for %s)' % source or ''),
                                  err)
@@ -398,7 +426,7 @@
 
     def disconnect(self, listener_id):
         self.debug('[app] disconnecting event: [id=%s]', listener_id)
-        for event in self._listeners.itervalues():
+        for event in itervalues(self._listeners):
             event.pop(listener_id, None)
 
     def emit(self, event, *args):
@@ -409,7 +437,7 @@
             pass
         results = []
         if event in self._listeners:
-            for _, callback in self._listeners[event].iteritems():
+            for _, callback in iteritems(self._listeners[event]):
                 results.append(callback(self, *args))
         return results
 
@@ -450,16 +478,23 @@
             raise ExtensionError('Event %r already present' % name)
         self._events[name] = ''
 
+    def set_translator(self, name, translator_class):
+        self.info(bold('A Translator for the %s builder is changed.' % name))
+        self._translators[name] = translator_class
+
     def add_node(self, node, **kwds):
         self.debug('[app] adding node: %r', (node, kwds))
         nodes._add_node_class_names([node.__name__])
-        for key, val in kwds.iteritems():
+        for key, val in iteritems(kwds):
             try:
                 visit, depart = val
             except ValueError:
                 raise ExtensionError('Value for key %r must be a '
                                      '(visit, depart) function tuple' % key)
-            if key == 'html':
+            translator = self._translators.get(key)
+            if translator is not None:
+                pass
+            elif key == 'html':
                 from sphinx.writers.html import HTMLTranslator as translator
             elif key == 'latex':
                 from sphinx.writers.latex import LaTeXTranslator as translator
diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py
index c02ecb5..833269c 100644
--- a/sphinx/builders/__init__.py
+++ b/sphinx/builders/__init__.py
@@ -20,7 +20,8 @@
 
 from docutils import nodes
 
-from sphinx.util.osutil import SEP, relative_uri
+from sphinx.util import i18n, path_stabilize
+from sphinx.util.osutil import SEP, relative_uri, find_catalog
 from sphinx.util.console import bold, purple, darkgreen, term_width_line
 
 # side effect: registers roles and directives
@@ -65,6 +66,9 @@
         # images that need to be copied over (source -> dest)
         self.images = {}
 
+        # load default translator class
+        self.translator_class = app._translators.get(self.name)
+
         self.init()
 
     # helper methods
@@ -170,6 +174,46 @@
                 continue
             self.images[candidate] = self.env.images[candidate][1]
 
+    # compile po methods
+
+    def compile_catalogs(self, catalogs, message):
+        if not self.config.gettext_auto_build:
+            return
+        self.info(bold('building [mo]: '), nonl=1)
+        self.info(message)
+        for catalog in self.status_iterator(
+                catalogs, 'writing output... ', darkgreen, len(catalogs),
+                lambda c: c.mo_path):
+            catalog.write_mo(self.config.language)
+
+    def compile_all_catalogs(self):
+        catalogs = i18n.get_catalogs(
+            [path.join(self.srcdir, x) for x in self.config.locale_dirs],
+            self.config.language, True)
+        message = 'all of %d po files' % len(catalogs)
+        self.compile_catalogs(catalogs, message)
+
+    def compile_specific_catalogs(self, specified_files):
+        def to_domain(fpath):
+            docname, _ = path.splitext(path_stabilize(fpath))
+            dom = find_catalog(docname, self.config.gettext_compact)
+            return dom
+
+        specified_domains = set(map(to_domain, specified_files))
+        catalogs = i18n.get_catalogs(
+            [path.join(self.srcdir, x) for x in self.config.locale_dirs],
+            self.config.language, True)
+        catalogs = [f for f in catalogs if f.domain in specified_domains]
+        message = 'targets for %d po files that are specified' % len(catalogs)
+        self.compile_catalogs(catalogs, message)
+
+    def compile_update_catalogs(self):
+        catalogs = i18n.get_catalogs(
+            [path.join(self.srcdir, x) for x in self.config.locale_dirs],
+            self.config.language)
+        message = 'targets for %d po files that are out of date' % len(catalogs)
+        self.compile_catalogs(catalogs, message)
+
     # build methods
 
     def build_all(self):
diff --git a/sphinx/builders/changes.py b/sphinx/builders/changes.py
index c9317af..aa947c9 100644
--- a/sphinx/builders/changes.py
+++ b/sphinx/builders/changes.py
@@ -12,6 +12,8 @@
 import codecs
 from os import path
 
+from six import iteritems
+
 from sphinx import package_dir
 from sphinx.util import copy_static_entry
 from sphinx.locale import _
@@ -93,9 +95,9 @@
             'version': version,
             'docstitle': self.config.html_title,
             'shorttitle': self.config.html_short_title,
-            'libchanges': sorted(libchanges.iteritems()),
+            'libchanges': sorted(iteritems(libchanges)),
             'apichanges': sorted(apichanges),
-            'otherchanges': sorted(otherchanges.iteritems()),
+            'otherchanges': sorted(iteritems(otherchanges)),
             'show_copyright': self.config.html_show_copyright,
             'show_sphinx': self.config.html_show_sphinx,
         }
@@ -143,7 +145,7 @@
             finally:
                 f.close()
         themectx = dict(('theme_' + key, val) for (key, val) in
-                        self.theme.get_options({}).iteritems())
+                        iteritems(self.theme.get_options({})))
         copy_static_entry(path.join(package_dir, 'themes', 'default',
                                     'static', 'default.css_t'),
                           self.outdir, self, themectx)
diff --git a/sphinx/builders/devhelp.py b/sphinx/builders/devhelp.py
index 61482fd..afe4b40 100644
--- a/sphinx/builders/devhelp.py
+++ b/sphinx/builders/devhelp.py
@@ -94,7 +94,7 @@
 
         def istoctree(node):
             return isinstance(node, addnodes.compact_paragraph) and \
-                   node.has_key('toctree')
+                   'toctree' in node
 
         for node in tocdoc.traverse(istoctree):
             write_toc(node, chapters)
diff --git a/sphinx/builders/epub.py b/sphinx/builders/epub.py
index a73679c..95a0ef0 100644
--- a/sphinx/builders/epub.py
+++ b/sphinx/builders/epub.py
@@ -12,7 +12,6 @@
 
 import os
 import re
-import sys
 import time
 import codecs
 import zipfile
@@ -219,7 +218,7 @@
         """Collect section titles, their depth in the toc and the refuri."""
         # XXX: is there a better way than checking the attribute
         # toctree-l[1-8] on the parent node?
-        if isinstance(doctree, nodes.reference) and doctree.has_key('refuri'):
+        if isinstance(doctree, nodes.reference) and 'refuri' in doctree:
             refuri = doctree['refuri']
             if refuri.startswith('http://') or refuri.startswith('https://') \
                 or refuri.startswith('irc:') or refuri.startswith('mailto:'):
@@ -418,7 +417,7 @@
                 try:
                     copyfile(path.join(self.srcdir, src),
                              path.join(self.outdir, '_images', dest))
-                except (IOError, OSError), err:
+                except (IOError, OSError) as err:
                     self.warn('cannot copy image file %r: %s' %
                               (path.join(self.srcdir, src), err))
                 continue
@@ -434,7 +433,7 @@
                     img = img.resize((nw, nh), Image.BICUBIC)
             try:
                 img.save(path.join(self.outdir, '_images', dest))
-            except (IOError, OSError), err:
+            except (IOError, OSError) as err:
                 self.warn('cannot write image file %r: %s' %
                           (path.join(self.srcdir, src), err))
 
@@ -490,7 +489,7 @@
         fn = path.join(outdir, outname)
         try:
             os.mkdir(path.dirname(fn))
-        except OSError, err:
+        except OSError as err:
             if err.errno != EEXIST:
                 raise
         f = codecs.open(path.join(outdir, outname), 'w', 'utf-8')
@@ -750,12 +749,5 @@
             zipfile.ZIP_STORED)
         for file in projectfiles:
             fp = path.join(outdir, file)
-            if sys.version_info < (2, 6):
-                # When zipile.ZipFile.write call with unicode filename, ZipFile
-                # encode filename to 'utf-8' (only after Python-2.6).
-                if isinstance(file, unicode):
-                    # OEBPS Container Format (OCF) 2.0.1 specification require
-                    # "File Names MUST be UTF-8 encoded".
-                    file = file.encode('utf-8')
             epub.write(fp, file, zipfile.ZIP_DEFLATED)
         epub.close()
diff --git a/sphinx/builders/gettext.py b/sphinx/builders/gettext.py
index 250bef8..657ce92 100644
--- a/sphinx/builders/gettext.py
+++ b/sphinx/builders/gettext.py
@@ -10,6 +10,7 @@
 """
 
 from __future__ import with_statement
+from __future__ import unicode_literals
 
 from os import path, walk
 from codecs import open
@@ -18,6 +19,8 @@
 from collections import defaultdict
 from uuid import uuid4
 
+from six import iteritems
+
 from sphinx.builders import Builder
 from sphinx.util import split_index_msg
 from sphinx.util.nodes import extract_messages, traverse_translatable_index
@@ -25,7 +28,7 @@
 from sphinx.util.console import darkgreen, purple, bold
 from sphinx.locale import pairindextypes
 
-POHEADER = ur"""
+POHEADER = r"""
 # SOME DESCRIPTIVE TITLE.
 # Copyright (C) %(copyright)s
 # This file is distributed under the same license as the %(project)s package.
@@ -96,6 +99,9 @@
     def prepare_writing(self, docnames):
         return
 
+    def compile_catalogs(self, catalogs, message):
+        return
+
     def write_doc(self, docname, doctree):
         catalog = self.catalogs[find_catalog(docname,
                                              self.config.gettext_compact)]
@@ -186,9 +192,9 @@
                 timestamp, ltz).strftime('%Y-%m-%d %H:%M%z'),
         )
         for textdomain, catalog in self.status_iterator(
-                self.catalogs.iteritems(), "writing message catalogs... ",
+                iteritems(self.catalogs), "writing message catalogs... ",
                 darkgreen, len(self.catalogs),
-                lambda (textdomain, _): textdomain):
+                lambda textdomain__: textdomain__[0]):
             # noop if config.gettext_compact is set
             ensuredir(path.join(self.outdir, path.dirname(textdomain)))
 
@@ -200,19 +206,21 @@
                 for message in catalog.messages:
                     positions = catalog.metadata[message]
 
-                    # generate "#: file1:line1\n#: file2:line2 ..."
-                    pofile.write(u"#: %s\n" % "\n#: ".join("%s:%s" %
-                        (safe_relpath(source, self.outdir), line)
-                        for source, line, _ in positions))
-                    # generate "# uuid1\n# uuid2\n ..."
-                    pofile.write(u"# %s\n" % "\n# ".join(uid for _, _, uid
-                        in positions))
+                    if self.config.gettext_location:
+                        # generate "#: file1:line1\n#: file2:line2 ..."
+                        pofile.write("#: %s\n" % "\n#: ".join("%s:%s" %
+                            (safe_relpath(source, self.outdir), line)
+                            for source, line, _ in positions))
+                    if self.config.gettext_uuid:
+                        # generate "# uuid1\n# uuid2\n ..."
+                        pofile.write("# %s\n" % "\n# ".join(
+                            uid for _, _, uid in positions))
 
                     # message contains *one* line of text ready for translation
-                    message = message.replace(u'\\', ur'\\'). \
-                                      replace(u'"', ur'\"'). \
-                                      replace(u'\n', u'\\n"\n"')
-                    pofile.write(u'msgid "%s"\nmsgstr ""\n\n' % message)
+                    message = message.replace('\\', r'\\'). \
+                                      replace('"', r'\"'). \
+                                      replace('\n', '\\n"\n"')
+                    pofile.write('msgid "%s"\nmsgstr ""\n\n' % message)
 
             finally:
                 pofile.close()
diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py
index 9c039e3..ec3a818 100644
--- a/sphinx/builders/html.py
+++ b/sphinx/builders/html.py
@@ -14,14 +14,11 @@
 import zlib
 import codecs
 import posixpath
-import cPickle as pickle
 from os import path
-try:
-    from hashlib import md5
-except ImportError:
-    # 2.4 compatibility
-    from md5 import md5
+from hashlib import md5
 
+from six import iteritems, itervalues, text_type, string_types
+from six.moves import cPickle as pickle
 from docutils import nodes
 from docutils.io import DocTreeInput, StringOutput
 from docutils.core import Publisher
@@ -35,8 +32,6 @@
      movefile, ustrftime, copyfile
 from sphinx.util.nodes import inline_all_toctrees
 from sphinx.util.matching import patmatch, compile_matchers
-from sphinx.util.pycompat import any, b
-from sphinx.errors import SphinxError
 from sphinx.locale import _
 from sphinx.search import js_index
 from sphinx.theming import Theme
@@ -63,7 +58,7 @@
         return get_stable_hash(list(obj.items()))
     elif isinstance(obj, (list, tuple)):
         obj = sorted(get_stable_hash(o) for o in obj)
-    return md5(unicode(obj).encode('utf8')).hexdigest()
+    return md5(text_type(obj).encode('utf8')).hexdigest()
 
 
 class StandaloneHTMLBuilder(Builder):
@@ -157,7 +152,9 @@
                                           self.config.trim_doctest_flags)
 
     def init_translator_class(self):
-        if self.config.html_translator_class:
+        if self.translator_class is not None:
+            pass
+        elif self.config.html_translator_class:
             self.translator_class = self.app.import_object(
                 self.config.html_translator_class,
                 'html_translator_class setting')
@@ -168,7 +165,7 @@
 
     def get_outdated_docs(self):
         cfgdict = dict((name, self.config[name])
-                       for (name, desc) in self.config.values.iteritems()
+                       for (name, desc) in iteritems(self.config.values)
                        if desc[1] == 'html')
         self.config_hash = get_stable_hash(cfgdict)
         self.tags_hash = get_stable_hash(sorted(self.tags))
@@ -225,7 +222,7 @@
         """Utility: Render a lone doctree node."""
         if node is None:
             return {'fragment': ''}
-        doc = new_document(b('<partial node>'))
+        doc = new_document(b'<partial node>')
         doc.append(node)
 
         if self._publisher is None:
@@ -269,7 +266,7 @@
         # html_domain_indices can be False/True or a list of index names
         indices_config = self.config.html_domain_indices
         if indices_config:
-            for domain in self.env.domains.itervalues():
+            for domain in itervalues(self.env.domains):
                 for indexcls in domain.indices:
                     indexname = '%s-%s' % (domain.name, indexcls.name)
                     if isinstance(indices_config, list):
@@ -300,7 +297,7 @@
         if favicon and os.path.splitext(favicon)[1] != '.ico':
             self.warn('html_favicon is not an .ico file')
 
-        if not isinstance(self.config.html_use_opensearch, basestring):
+        if not isinstance(self.config.html_use_opensearch, string_types):
             self.warn('html_use_opensearch config value must now be a string')
 
         self.relations = self.env.collect_relations()
@@ -350,7 +347,7 @@
         if self.theme:
             self.globalcontext.update(
                 ('theme_' + key, val) for (key, val) in
-                self.theme.get_options(self.theme_options).iteritems())
+                iteritems(self.theme.get_options(self.theme_options)))
         self.globalcontext.update(self.config.html_context)
 
     def get_doc_context(self, docname, body, metatags):
@@ -535,7 +532,7 @@
                 try:
                     copyfile(path.join(self.srcdir, src),
                              path.join(self.outdir, '_images', dest))
-                except Exception, err:
+                except Exception as err:
                     self.warn('cannot copy image file %r: %s' %
                               (path.join(self.srcdir, src), err))
 
@@ -550,7 +547,7 @@
                 try:
                     copyfile(path.join(self.srcdir, src),
                              path.join(self.outdir, '_downloads', dest))
-                except Exception, err:
+                except Exception as err:
                     self.warn('cannot copy downloadable file %r: %s' %
                               (path.join(self.srcdir, src), err))
 
@@ -583,10 +580,7 @@
         # then, copy over all user-supplied static files
         staticentries = [path.join(self.confdir, spath)
                          for spath in self.config.html_static_path]
-        matchers = compile_matchers(
-            self.config.exclude_patterns +
-            ['**/' + d for d in self.config.exclude_dirnames]
-        )
+        matchers = compile_matchers(self.config.exclude_patterns)
         for entry in staticentries:
             if not path.exists(entry):
                 self.warn('html_static_path entry %r does not exist' % entry)
@@ -704,7 +698,7 @@
         sidebars = None
         matched = None
         customsidebar = None
-        for pattern, patsidebars in self.config.html_sidebars.iteritems():
+        for pattern, patsidebars in iteritems(self.config.html_sidebars):
             if patmatch(pagename, pattern):
                 if matched:
                     if has_wildcard(pattern):
@@ -721,7 +715,7 @@
         if sidebars is None:
             # keep defaults
             pass
-        elif isinstance(sidebars, basestring):
+        elif isinstance(sidebars, string_types):
             # 0.x compatible mode: insert custom sidebar before searchbox
             customsidebar = sidebars
             sidebars = None
@@ -782,7 +776,7 @@
                 f.write(output)
             finally:
                 f.close()
-        except (IOError, OSError), err:
+        except (IOError, OSError) as err:
             self.warn("error writing file %s: %s" % (outfilename, err))
         if self.copysource and ctx.get('sourcename'):
             # copy the source file for the "show source" link
@@ -806,7 +800,7 @@
                      % (self.config.project, self.config.version)
                     ).encode('utf-8'))
             compressor = zlib.compressobj(9)
-            for domainname, domain in self.env.domains.iteritems():
+            for domainname, domain in iteritems(self.env.domains):
                 for name, dispname, type, docname, anchor, prio in \
                         domain.get_objects():
                     if anchor.endswith(name):
@@ -825,7 +819,9 @@
         self.info('done')
 
     def dump_search_index(self):
-        self.info(bold('dumping search index... '), nonl=True)
+        self.info(
+            bold('dumping search index in %s ... ' % self.indexer.label()),
+            nonl=True)
         self.indexer.prune(self.env.all_docs)
         searchindexfn = path.join(self.outdir, self.searchindex_filename)
         # first write to a temporary file, so that if dumping fails,
@@ -919,6 +915,23 @@
         self.fix_refuris(tree)
         return tree
 
+    def assemble_toc_secnumbers(self):
+        # Assemble toc_secnumbers to resolve section numbers on SingleHTML.
+        # Merge all secnumbers to single secnumber.
+        #
+        # Note: current Sphinx has refid confliction in singlehtml mode.
+        #       To avoid the problem, it replaces key of secnumbers to
+        #       tuple of docname and refid.
+        #
+        #       There are related codes in inline_all_toctres() and
+        #       HTMLTranslter#add_secnumber().
+        new_secnumbers = {}
+        for docname, secnums in iteritems(self.env.toc_secnumbers):
+            for id, secnum in iteritems(secnums):
+                new_secnumbers[(docname, id)] = secnum
+
+        return {self.config.master_doc: new_secnumbers}
+
     def get_doc_context(self, docname, body, metatags):
         # no relation links...
         toc = self.env.get_toctree_for(self.config.master_doc, self, False)
@@ -954,6 +967,7 @@
 
         self.info(bold('assembling single document... '), nonl=True)
         doctree = self.assemble_doctree()
+        self.env.toc_secnumbers = self.assemble_toc_secnumbers()
         self.info()
         self.info(bold('writing... '), nonl=True)
         self.write_doc_serialized(self.config.master_doc, doctree)
@@ -1100,8 +1114,4 @@
     searchindex_filename = 'searchindex.json'
 
     def init(self):
-        if jsonimpl.json is None:
-            raise SphinxError(
-                'The module simplejson (or json in Python >= 2.6) '
-                'is not available. The JSONHTMLBuilder builder will not work.')
         SerializingHTMLBuilder.init(self)
diff --git a/sphinx/builders/htmlhelp.py b/sphinx/builders/htmlhelp.py
index 77fcd43..400fbdc 100644
--- a/sphinx/builders/htmlhelp.py
+++ b/sphinx/builders/htmlhelp.py
@@ -9,6 +9,7 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
+from __future__ import print_function
 
 import os
 import codecs
@@ -197,7 +198,7 @@
         f = self.open_file(outdir, outname+'.stp')
         try:
             for word in sorted(stopwords):
-                print >>f, word
+                print(word, file=f)
         finally:
             f.close()
 
@@ -217,8 +218,8 @@
                 for fn in files:
                     if (staticdir and not fn.endswith('.js')) or \
                            fn.endswith('.html'):
-                        print >>f, path.join(root, fn)[olen:].replace(os.sep,
-                                                                      '\\')
+                        print(path.join(root, fn)[olen:].replace(os.sep, '\\'),
+                              file=f)
         finally:
             f.close()
 
@@ -256,7 +257,7 @@
                         write_toc(subnode, ullevel)
             def istoctree(node):
                 return isinstance(node, addnodes.compact_paragraph) and \
-                       node.has_key('toctree')
+                       'toctree' in node
             for node in tocdoc.traverse(istoctree):
                 write_toc(node)
             f.write(contents_footer)
diff --git a/sphinx/builders/latex.py b/sphinx/builders/latex.py
index f545330..bf7991c 100644
--- a/sphinx/builders/latex.py
+++ b/sphinx/builders/latex.py
@@ -12,6 +12,7 @@
 import os
 from os import path
 
+from six import iteritems
 from docutils import nodes
 from docutils.io import FileOutput
 from docutils.utils import new_document
@@ -56,7 +57,7 @@
         return self.get_target_uri(to, typ)
 
     def init_document_data(self):
-        preliminary_document_data = map(list, self.config.latex_documents)
+        preliminary_document_data = [list(x) for x in self.config.latex_documents]
         if not preliminary_document_data:
             self.warn('no "latex_documents" config value found; no documents '
                       'will be written')
@@ -152,7 +153,7 @@
         # copy image files
         if self.images:
             self.info(bold('copying images...'), nonl=1)
-            for src, dest in self.images.iteritems():
+            for src, dest in iteritems(self.images):
                 self.info(' '+src, nonl=1)
                 copyfile(path.join(self.srcdir, src),
                          path.join(self.outdir, dest))
diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py
index f0cb3c9..bf50e64 100644
--- a/sphinx/builders/linkcheck.py
+++ b/sphinx/builders/linkcheck.py
@@ -10,15 +10,15 @@
 """
 
 import re
-import sys
-import Queue
 import socket
 import threading
 from os import path
-from urllib2 import build_opener, unquote, Request, \
-    HTTPError, HTTPRedirectHandler
-from HTMLParser import HTMLParser, HTMLParseError
 
+from six.moves import queue
+from six.moves.urllib.request import build_opener, Request, HTTPRedirectHandler
+from six.moves.urllib.parse import unquote
+from six.moves.urllib.error import HTTPError
+from six.moves.html_parser import HTMLParser, HTMLParseError
 from docutils import nodes
 
 from sphinx.builders import Builder
@@ -90,7 +90,7 @@
     name = 'linkcheck'
 
     def init(self):
-        self.to_ignore = map(re.compile, self.app.config.linkcheck_ignore)
+        self.to_ignore = [re.compile(x) for x in self.app.config.linkcheck_ignore]
         self.good = set()
         self.broken = {}
         self.redirected = {}
@@ -100,8 +100,8 @@
         open(path.join(self.outdir, 'output.txt'), 'w').close()
 
         # create queues and worker threads
-        self.wqueue = Queue.Queue()
-        self.rqueue = Queue.Queue()
+        self.wqueue = queue.Queue()
+        self.rqueue = queue.Queue()
         self.workers = []
         for i in range(self.app.config.linkcheck_workers):
             thread = threading.Thread(target=self.check_thread)
@@ -111,7 +111,7 @@
 
     def check_thread(self):
         kwargs = {}
-        if sys.version_info > (2, 5) and self.app.config.linkcheck_timeout:
+        if self.app.config.linkcheck_timeout:
             kwargs['timeout'] = self.app.config.linkcheck_timeout
 
         def check():
@@ -158,7 +158,7 @@
                         req = HeadRequest(req_url)
                         f = opener.open(req, **kwargs)
                         f.close()
-                    except HTTPError, err:
+                    except HTTPError as err:
                         if err.code != 405:
                             raise
                         # retry with GET if that fails, some servers
@@ -167,7 +167,7 @@
                         f = opener.open(req, **kwargs)
                         f.close()
 
-            except Exception, err:
+            except Exception as err:
                 self.broken[uri] = str(err)
                 return 'broken', str(err), 0
             if f.url.rstrip('/') == req_url.rstrip('/'):
diff --git a/sphinx/builders/manpage.py b/sphinx/builders/manpage.py
index 4de82a7..dfbf898 100644
--- a/sphinx/builders/manpage.py
+++ b/sphinx/builders/manpage.py
@@ -11,16 +11,16 @@
 
 from os import path
 
+from six import string_types
 from docutils.io import FileOutput
 from docutils.frontend import OptionParser
 
 from sphinx import addnodes
-from sphinx.errors import SphinxError
 from sphinx.builders import Builder
 from sphinx.environment import NoUri
 from sphinx.util.nodes import inline_all_toctrees
 from sphinx.util.console import bold, darkgreen
-from sphinx.writers.manpage import ManualPageWriter, has_manpage_writer
+from sphinx.writers.manpage import ManualPageWriter
 
 
 class ManualPageBuilder(Builder):
@@ -32,9 +32,6 @@
     supported_image_types = []
 
     def init(self):
-        if not has_manpage_writer:
-            raise SphinxError('The docutils manual page writer can\'t be '
-                              'found; it is only available as of docutils 0.6.')
         if not self.config.man_pages:
             self.warn('no "man_pages" config value found; no manual pages '
                       'will be written')
@@ -58,7 +55,7 @@
 
         for info in self.config.man_pages:
             docname, name, description, authors, section = info
-            if isinstance(authors, basestring):
+            if isinstance(authors, string_types):
                 if authors:
                     authors = [authors]
                 else:
diff --git a/sphinx/builders/qthelp.py b/sphinx/builders/qthelp.py
index 1d46284..c0fff2a 100644
--- a/sphinx/builders/qthelp.py
+++ b/sphinx/builders/qthelp.py
@@ -15,6 +15,7 @@
 import posixpath
 from os import path
 
+from six import text_type
 from docutils import nodes
 
 from sphinx import addnodes
@@ -123,7 +124,7 @@
                                                   prune_toctrees=False)
         istoctree = lambda node: (
                         isinstance(node, addnodes.compact_paragraph)
-                            and node.has_key('toctree'))
+                            and 'toctree' in node)
         sections = []
         for node in tocdoc.traverse(istoctree):
             sections.extend(self.write_toc(node))
@@ -136,7 +137,7 @@
         # they are all unicode strings before joining them
         new_sections = []
         for section in sections:
-            if not isinstance(section, unicode):
+            if not isinstance(section, text_type):
                 new_sections.append(force_decode(section, None))
             else:
                 new_sections.append(section)
diff --git a/sphinx/builders/texinfo.py b/sphinx/builders/texinfo.py
index 39499e6..53463f3 100644
--- a/sphinx/builders/texinfo.py
+++ b/sphinx/builders/texinfo.py
@@ -11,6 +11,7 @@
 
 from os import path
 
+from six import iteritems
 from docutils import nodes
 from docutils.io import FileOutput
 from docutils.utils import new_document
@@ -107,7 +108,7 @@
         return self.get_target_uri(to, typ)
 
     def init_document_data(self):
-        preliminary_document_data = map(list, self.config.texinfo_documents)
+        preliminary_document_data = [list(x) for x in self.config.texinfo_documents]
         if not preliminary_document_data:
             self.warn('no "texinfo_documents" config value found; no documents '
                       'will be written')
@@ -207,7 +208,7 @@
         # copy image files
         if self.images:
             self.info(bold('copying images...'), nonl=1)
-            for src, dest in self.images.iteritems():
+            for src, dest in iteritems(self.images):
                 self.info(' '+src, nonl=1)
                 copyfile(path.join(self.srcdir, src),
                          path.join(self.outdir, dest))
@@ -223,6 +224,6 @@
                 mkfile.write(TEXINFO_MAKEFILE)
             finally:
                 mkfile.close()
-        except (IOError, OSError), err:
+        except (IOError, OSError) as err:
             self.warn("error writing file %s: %s" % (fn, err))
         self.info(' done')
diff --git a/sphinx/builders/text.py b/sphinx/builders/text.py
index 0aeeb5f..46b4d72 100644
--- a/sphinx/builders/text.py
+++ b/sphinx/builders/text.py
@@ -65,7 +65,7 @@
                 f.write(self.writer.output)
             finally:
                 f.close()
-        except (IOError, OSError), err:
+        except (IOError, OSError) as err:
             self.warn("error writing file %s: %s" % (outfilename, err))
 
     def finish(self):
diff --git a/sphinx/builders/websupport.py b/sphinx/builders/websupport.py
index 6cf9810..7b0e6f7 100644
--- a/sphinx/builders/websupport.py
+++ b/sphinx/builders/websupport.py
@@ -46,7 +46,8 @@
         self.storage = storage
 
     def init_translator_class(self):
-        self.translator_class = WebSupportTranslator
+        if self.translator_class is None:
+            self.translator_class = WebSupportTranslator
 
     def prepare_writing(self, docnames):
         PickleHTMLBuilder.prepare_writing(self, docnames)
diff --git a/sphinx/builders/xml.py b/sphinx/builders/xml.py
index 9a9aec9..b0fcd2f 100644
--- a/sphinx/builders/xml.py
+++ b/sphinx/builders/xml.py
@@ -81,7 +81,7 @@
                 f.write(self.writer.output)
             finally:
                 f.close()
-        except (IOError, OSError), err:
+        except (IOError, OSError) as err:
             self.warn("error writing file %s: %s" % (outfilename, err))
 
     def finish(self):
diff --git a/sphinx/cmdline.py b/sphinx/cmdline.py
index ec24d90..6e7ab32 100644
--- a/sphinx/cmdline.py
+++ b/sphinx/cmdline.py
@@ -8,6 +8,7 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
+from __future__ import print_function
 
 import os
 import sys
@@ -15,6 +16,7 @@
 import traceback
 from os import path
 
+from six import text_type, binary_type
 from docutils.utils import SystemMessage
 
 from sphinx import __version__
@@ -23,14 +25,14 @@
 from sphinx.util import Tee, format_exception_cut_frames, save_traceback
 from sphinx.util.console import red, nocolor, color_terminal
 from sphinx.util.osutil import abspath, fs_encoding
-from sphinx.util.pycompat import terminal_safe, bytes
+from sphinx.util.pycompat import terminal_safe
 
 
 def usage(argv, msg=None):
     if msg:
-        print >>sys.stderr, msg
-        print >>sys.stderr
-    print >>sys.stderr, """\
+        print(msg, file=sys.stderr)
+        print(file=sys.stderr)
+    print("""\
 Sphinx v%s
 Usage: %s [options] sourcedir outdir [filenames...]
 
@@ -75,19 +77,18 @@
 ^^^^^^^^^^^^^^^^
 -h, --help  show this help and exit
 --version   show version information and exit
-""" % (__version__, argv[0])
+""" % (__version__, argv[0]), file=sys.stderr)
 
 
 def main(argv):
     if not color_terminal():
-        # Windows' poor cmd box doesn't understand ANSI sequences
         nocolor()
 
     # parse options
     try:
         opts, args = getopt.getopt(argv[1:], 'ab:t:d:c:CD:A:nNEqQWw:PThvj:',
                                    ['help', 'version'])
-    except getopt.error, err:
+    except getopt.error as err:
         usage(argv, 'Error: %s' % err)
         return 1
 
@@ -96,33 +97,34 @@
     # help and version options
     if '-h' in allopts or '--help' in allopts:
         usage(argv)
-        print >>sys.stderr
-        print >>sys.stderr, 'For more information, see <http://sphinx-doc.org/>.'
+        print(file=sys.stderr)
+        print('For more information, see <http://sphinx-doc.org/>.',
+              file=sys.stderr)
         return 0
     if '--version' in allopts:
-        print 'Sphinx (sphinx-build) %s' %  __version__
+        print('Sphinx (sphinx-build) %s' %  __version__)
         return 0
 
     # get paths (first and second positional argument)
     try:
         srcdir = confdir = abspath(args[0])
         if not path.isdir(srcdir):
-            print >>sys.stderr, 'Error: Cannot find source directory `%s\'.' % (
-                                srcdir,)
+            print('Error: Cannot find source directory `%s\'.' % srcdir,
+                  file=sys.stderr)
             return 1
         if not path.isfile(path.join(srcdir, 'conf.py')) and \
                '-c' not in allopts and '-C' not in allopts:
-            print >>sys.stderr, ('Error: Source directory doesn\'t '
-                                 'contain a conf.py file.')
+            print('Error: Source directory doesn\'t contain a conf.py file.',
+                  file=sys.stderr)
             return 1
         outdir = abspath(args[1])
     except IndexError:
         usage(argv, 'Error: Insufficient arguments.')
         return 1
     except UnicodeError:
-        print >>sys.stderr, (
+        print(
             'Error: Multibyte filename not supported on this filesystem '
-            'encoding (%r).' % fs_encoding)
+            'encoding (%r).' % fs_encoding, file=sys.stderr)
         return 1
 
     # handle remaining filename arguments
@@ -130,7 +132,7 @@
     err = 0
     for filename in filenames:
         if not path.isfile(filename):
-            print >>sys.stderr, 'Error: Cannot find file %r.' % filename
+            print('Error: Cannot find file %r.' % filename, file=sys.stderr)
             err = 1
     if err:
         return 1
@@ -169,8 +171,8 @@
         elif opt == '-c':
             confdir = abspath(val)
             if not path.isfile(path.join(confdir, 'conf.py')):
-                print >>sys.stderr, ('Error: Configuration directory '
-                                     'doesn\'t contain conf.py file.')
+                print('Error: Configuration directory doesn\'t contain conf.py file.',
+                      file=sys.stderr)
                 return 1
         elif opt == '-C':
             confdir = None
@@ -178,29 +180,26 @@
             try:
                 key, val = val.split('=')
             except ValueError:
-                print >>sys.stderr, ('Error: -D option argument must be '
-                                     'in the form name=value.')
+                print('Error: -D option argument must be in the form name=value.',
+                      file=sys.stderr)
                 return 1
-            try:
-                val = int(val)
-            except ValueError:
-                if likely_encoding and isinstance(val, bytes):
-                    try:
-                        val = val.decode(likely_encoding)
-                    except UnicodeError:
-                        pass
+            if likely_encoding and isinstance(val, binary_type):
+                try:
+                    val = val.decode(likely_encoding)
+                except UnicodeError:
+                    pass
             confoverrides[key] = val
         elif opt == '-A':
             try:
                 key, val = val.split('=')
             except ValueError:
-                print >>sys.stderr, ('Error: -A option argument must be '
-                                     'in the form name=value.')
+                print('Error: -A option argument must be in the form name=value.',
+                      file=sys.stderr)
                 return 1
             try:
                 val = int(val)
             except ValueError:
-                if likely_encoding and isinstance(val, bytes):
+                if likely_encoding and isinstance(val, binary_type):
                     try:
                         val = val.decode(likely_encoding)
                     except UnicodeError:
@@ -232,8 +231,8 @@
             try:
                 parallel = int(val)
             except ValueError:
-                print >>sys.stderr, ('Error: -j option argument must be an '
-                                     'integer.')
+                print('Error: -j option argument must be an integer.',
+                      file=sys.stderr)
                 return 1
 
     if warning and warnfile:
@@ -243,7 +242,7 @@
 
     if not path.isdir(outdir):
         if status:
-            print >>status, 'Making output directory...'
+            print('Making output directory...', file=status)
         os.makedirs(outdir)
 
     app = None
@@ -253,44 +252,44 @@
                      warningiserror, tags, verbosity, parallel)
         app.build(force_all, filenames)
         return app.statuscode
-    except (Exception, KeyboardInterrupt), err:
+    except (Exception, KeyboardInterrupt) as err:
         if use_pdb:
             import pdb
-            print >>error, red('Exception occurred while building, '
-                               'starting debugger:')
+            print(red('Exception occurred while building, starting debugger:'),
+                  file=error)
             traceback.print_exc()
             pdb.post_mortem(sys.exc_info()[2])
         else:
-            print >>error
+            print(file=error)
             if show_traceback:
                 traceback.print_exc(None, error)
-                print >>error
+                print(file=error)
             if isinstance(err, KeyboardInterrupt):
-                print >>error, 'interrupted!'
+                print('interrupted!', file=error)
             elif isinstance(err, SystemMessage):
-                print >>error, red('reST markup error:')
-                print >>error, terminal_safe(err.args[0])
+                print(red('reST markup error:'), file=error)
+                print(terminal_safe(err.args[0]), file=error)
             elif isinstance(err, SphinxError):
-                print >>error, red('%s:' % err.category)
-                print >>error, terminal_safe(unicode(err))
+                print(red('%s:' % err.category), file=error)
+                print(terminal_safe(text_type(err)), file=error)
             elif isinstance(err, UnicodeError):
-                print >>error, red('Encoding error:')
-                print >>error, terminal_safe(unicode(err))
+                print(red('Encoding error:'), file=error)
+                print(terminal_safe(text_type(err)), file=error)
                 tbpath = save_traceback(app)
-                print >>error, red('The full traceback has been saved '
-                                   'in %s, if you want to report the '
-                                   'issue to the developers.' % tbpath)
+                print(red('The full traceback has been saved in %s, if you want '
+                          'to report the issue to the developers.' % tbpath),
+                      file=error)
             else:
-                print >>error, red('Exception occurred:')
-                print >>error, format_exception_cut_frames().rstrip()
+                print(red('Exception occurred:'), file=error)
+                print(format_exception_cut_frames().rstrip(), file=error)
                 tbpath = save_traceback(app)
-                print >>error, red('The full traceback has been saved '
-                                   'in %s, if you want to report the '
-                                   'issue to the developers.' % tbpath)
-                print >>error, ('Please also report this if it was a user '
-                                'error, so that a better error message '
-                                'can be provided next time.')
-                print >>error, (
-                    'A bug report can be filed in the tracker at '
-                    '<https://bitbucket.org/birkenfeld/sphinx/issues/>. Thanks!')
+                print(red('The full traceback has been saved in %s, if you '
+                          'want to report the issue to the developers.' % tbpath),
+                      file=error)
+                print('Please also report this if it was a user error, so '
+                      'that a better error message can be provided next time.',
+                      file=error)
+                print('A bug report can be filed in the tracker at '
+                      '<https://bitbucket.org/birkenfeld/sphinx/issues/>. Thanks!',
+                      file=error)
             return 1
diff --git a/sphinx/config.py b/sphinx/config.py
index a4fc234..9e5705e 100644
--- a/sphinx/config.py
+++ b/sphinx/config.py
@@ -11,18 +11,19 @@
 
 import os
 import re
-import sys
 from os import path
 
+from six import PY3, iteritems, string_types, binary_type, integer_types
+
 from sphinx.errors import ConfigError
 from sphinx.locale import l_
 from sphinx.util.osutil import make_filename
-from sphinx.util.pycompat import bytes, b, execfile_
+from sphinx.util.pycompat import execfile_
 
-nonascii_re = re.compile(b(r'[\x80-\xff]'))
+nonascii_re = re.compile(br'[\x80-\xff]')
 
 CONFIG_SYNTAX_ERROR = "There is a syntax error in your configuration file: %s"
-if sys.version_info >= (3, 0):
+if PY3:
     CONFIG_SYNTAX_ERROR += "\nDid you change the syntax from 2.x to 3.x?"
 
 class Config(object):
@@ -51,10 +52,6 @@
         source_suffix = ('.rst', 'env'),
         source_encoding = ('utf-8-sig', 'env'),
         exclude_patterns = ([], 'env'),
-        # the next three are all deprecated now
-        unused_docs = ([], 'env'),
-        exclude_trees = ([], 'env'),
-        exclude_dirnames = ([], 'env'),
         default_role = (None, 'env'),
         add_function_parentheses = (True, 'env'),
         add_module_names = (True, 'env'),
@@ -71,6 +68,7 @@
         trim_doctest_flags = (True, 'env'),
         primary_domain = ('py', 'env'),
         needs_sphinx = (None, None),
+        needs_extensions = ({}, None),
         nitpicky = (False, 'env'),
         nitpick_ignore = ([], 'html'),
 
@@ -205,6 +203,9 @@
 
         # gettext options
         gettext_compact = (True, 'gettext'),
+        gettext_location = (True, 'gettext'),
+        gettext_uuid = (True, 'gettext'),
+        gettext_auto_build = (True, 'env'),
 
         # XML options
         xml_pretty = (True, 'env'),
@@ -214,8 +215,11 @@
         self.overrides = overrides
         self.values = Config.config_values.copy()
         config = {}
-        if "extensions" in overrides:
-            config["extensions"] = overrides["extensions"]
+        if 'extensions' in overrides:
+            if isinstance(overrides['extensions'], string_types):
+                config['extensions'] = overrides.pop('extensions').split(',')
+            else:
+                config['extensions'] = overrides.pop('extensions')
         if dirname is not None:
             config_file = path.join(dirname, filename)
             config['__file__'] = config_file
@@ -227,7 +231,7 @@
                 os.chdir(dirname)
                 try:
                     execfile_(filename, config)
-                except SyntaxError, err:
+                except SyntaxError as err:
                     raise ConfigError(CONFIG_SYNTAX_ERROR % err)
             finally:
                 os.chdir(olddir)
@@ -241,19 +245,43 @@
     def check_unicode(self, warn):
         # check all string values for non-ASCII characters in bytestrings,
         # since that can result in UnicodeErrors all over the place
-        for name, value in self._raw_config.iteritems():
-            if isinstance(value, bytes) and nonascii_re.search(value):
+        for name, value in iteritems(self._raw_config):
+            if isinstance(value, binary_type) and nonascii_re.search(value):
                 warn('the config value %r is set to a string with non-ASCII '
                      'characters; this can lead to Unicode errors occurring. '
                      'Please use Unicode strings, e.g. %r.' % (name, u'Content')
                 )
 
-    def init_values(self):
+    def init_values(self, warn):
         config = self._raw_config
-        for valname, value in self.overrides.iteritems():
+        for valname, value in iteritems(self.overrides):
             if '.' in valname:
                 realvalname, key = valname.split('.', 1)
                 config.setdefault(realvalname, {})[key] = value
+                continue
+            elif valname not in self.values:
+                warn('unknown config value %r in override, ignoring' % valname)
+                continue
+            defvalue = self.values[valname][0]
+            if isinstance(value, string_types):
+                if isinstance(defvalue, dict):
+                    warn('cannot override dictionary config setting %r, '
+                         'ignoring (use %r to set individual elements)' %
+                         (valname, valname + '.key=value'))
+                    continue
+                elif isinstance(defvalue, list):
+                    config[valname] = value.split(',')
+                elif isinstance(defvalue, integer_types):
+                    try:
+                        config[valname] = int(value)
+                    except ValueError:
+                        warn('invalid number %r for config value %r, ignoring'
+                             % (value, valname))
+                elif defvalue is not None and not isinstance(defvalue, string_types):
+                    warn('cannot override config setting %r with unsupported type, '
+                         'ignoring' % valname)
+                else:
+                    config[valname] = value
             else:
                 config[valname] = value
         for name in config:
diff --git a/sphinx/directives/__init__.py b/sphinx/directives/__init__.py
index 250a013..52b638f 100644
--- a/sphinx/directives/__init__.py
+++ b/sphinx/directives/__init__.py
@@ -178,7 +178,7 @@
         domain_name = self.arguments[0].lower()
         # if domain_name not in env.domains:
         #     # try searching by label
-        #     for domain in env.domains.itervalues():
+        #     for domain in itervalues(env.domains):
         #         if domain.label.lower() == domain_name:
         #             domain_name = domain.name
         #             break
diff --git a/sphinx/directives/code.py b/sphinx/directives/code.py
index 9bfac5a..6ea525b 100644
--- a/sphinx/directives/code.py
+++ b/sphinx/directives/code.py
@@ -9,10 +9,13 @@
 
 import sys
 import codecs
+from difflib import unified_diff
 
 from docutils import nodes
 from docutils.parsers.rst import Directive, directives
 
+from six import string_types
+
 from sphinx import addnodes
 from sphinx.util import parselinenos
 from sphinx.util.nodes import set_source_info
@@ -39,11 +42,26 @@
             except Exception:
                 linenothreshold = 10
         else:
-            linenothreshold = sys.maxint
+            linenothreshold = sys.maxsize
         return [addnodes.highlightlang(lang=self.arguments[0].strip(),
                                        linenothreshold=linenothreshold)]
 
 
+
+def dedent_lines(lines, dedent):
+    if not dedent:
+        return lines
+
+    new_lines = []
+    for line in lines:
+        new_line = line[dedent:]
+        if line.endswith('\n') and not new_line:
+            new_line = '\n'  # keep CRLF
+        new_lines.append(new_line)
+
+    return new_lines
+
+
 class CodeBlock(Directive):
     """
     Directive for a code block with special highlighting or line numbering
@@ -56,7 +74,10 @@
     final_argument_whitespace = False
     option_spec = {
         'linenos': directives.flag,
+        'dedent': int,
+        'lineno-start': int,
         'emphasize-lines': directives.unchanged_required,
+        'caption': directives.unchanged_required,
     }
 
     def run(self):
@@ -67,17 +88,29 @@
             try:
                 nlines = len(self.content)
                 hl_lines = [x+1 for x in parselinenos(linespec, nlines)]
-            except ValueError, err:
+            except ValueError as err:
                 document = self.state.document
                 return [document.reporter.warning(str(err), line=self.lineno)]
         else:
             hl_lines = None
+        
+        if 'dedent' in self.options:
+            lines = code.split('\n')
+            lines = dedent_lines(lines, self.options['dedent'])
+            code = '\n'.join(lines)
 
         literal = nodes.literal_block(code, code)
         literal['language'] = self.arguments[0]
-        literal['linenos'] = 'linenos' in self.options
+        caption = self.options.get('caption')
+        if caption:
+            literal['caption'] = caption
+        literal['linenos'] = 'linenos' in self.options or \
+                             'lineno-start' in self.options
+        extra_args = literal['highlight_args'] = {}
         if hl_lines is not None:
-            literal['highlight_args'] = {'hl_lines': hl_lines}
+            extra_args['hl_lines'] = hl_lines
+        if 'lineno-start' in self.options:
+            extra_args['linenostart'] = self.options['lineno-start']
         set_source_info(self, literal)
         return [literal]
 
@@ -94,7 +127,9 @@
     optional_arguments = 0
     final_argument_whitespace = True
     option_spec = {
+        'dedent': int,
         'linenos': directives.flag,
+        'lineno-start': int,
         'tab-width': int,
         'language': directives.unchanged_required,
         'encoding': directives.encoding,
@@ -105,8 +140,31 @@
         'prepend': directives.unchanged_required,
         'append': directives.unchanged_required,
         'emphasize-lines': directives.unchanged_required,
+        'caption': directives.unchanged,
+        'diff': directives.unchanged_required,
     }
 
+    def read_with_encoding(self, filename, document, codec_info, encoding):
+        f = None
+        try:
+            f = codecs.StreamReaderWriter(open(filename, 'rb'),
+                                          codec_info[2], codec_info[3], 'strict')
+            lines = f.readlines()
+            lines = dedent_lines(lines, self.options.get('dedent'))
+            return lines
+        except (IOError, OSError):
+            return [document.reporter.warning(
+                'Include file %r not found or reading it failed' % filename,
+                line=self.lineno)]
+        except UnicodeError:
+            return [document.reporter.warning(
+                'Encoding %r used for reading included file %r seems to '
+                'be wrong, try giving an :encoding: option' %
+                (encoding, filename))]
+        finally:
+            if f is not None:
+                f.close()
+
     def run(self):
         document = self.state.document
         if not document.settings.file_insertion_enabled:
@@ -122,23 +180,26 @@
 
         encoding = self.options.get('encoding', env.config.source_encoding)
         codec_info = codecs.lookup(encoding)
-        f = None
-        try:
-            f = codecs.StreamReaderWriter(open(filename, 'rb'),
-                    codec_info[2], codec_info[3], 'strict')
-            lines = f.readlines()
-        except (IOError, OSError):
-            return [document.reporter.warning(
-                'Include file %r not found or reading it failed' % filename,
-                line=self.lineno)]
-        except UnicodeError:
-            return [document.reporter.warning(
-                'Encoding %r used for reading included file %r seems to '
-                'be wrong, try giving an :encoding: option' %
-                (encoding, filename))]
-        finally:
-            if f is not None:
-                f.close()
+
+        lines = self.read_with_encoding(filename, document,
+                                        codec_info, encoding)
+        if not isinstance(lines[0], string_types):
+            return lines
+
+        diffsource = self.options.get('diff')
+        if diffsource is not None:
+            tmp, fulldiffsource = env.relfn2path(diffsource)
+
+            difflines = self.read_with_encoding(fulldiffsource, document,
+                                           codec_info, encoding)
+            if not isinstance(difflines[0], string_types):
+                return difflines
+            diff = unified_diff(
+                difflines,
+                lines,
+                diffsource,
+                self.arguments[0])
+            lines = list(diff)
 
         objectname = self.options.get('pyobject')
         if objectname is not None:
@@ -156,7 +217,7 @@
         if linespec is not None:
             try:
                 linelist = parselinenos(linespec, len(lines))
-            except ValueError, err:
+            except ValueError as err:
                 return [document.reporter.warning(str(err), line=self.lineno)]
             # just ignore nonexisting lines
             nlines = len(lines)
@@ -170,7 +231,7 @@
         if linespec:
             try:
                 hl_lines = [x+1 for x in parselinenos(linespec, len(lines))]
-            except ValueError, err:
+            except ValueError as err:
                 return [document.reporter.warning(str(err), line=self.lineno)]
         else:
             hl_lines = None
@@ -202,12 +263,22 @@
             text = text.expandtabs(self.options['tab-width'])
         retnode = nodes.literal_block(text, text, source=filename)
         set_source_info(self, retnode)
+        if diffsource is not None:  # if diff is set, set udiff
+            retnode['language'] = 'udiff'
         if self.options.get('language', ''):
             retnode['language'] = self.options['language']
-        if 'linenos' in self.options:
-            retnode['linenos'] = True
+        retnode['linenos'] = 'linenos' in self.options or \
+                             'lineno-start' in self.options
+        caption = self.options.get('caption')
+        if caption is not None:
+            if not caption:
+                caption = self.arguments[0]
+            retnode['caption'] = caption
+        extra_args = retnode['highlight_args'] = {}
         if hl_lines is not None:
-            retnode['highlight_args'] = {'hl_lines': hl_lines}
+            extra_args['hl_lines'] = hl_lines
+        if 'lineno-start' in self.options:
+            extra_args['linenostart'] = self.options['lineno-start']
         env.note_dependency(rel_filename)
         return [retnode]
 
diff --git a/sphinx/directives/other.py b/sphinx/directives/other.py
index d28c00f..01c8c01 100644
--- a/sphinx/directives/other.py
+++ b/sphinx/directives/other.py
@@ -7,6 +7,7 @@
     :license: BSD, see LICENSE for details.
 """
 
+from six.moves import range
 from docutils import nodes
 from docutils.parsers.rst import Directive, directives
 from docutils.parsers.rst.directives.admonitions import BaseAdmonition
@@ -368,7 +369,7 @@
             # be placed in the doctree.
             n_sects_to_raise = current_depth - nested_depth + 1
             parent = self.state.parent
-            for i in xrange(n_sects_to_raise):
+            for i in range(n_sects_to_raise):
                 if parent.parent:
                     parent = parent.parent
             parent.append(node)
diff --git a/sphinx/domains/__init__.py b/sphinx/domains/__init__.py
index 200fd51..51b886f 100644
--- a/sphinx/domains/__init__.py
+++ b/sphinx/domains/__init__.py
@@ -10,6 +10,8 @@
     :license: BSD, see LICENSE for details.
 """
 
+from six import iteritems
+
 from sphinx.errors import SphinxError
 from sphinx.locale import _
 
@@ -153,7 +155,7 @@
         self._role_cache = {}
         self._directive_cache = {}
         self._role2type = {}
-        for name, obj in self.object_types.iteritems():
+        for name, obj in iteritems(self.object_types):
             for rolename in obj.roles:
                 self._role2type.setdefault(rolename, []).append(name)
         self.objtypes_for_role = self._role2type.get
diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py
index fb38cfe..4d12c14 100644
--- a/sphinx/domains/c.py
+++ b/sphinx/domains/c.py
@@ -39,6 +39,13 @@
         \( (.*) \)         # arguments
         (\s+const)? $      # const specifier
     ''', re.VERBOSE)
+c_funcptr_arg_sig_re = re.compile(
+    r'''^\s*([^(,]+?)      # return type
+        \( ([^()]+) \) \s* # name in parentheses
+        \( (.*) \)         # arguments
+        (\s+const)?        # const specifier
+        \s*(?=$|,)         # end with comma or end of string
+    ''', re.VERBOSE)
 c_funcptr_name_re = re.compile(r'^\(\s*\*\s*(.*?)\s*\)$')
 
 
@@ -68,7 +75,7 @@
 
     def _parse_type(self, node, ctype):
         # add cross-ref nodes for all words
-        for part in filter(None, wsplit_re.split(ctype)):
+        for part in [_f for _f in wsplit_re.split(ctype) if _f]:
             tnode = nodes.Text(part, part)
             if part[0] in string.ascii_letters+'_' and \
                    part not in self.stopwords:
@@ -80,6 +87,24 @@
             else:
                 node += tnode
 
+    def _parse_arglist(self, arglist):
+        while True:
+            m = c_funcptr_arg_sig_re.match(arglist)
+            if m:
+                yield m.group()
+                arglist = c_funcptr_arg_sig_re.sub('', arglist)
+                if ',' in arglist:
+                    _, arglist = arglist.split(',', 1)
+                else:
+                    break
+            else:
+                if ',' in arglist:
+                    arg, arglist = arglist.split(',', 1)
+                    yield arg
+                else:
+                    yield arglist
+                    break
+
     def handle_signature(self, sig, signode):
         """Transform a C signature into RST nodes."""
         # first try the function pointer signature regex, it's more specific
@@ -122,19 +147,25 @@
         paramlist = addnodes.desc_parameterlist()
         arglist = arglist.replace('`', '').replace('\\ ', '') # remove markup
         # this messes up function pointer types, but not too badly ;)
-        args = arglist.split(',')
-        for arg in args:
+        for arg in self._parse_arglist(arglist):
             arg = arg.strip()
             param = addnodes.desc_parameter('', '', noemph=True)
             try:
-                ctype, argname = arg.rsplit(' ', 1)
+                m = c_funcptr_arg_sig_re.match(arg)
+                if m:
+                    self._parse_type(param, m.group(1) + '(')
+                    param += nodes.emphasis(m.group(2), m.group(2))
+                    self._parse_type(param, ')(' + m.group(3) + ')')
+                    if m.group(4):
+                        param += addnodes.desc_addname(m.group(4), m.group(4))
+                else:
+                    ctype, argname = arg.rsplit(' ', 1)
+                    self._parse_type(param, ctype)
+                    # separate by non-breaking space in the output
+                    param += nodes.emphasis(' '+argname, u'\xa0'+argname)
             except ValueError:
                 # no argument name given, only the type
                 self._parse_type(param, arg)
-            else:
-                self._parse_type(param, ctype)
-                # separate by non-breaking space in the output
-                param += nodes.emphasis(' '+argname, u'\xa0'+argname)
             paramlist += param
         signode += paramlist
         if const:
@@ -234,7 +265,7 @@
     }
 
     def clear_doc(self, docname):
-        for fullname, (fn, _) in self.data['objects'].items():
+        for fullname, (fn, _) in list(self.data['objects'].items()):
             if fn == docname:
                 del self.data['objects'][fullname]
 
@@ -249,5 +280,5 @@
                             contnode, target)
 
     def get_objects(self):
-        for refname, (docname, type) in self.data['objects'].iteritems():
+        for refname, (docname, type) in list(self.data['objects'].items()):
             yield (refname, refname, type, docname, 'c.' + refname, 1)
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py
index cb64a60..778a36b 100644
--- a/sphinx/domains/cpp.py
+++ b/sphinx/domains/cpp.py
@@ -7,11 +7,144 @@
 
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
+
+    See http://www.nongnu.org/hcb/ for the grammar.
+    See http://mentorembedded.github.io/cxx-abi/abi.html#mangling for the
+    inspiration for the id generation.
+
+    common grammar things:
+           simple-declaration
+        -> attribute-specifier-seq[opt] decl-specifier-seq[opt]
+           init-declarator-list[opt] ;
+        # Drop the semi-colon. For now: drop the attributes (TODO).
+        # Use at most 1 init-declerator.
+        -> decl-specifier-seq init-declerator
+        -> decl-specifier-seq declerator initializer
+
+        decl-specifier ->
+              storage-class-specifier -> "static" (only for member_object and
+              function_object)
+            | type-specifier -> trailing-type-specifier
+            | function-specifier -> "inline" | "virtual" | "explicit" (only
+              for function_object)
+            | "friend" (only for function_object)
+            | "constexpr" (only for member_object and function_object)
+        trailing-type-specifier ->
+              simple-type-specifier
+            | elaborated-type-specifier
+            | typename-specifier
+            | cv-qualifier -> "const" | "volatile"
+        stricter grammar for decl-specifier-seq (with everything, each object
+        uses a subset):
+            visibility storage-class-specifier function-specifier "friend"
+            "constexpr" "volatile" "const" trailing-type-specifier
+            # where trailing-type-specifier can no be cv-qualifier
+        # Inside e.g., template paramters a strict subset is used
+        # (see type-specifier-seq)
+        trailing-type-specifier ->
+              simple-type-specifier ->
+                ::[opt] nested-name-specifier[opt] type-name
+              | ::[opt] nested-name-specifier "template" simple-template-id
+              | "char" | "bool" | ect.
+              | decltype-specifier
+            | elaborated-type-specifier ->
+                class-key attribute-specifier-seq[opt] ::[opt]
+                nested-name-specifier[opt] identifier
+              | class-key ::[opt] nested-name-specifier[opt] template[opt]
+                simple-template-id
+              | "enum" ::[opt] nested-name-specifier[opt] identifier
+            | typename-specifier ->
+                "typename" ::[opt] nested-name-specifier identifier
+              | "typename" ::[opt] nested-name-specifier template[opt]
+                simple-template-id
+        class-key -> "class" | "struct" | "union"
+        type-name ->* identifier | simple-template-id
+        # ignoring attributes and decltype, and then some left-factoring
+        trailing-type-specifier ->
+            rest-of-trailing
+            ("class" | "struct" | "union" | "typename") rest-of-trailing
+            build-in -> "char" | "bool" | ect.
+            decltype-specifier
+        rest-of-trailing -> (with some simplification)
+            "::"[opt] list-of-elements-separated-by-::
+        element ->
+            "template"[opt] identifier ("<" template-argument-list ">")[opt]
+        template-argument-list ->
+              template-argument "..."[opt]
+            | template-argument-list "," template-argument "..."[opt]
+        template-argument ->
+              constant-expression
+            | type-specifier-seq abstract-declerator
+            | id-expression
+
+
+        declerator ->
+              ptr-declerator
+            | noptr-declarator parameters-and-qualifiers trailing-return-type
+              (TODO: for now we don't support it)
+        ptr-declerator ->
+              noptr-declerator
+            | ptr-operator ptr-declarator
+        noptr-declerator ->
+              declarator-id attribute-specifier-seq[opt] ->
+                    "..."[opt] id-expression
+                  | rest-of-trailing
+            | noptr-declerator parameters-and-qualifiers
+            | noptr-declarator "[" constant-expression[opt] "]"
+              attribute-specifier-seq[opt]
+            | "(" ptr-declarator ")"  # TODO: not implemented yet
+        # function_object must use a parameters-and-qualifiers, the others may
+        # use it (e.g., function poitners)
+        parameters-and-qualifiers ->
+            "(" parameter-clause ")" attribute-specifier-seq[opt]
+            cv-qualifier-seq[opt] ref-qualifier[opt]
+            exception-specification[opt]
+        ref-qualifier -> "&" | "&&"
+        exception-specification ->
+            "noexcept" ("(" constant-expression ")")[opt]
+            "throw" ("(" type-id-list ")")[opt]
+        # TODO: we don't implement attributes
+        # member functions can have initializers, but we fold them into here
+        memberFunctionInit -> "=" "0"
+        # (note: only "0" is allowed as the value, according to the standard,
+        # right?)
+
+
+    We additionally add the possibility for specifying the visibility as the
+    first thing.
+
+    type_object:
+        goal:
+            either a single type (e.g., "MyClass:Something_T" or a typedef-like
+            thing (e.g. "Something Something_T" or "int I_arr[]"
+        grammar, single type: based on a type in a function parameter, but
+        without a name:
+               parameter-declaration
+            -> attribute-specifier-seq[opt] decl-specifier-seq
+               abstract-declarator[opt]
+            # Drop the attributes
+            -> decl-specifier-seq abstract-declarator[opt]
+        grammar, typedef-like: no initilizer
+            decl-specifier-seq declerator
+
+
+    member_object:
+        goal: as a type_object which must have a declerator, and optionally
+        with a initializer
+        grammar:
+            decl-specifier-seq declerator initializer
+
+    function_object:
+        goal: a function declaration, TODO: what about templates? for now: skip
+        grammar: no initializer
+           decl-specifier-seq declerator
 """
 
 import re
+import traceback
 from copy import deepcopy
 
+from six import iteritems, text_type
 from docutils import nodes
 
 from sphinx import addnodes
@@ -21,6 +154,7 @@
 from sphinx.directives import ObjectDescription
 from sphinx.util.nodes import make_refnode
 from sphinx.util.compat import Directive
+from sphinx.util.pycompat import UnicodeMixin
 from sphinx.util.docfields import Field, GroupedField
 
 
@@ -40,88 +174,112 @@
     |   [!<>=/*%+|&^~-]=?
 ''')
 
-_id_shortwords = {
-    'char':                 'c',
-    'signed char':          'c',
-    'unsigned char':        'C',
-    'int':                  'i',
-    'signed int':           'i',
-    'unsigned int':         'U',
-    'long':                 'l',
-    'signed long':          'l',
-    'unsigned long':        'L',
-    'bool':                 'b',
-    'size_t':               's',
-    'std::string':          'ss',
-    'std::ostream':         'os',
-    'std::istream':         'is',
-    'std::iostream':        'ios',
-    'std::vector':          'v',
-    'std::map':             'm',
-    'operator[]':           'subscript-operator',
-    'operator()':           'call-operator',
-    'operator!':            'not-operator',
-    'operator<':            'lt-operator',
-    'operator<=':           'lte-operator',
-    'operator>':            'gt-operator',
-    'operator>=':           'gte-operator',
-    'operator=':            'assign-operator',
-    'operator/':            'div-operator',
-    'operator*':            'mul-operator',
-    'operator%':            'mod-operator',
-    'operator+':            'add-operator',
-    'operator-':            'sub-operator',
-    'operator|':            'or-operator',
-    'operator&':            'and-operator',
-    'operator^':            'xor-operator',
-    'operator&&':           'sand-operator',
-    'operator||':           'sor-operator',
-    'operator==':           'eq-operator',
-    'operator!=':           'neq-operator',
-    'operator<<':           'lshift-operator',
-    'operator>>':           'rshift-operator',
-    'operator-=':           'sub-assign-operator',
-    'operator+=':           'add-assign-operator',
-    'operator*-':           'mul-assign-operator',
-    'operator/=':           'div-assign-operator',
-    'operator%=':           'mod-assign-operator',
-    'operator&=':           'and-assign-operator',
-    'operator|=':           'or-assign-operator',
-    'operator<<=':          'lshift-assign-operator',
-    'operator>>=':          'rshift-assign-operator',
-    'operator^=':           'xor-assign-operator',
-    'operator,':            'comma-operator',
-    'operator->':           'pointer-operator',
-    'operator->*':          'pointer-by-pointer-operator',
-    'operator~':            'inv-operator',
-    'operator++':           'inc-operator',
-    'operator--':           'dec-operator',
-    'operator new':         'new-operator',
-    'operator new[]':       'new-array-operator',
-    'operator delete':      'delete-operator',
-    'operator delete[]':    'delete-array-operator'
+_id_prefix = '_CPP'
+_id_fundamental = {
+    # not all of these are actually parsed as fundamental types, TODO: do that
+    'void': 'v',
+    'bool': 'b',
+    'char': 'c',
+    'signed char': 'a',
+    'unsigned char': 'h',
+    'wchar_t': 'w',
+    'char32_t': 'Di',
+    'char16_t': 'Ds',
+    'short': 's',
+    'short int': 's',
+    'signed short': 's',
+    'signed short int': 's',
+    'unsigned short': 't',
+    'unsigned short int': 't',
+    'int': 'i',
+    'signed': 'i',
+    'signed int': 'i',
+    'unsigned': 'j',
+    'unsigned int': 'j',
+    'long': 'l',
+    'long int': 'l',
+    'signed long': 'l',
+    'signed long int': 'l',
+    'unsigned long': 'm',
+    'unsigned long int': 'm',
+    'long long': 'x',
+    'long long int': 'x',
+    'signed long long': 'x',
+    'signed long long int': 'x',
+    'unsigned long long': 'y',
+    'unsigned long long int': 'y',
+    'float': 'f',
+    'double': 'd',
+    'long double': 'e',
+    'auto': 'Da',
+    'decltype(auto)': 'Dc',
+    'std::nullptr_t': 'Dn'
+}
+_id_operator = {
+    'new': 'nw',
+    'new[]': 'na',
+    'delete': 'dl',
+    'delete[]': 'da',
+    # the arguments will make the difference between unary and binary
+    # '+(unary)' : 'ps',
+    #'-(unary)' : 'ng',
+    #'&(unary)' : 'ad',
+    #'*(unary)' : 'de',
+    '~': 'co',
+    '+': 'pl',
+    '-': 'mi',
+    '*': 'ml',
+    '/': 'dv',
+    '%': 'rm',
+    '&': 'an',
+    '|': 'or',
+    '^': 'eo',
+    '=': 'aS',
+    '+=': 'pL',
+    '-=': 'mI',
+    '*=': 'mL',
+    '/=': 'dV',
+    '%=': 'rM',
+    '&=': 'aN',
+    '|=': 'oR',
+    '^=': 'eO',
+    '<<': 'ls',
+    '>>': 'rs',
+    '<<=': 'lS',
+    '>>=': 'rS',
+    '==': 'eq',
+    '!=': 'ne',
+    '<': 'lt',
+    '>': 'gt',
+    '<=': 'le',
+    '>=': 'ge',
+    '!': 'nt',
+    '&&': 'aa',
+    '||': 'oo',
+    '++': 'pp',
+    '--': 'mm',
+    ',': 'cm',
+    '->*': 'pm',
+    '->': 'pt',
+    '()': 'cl',
+    '[]': 'ix'
 }
 
 
-class DefinitionError(Exception):
-
+class DefinitionError(UnicodeMixin, Exception):
     def __init__(self, description):
         self.description = description
 
-    def __str__(self):
-        return unicode(self).encode('utf-8')
-
     def __unicode__(self):
         return self.description
 
 
-class DefExpr(object):
-
+class ASTBase(UnicodeMixin):
     def __eq__(self, other):
         if type(self) is not type(other):
             return False
         try:
-            for key, value in self.__dict__.iteritems():
+            for key, value in iteritems(self.__dict__):
                 if value != getattr(other, key):
                     return False
         except AttributeError:
@@ -139,7 +297,7 @@
 
     def get_id(self):
         """Return the id for the node."""
-        return u''
+        raise NotImplementedError(repr(self))
 
     def get_name(self):
         """Return the name.
@@ -147,402 +305,748 @@
         Returns either `None` or a node with a name you might call
         :meth:`split_owner` on.
         """
-        return None
+        raise NotImplementedError(repr(self))
 
-    def split_owner(self):
-        """Nodes returned by :meth:`get_name` can split off their
-        owning parent.  This function returns the owner and the
-        name as a tuple of two items.  If a node does not support
-        it, it returns None as owner and self as name.
-        """
-        return None, self
-
-    def prefix(self, prefix):
+    def prefix_nested_name(self, prefix):
         """Prefix a name node (a node returned by :meth:`get_name`)."""
-        raise NotImplementedError()
-
-    def __str__(self):
-        return unicode(self).encode('utf-8')
+        raise NotImplementedError(repr(self))
 
     def __unicode__(self):
-        raise NotImplementedError()
+        raise NotImplementedError(repr(self))
 
     def __repr__(self):
         return '<%s %s>' % (self.__class__.__name__, self)
 
 
-class PrimaryDefExpr(DefExpr):
+def _verify_description_mode(mode):
+    if not mode in ('lastIsName', 'noneIsName', 'markType', 'param'):
+        raise Exception("Description mode '%s' is invalid." % mode)
 
-    def get_name(self):
+
+class ASTOperatorBuildIn(ASTBase):
+    def __init__(self, op):
+        self.op = op
+
+    def get_id(self):
+        if not self.op in _id_operator:
+            raise Exception('Internal error: Build-in operator "%s" can not '
+                            'be mapped to an id.' % self.op)
+        return _id_operator[self.op]
+
+    def __unicode__(self):
+        if self.op in ('new', 'new[]', 'delete', 'delete[]'):
+            return u'operator ' + self.op
+        else:
+            return u'operator' + self.op
+
+    def get_name_no_template(self):
+        return text_type(self)
+
+    def describe_signature(self, signode, mode, env, prefix):
+        _verify_description_mode(mode)
+        identifier = text_type(self)
+        if mode == 'lastIsName':
+            signode += addnodes.desc_name(identifier, identifier)
+        else:
+            signode += addnodes.desc_addname(identifier, identifier)
+
+
+class ASTOperatorType(ASTBase):
+    def __init__(self, type):
+        self.type = type
+
+    def __unicode__(self):
+        return u''.join(['operator ', text_type(self.type)])
+
+    def get_id(self):
+        return u'cv' + self.type.get_id()
+
+    def get_name_no_template(self):
+        return text_type(self)
+
+    def describe_signature(self, signode, mode, env, prefix):
+        _verify_description_mode(mode)
+        identifier = text_type(self)
+        if mode == 'lastIsName':
+            signode += addnodes.desc_name(identifier, identifier)
+        else:
+            signode += addnodes.desc_addname(identifier, identifier)
+
+
+class ASTTemplateArgConstant(ASTBase):
+    def __init__(self, value):
+        self.value = value
+
+    def __unicode__(self):
+        return text_type(self.value)
+
+    def get_id(self):
+        # TODO: doing this properly needs parsing of expressions, let's just
+        # juse it verbatim for now
+        return u'X' + text_type(self) + u'E'
+
+    def describe_signature(self, signode, mode, env):
+        _verify_description_mode(mode)
+        signode += nodes.Text(text_type(self))
+
+
+class ASTNestedNameElement(ASTBase):
+    def __init__(self, identifier, templateArgs):
+        self.identifier = identifier
+        self.templateArgs = templateArgs
+
+    def get_id(self):
+        res = []
+        if self.identifier == "std":
+            res.append(u'St')
+        else:
+            res.append(text_type(len(self.identifier)))
+            res.append(self.identifier)
+        if self.templateArgs:
+            res.append('I')
+            for a in self.templateArgs:
+                res.append(a.get_id())
+            res.append('E')
+        return u''.join(res)
+
+    def __unicode__(self):
+        res = []
+        res.append(self.identifier)
+        if self.templateArgs:
+            res.append('<')
+            first = True
+            for a in self.templateArgs:
+                if not first:
+                    res.append(', ')
+                first = False
+                res.append(text_type(a))
+            res.append('>')
+        return u''.join(res)
+
+    def get_name_no_template(self):
+        return text_type(self.identifier)
+
+    def describe_signature(self, signode, mode, env, prefix):
+        _verify_description_mode(mode)
+        if mode == 'markType':
+            targetText = prefix + text_type(self)
+            pnode = addnodes.pending_xref(
+                '', refdomain='cpp', reftype='type',
+                reftarget=targetText, modname=None, classname=None)
+            if env:  # during testing we don't have an env, do we?
+                pnode['cpp:parent'] = env.temp_data.get('cpp:parent')
+            pnode += nodes.Text(text_type(self.identifier))
+            signode += pnode
+        elif mode == 'lastIsName':
+            name = text_type(self.identifier)
+            signode += addnodes.desc_name(name, name)
+        else:
+            raise Exception('Unknown description mode: %s' % mode)
+        if self.templateArgs:
+            signode += nodes.Text('<')
+            first = True
+            for a in self.templateArgs:
+                if not first:
+                    signode += nodes.Text(', ')
+                first = False
+                a.describe_signature(signode, 'markType', env)
+            signode += nodes.Text('>')
+
+
+class ASTNestedName(ASTBase):
+    def __init__(self, names):
+        """Use an empty string as the first name if it should start with '::'
+        """
+        self.names = names
+
+    @property
+    def name(self):
         return self
 
-    def prefix(self, prefix):
-        if isinstance(prefix, PathDefExpr):
-            prefix = prefix.clone()
-            prefix.path.append(self)
-            return prefix
-        return PathDefExpr([prefix, self])
+    def get_id(self):
+        res = []
+        if len(self.names) > 1:
+            res.append('N')
+        for n in self.names:
+            res.append(n.get_id())
+        if len(self.names) > 1:
+            res.append('E')
+        return u''.join(res)
+
+    def get_name_no_last_template(self):
+        res = u'::'.join([text_type(n) for n in self.names[:-1]])
+        if len(self.names) > 1:
+            res += '::'
+        res += self.names[-1].get_name_no_template()
+        return res
+
+    def prefix_nested_name(self, prefix):
+        if self.names[0] == '':
+            return self  # it's defined at global namespace, don't tuch it
+        assert isinstance(prefix, ASTNestedName)
+        names = prefix.names[:]
+        names.extend(self.names)
+        return ASTNestedName(names)
+
+    def __unicode__(self):
+        return u'::'.join([text_type(n) for n in self.names])
+
+    def describe_signature(self, signode, mode, env):
+        _verify_description_mode(mode)
+        if mode == 'lastIsName':
+            addname = u'::'.join([text_type(n) for n in self.names[:-1]])
+            if len(self.names) > 1:
+                addname += u'::'
+            name = text_type(self.names[-1])
+            signode += addnodes.desc_addname(addname, addname)
+            self.names[-1].describe_signature(signode, mode, env, '')
+        elif mode == 'noneIsName':
+            name = text_type(self)
+            signode += nodes.Text(name)
+        elif mode == 'param':
+            name = text_type(self)
+            signode += nodes.emphasis(name, name)
+        elif mode == 'markType':
+            # each element should be a pending xref targeting the complete
+            # prefix. however, only the identifier part should be a link, such
+            # that template args can be a link as well.
+            prefix = ''
+            first = True
+            for name in self.names:
+                if not first:
+                    signode += nodes.Text('::')
+                    prefix += '::'
+                first = False
+                if name != '':
+                    name.describe_signature(signode, mode, env, prefix)
+                prefix += text_type(name)
+        else:
+            raise Exception('Unknown description mode: %s' % mode)
 
 
-class NameDefExpr(PrimaryDefExpr):
-
+class ASTTrailingTypeSpecFundamental(ASTBase):
     def __init__(self, name):
         self.name = name
 
-    def get_id(self):
-        name = _id_shortwords.get(self.name)
-        if name is not None:
-            return name
-        return self.name.replace(u' ', u'-')
-
     def __unicode__(self):
-        return unicode(self.name)
-
-
-class PathDefExpr(PrimaryDefExpr):
-
-    def __init__(self, parts):
-        self.path = parts
+        return self.name
 
     def get_id(self):
-        rv = u'::'.join(x.get_id() for x in self.path)
-        return _id_shortwords.get(rv, rv)
+        if not self.name in _id_fundamental:
+            raise Exception(
+                'Semi-internal error: Fundamental type "%s" can not be mapped '
+                'to an id. Is it a true fundamental type? If not so, the '
+                'parser should have rejected it.' % self.name)
+        return _id_fundamental[self.name]
 
-    def split_owner(self):
-        if len(self.path) > 1:
-            return PathDefExpr(self.path[:-1]), self.path[-1]
-        return None, self
-
-    def prefix(self, prefix):
-        if isinstance(prefix, PathDefExpr):
-            prefix = prefix.clone()
-            prefix.path.extend(self.path)
-            return prefix
-        return PathDefExpr([prefix] + self.path)
-
-    def __unicode__(self):
-        return u'::'.join(map(unicode, self.path))
+    def describe_signature(self, signode, mode, env):
+        signode += nodes.Text(text_type(self.name))
 
 
-class ArrayTypeSuffixDefExpr(object):
-
-    def __init__(self, size_hint=None):
-        self.size_hint = size_hint
-
-    def get_id_suffix(self):
-        return 'A'
-
-    def __unicode__(self):
-        return u'[%s]' % (
-            self.size_hint is not None and unicode(self.size_hint) or u'',
-        )
-
-
-class TemplateDefExpr(PrimaryDefExpr):
-
-    def __init__(self, typename, args):
-        self.typename = typename
-        self.args = args
-
-    def split_owner(self):
-        owner, typename = self.typename.split_owner()
-        return owner, TemplateDefExpr(typename, self.args)
-
-    def get_id(self):
-        return u'%s:%s:' % (self.typename.get_id(),
-                            u'.'.join(x.get_id() for x in self.args))
-
-    def __unicode__(self):
-        return u'%s<%s>' % (self.typename, u', '.join(map(unicode, self.args)))
-
-
-class ConstantTemplateArgExpr(PrimaryDefExpr):
-
-    def __init__(self, arg):
-        self.arg = arg
-
-    def get_id(self):
-        return self.arg.replace(u' ', u'-')
-
-    def __unicode__(self):
-        return unicode(self.arg)
-
-
-class WrappingDefExpr(DefExpr):
-
-    def __init__(self, typename):
-        self.typename = typename
-
-    def get_name(self):
-        return self.typename.get_name()
-
-
-class ModifierDefExpr(WrappingDefExpr):
-
-    def __init__(self, typename, modifiers):
-        WrappingDefExpr.__init__(self, typename)
-        self.modifiers = modifiers
-
-    def get_id(self):
-        pieces = [_id_shortwords.get(unicode(x), unicode(x))
-                  for x in self.modifiers]
-        pieces.append(self.typename.get_id())
-        return u'-'.join(pieces)
-
-    def __unicode__(self):
-        return u' '.join(map(unicode, list(self.modifiers) + [self.typename]))
-
-
-class PtrDefExpr(WrappingDefExpr):
-
-    def get_id(self):
-        return self.typename.get_id() + u'P'
-
-    def __unicode__(self):
-        return u'%s*' % self.typename
-
-
-class LValRefDefExpr(WrappingDefExpr):
-
-    def get_id(self):
-        return self.typename.get_id() + u'R'
-
-    def __unicode__(self):
-        return u'%s&' % self.typename
-
-
-class RValRefDefExpr(WrappingDefExpr):
-
-    def get_id(self):
-        return self.typename.get_id() + u'RR'
-
-    def __unicode__(self):
-        return u'%s&&' % self.typename
-
-
-class ConstDefExpr(WrappingDefExpr):
-
-    def __init__(self, typename, prefix=False):
-        WrappingDefExpr.__init__(self, typename)
+class ASTTrailingTypeSpecName(ASTBase):
+    def __init__(self, prefix, nestedName):
         self.prefix = prefix
+        self.nestedName = nestedName
+
+    @property
+    def name(self):
+        return self.nestedName
 
     def get_id(self):
-        return self.typename.get_id() + u'C'
+        return self.nestedName.get_id()
 
     def __unicode__(self):
-        return (self.prefix and u'const %s' or u'%s const') % self.typename
+        res = []
+        if self.prefix:
+            res.append(self.prefix)
+            res.append(' ')
+        res.append(text_type(self.nestedName))
+        return u''.join(res)
+
+    def describe_signature(self, signode, mode, env):
+        if self.prefix:
+            signode += addnodes.desc_annotation(self.prefix, self.prefix)
+            signode += nodes.Text(' ')
+        self.nestedName.describe_signature(signode, mode, env)
 
 
-class CastOpDefExpr(PrimaryDefExpr):
-
-    def __init__(self, typename):
-        self.typename = typename
+class ASTFunctinoParameter(ASTBase):
+    def __init__(self, arg, ellipsis=False):
+        self.arg = arg
+        self.ellipsis = ellipsis
 
     def get_id(self):
-        return u'castto-%s-operator' % self.typename.get_id()
+        if self.ellipsis:
+            return 'z'
+        else:
+            return self.arg.get_id()
 
     def __unicode__(self):
-        return u'operator %s' % self.typename
+        if self.ellipsis:
+            return '...'
+        else:
+            return text_type(self.arg)
+
+    def describe_signature(self, signode, mode, env):
+        _verify_description_mode(mode)
+        if self.ellipsis:
+            signode += nodes.Text('...')
+        else:
+            self.arg.describe_signature(signode, mode, env)
 
 
-class ArgumentDefExpr(DefExpr):
+class ASTParametersQualifiers(ASTBase):
+    def __init__(self, args, volatile, const, refQual, exceptionSpec, override,
+                 final, initializer):
+        self.args = args
+        self.volatile = volatile
+        self.const = const
+        self.refQual = refQual
+        self.exceptionSpec = exceptionSpec
+        self.override = override
+        self.final = final
+        self.initializer = initializer
 
-    def __init__(self, type, name, type_suffixes, default=None):
-        self.name = name
-        self.type = type
-        self.type_suffixes = type_suffixes
-        self.default = default
+    def get_modifiers_id(self):
+        res = []
+        if self.volatile:
+            res.append('V')
+        if self.const:
+            res.append('K')
+        if self.refQual == '&&':
+            res.append('O')
+        elif self.refQual == '&':
+            res.append('R')
+        return u''.join(res)
 
-    def get_name(self):
-        return self.name.get_name()
-
-    def get_id(self):
-        buf = []
-        buf.append(self.type and self.type.get_id() or 'X')
-        for suffix in self.type_suffixes:
-            buf.append(suffix.get_id_suffix())
-        return u''.join(buf)
+    def get_param_id(self):
+        if len(self.args) == 0:
+            return 'v'
+        else:
+            return u''.join(a.get_id() for a in self.args)
 
     def __unicode__(self):
-        buf = [(u'%s %s' % (self.type or u'', self.name or u'')).strip()]
-        if self.default is not None:
-            buf.append('=%s' % self.default)
-        for suffix in self.type_suffixes:
-            buf.append(unicode(suffix))
-        return u''.join(buf)
+        res = []
+        res.append('(')
+        first = True
+        for a in self.args:
+            if not first:
+                res.append(', ')
+            first = False
+            res.append(text_type(a))
+        res.append(')')
+        if self.volatile:
+            res.append(' volatile')
+        if self.const:
+            res.append(' const')
+        if self.refQual:
+            res.append(' ')
+            res.append(self.refQual)
+        if self.exceptionSpec:
+            res.append(' ')
+            res.append(text_type(self.exceptionSpec))
+        if self.final:
+            res.append(' final')
+        if self.override:
+            res.append(' override')
+        if self.initializer:
+            res.append(' = ')
+            res.append(self.initializer)
+        return u''.join(res)
+
+    def describe_signature(self, signode, mode, env):
+        _verify_description_mode(mode)
+        paramlist = addnodes.desc_parameterlist()
+        for arg in self.args:
+            param = addnodes.desc_parameter('', '', noemph=True)
+            if mode == 'lastIsName':  # i.e., outer-function params
+                arg.describe_signature(param, 'param', env)
+            else:
+                arg.describe_signature(param, 'markType', env)
+            paramlist += param
+        signode += paramlist
+
+        def _add_anno(signode, text):
+            signode += nodes.Text(' ')
+            signode += addnodes.desc_annotation(text, text)
+
+        def _add_text(signode, text):
+            signode += nodes.Text(' ' + text)
+
+        if self.volatile:
+            _add_anno(signode, 'volatile')
+        if self.const:
+            _add_anno(signode, 'const')
+        if self.refQual:
+            _add_text(signode, self.refQual)
+        if self.exceptionSpec:
+            _add_anno(signode, text_type(self.exceptionSpec))
+        if self.final:
+            _add_anno(signode, 'final')
+        if self.override:
+            _add_anno(signode, 'override')
+        if self.initializer:
+            _add_text(signode, '= ' + text_type(self.initializer))
 
 
-class NamedDefExpr(DefExpr):
-
-    def __init__(self, name, visibility, static):
-        self.name = name
+class ASTDeclSpecs(ASTBase):
+    def __init__(self, outer, visibility, storage, inline, virtual, explicit,
+                 constexpr, volatile, const, trailing):
+        self.outer = outer
         self.visibility = visibility
-        self.static = static
-
-    def get_name(self):
-        return self.name.get_name()
-
-    def get_modifiers(self, visibility='public'):
-        rv = []
-        if self.visibility != visibility:
-            rv.append(self.visibility)
-        if self.static:
-            rv.append(u'static')
-        return rv
-
-
-class TypeObjDefExpr(NamedDefExpr):
-
-    def __init__(self, name, visibility, static, typename, type_suffixes):
-        NamedDefExpr.__init__(self, name, visibility, static)
-        self.typename = typename
-        self.type_suffixes = type_suffixes
-
-    def get_id(self):
-        if self.typename is None:
-            buf = [self.name.get_id()]
-        else:
-            buf = [u'%s__%s' % (self.name.get_id(), self.typename.get_id())]
-        for suffix in self.type_suffixes:
-            buf.append(suffix.get_id_suffix())
-        return u''.join(buf)
-
-    def __unicode__(self):
-        buf = self.get_modifiers()
-        if self.typename is None:
-            buf.append(unicode(self.name))
-        else:
-            buf.extend(map(unicode, (self.typename, self.name)))
-        buf = [u' '.join(buf)]
-        for suffix in self.type_suffixes:
-            buf.append(unicode(suffix))
-        return u''.join(buf)
-
-
-class MemberObjDefExpr(NamedDefExpr):
-
-    def __init__(self, name, visibility, static, typename, type_suffixes,
-                 value):
-        NamedDefExpr.__init__(self, name, visibility, static)
-        self.typename = typename
-        self.type_suffixes = type_suffixes
-        self.value = value
-
-    def get_id(self):
-        buf = [u'%s__%s' % (self.name.get_id(), self.typename.get_id())]
-        for suffix in self.type_suffixes:
-            buf.append(suffix.get_id_suffix())
-        return u''.join(buf)
-
-    def __unicode__(self):
-        buf = self.get_modifiers()
-        buf.extend((unicode(self.typename), unicode(self.name)))
-        buf = [u' '.join(buf)]
-        for suffix in self.type_suffixes:
-            buf.append(unicode(suffix))
-        if self.value is not None:
-            buf.append(u' = %s' % self.value)
-        return u''.join(buf)
-
-
-class FuncDefExpr(NamedDefExpr):
-
-    def __init__(self, name, visibility, static, explicit, constexpr, rv,
-                 signature, **kwargs):
-        NamedDefExpr.__init__(self, name, visibility, static)
-        self.rv = rv
-        self.signature = signature
+        self.storage = storage
+        self.inline = inline
+        self.virtual = virtual
         self.explicit = explicit
         self.constexpr = constexpr
-        self.const = kwargs.get('const', False)
-        self.volatile = kwargs.get('volatile', False)
-        self.noexcept = kwargs.get('noexcept', False)
-        self.override = kwargs.get('override', False)
-        self.rvalue_this = kwargs.get('rvalue_this', False)
-        self.lvalue_this = kwargs.get('lvalue_this', False)
-        self.pure_virtual = kwargs.get('pure_virtual', False)
-        self.delete = kwargs.get('delete', False)
-        self.default = kwargs.get('default', False)
+        self.volatile = volatile
+        self.const = const
+        self.trailingTypeSpec = trailing
+
+    @property
+    def name(self):
+        return self.trailingTypeSpec.name
 
     def get_id(self):
-        return u'%s%s%s%s' % (
-            self.name.get_id(),
-            self.signature and u'__' +
-                u'.'.join(x.get_id() for x in self.signature) or u'',
-            self.const and u'C' or u'',
-            self.constexpr and 'CE' or ''
-        )
+        res = []
+        if self.volatile:
+            res.append('V')
+        if self.const:
+            res.append('K')
+        res.append(self.trailingTypeSpec.get_id())
+        return u''.join(res)
+
+    def _print_visibility(self):
+        return (self.visibility and
+                not (
+                    self.outer in ('type', 'member', 'function') and
+                    self.visibility == 'public'))
 
     def __unicode__(self):
-        buf = self.get_modifiers()
+        res = []
+        if self._print_visibility():
+            res.append(self.visibility)
+        if self.storage:
+            res.append(self.storage)
+        if self.inline:
+            res.append('inline')
+        if self.virtual:
+            res.append('virtual')
         if self.explicit:
-            buf.append(u'explicit')
+            res.append('explicit')
         if self.constexpr:
-            buf.append(u'constexpr')
-        if self.rv is not None:
-            buf.append(unicode(self.rv))
-        buf.append(u'%s(%s)' % (self.name, u', '.join(
-            map(unicode, self.signature))))
-        if self.const:
-            buf.append(u'const')
+            res.append('constexpr')
         if self.volatile:
-            buf.append(u'volatile')
-        if self.rvalue_this:
-            buf.append(u'&&')
-        if self.lvalue_this:
-            buf.append(u'&')
-        if self.noexcept:
-            buf.append(u'noexcept')
-        if self.override:
-            buf.append(u'override')
-        if self.pure_virtual:
-            buf.append(u'= 0')
-        if self.default:
-            buf.append(u'= default')
-        if self.delete:
-            buf.append(u'= delete')
-        return u' '.join(buf)
+            res.append('volatile')
+        if self.const:
+            res.append('const')
+        if self.trailingTypeSpec:
+            res.append(text_type(self.trailingTypeSpec))
+        return u' '.join(res)
+
+    def describe_signature(self, signode, mode, env):
+        _verify_description_mode(mode)
+        modifiers = []
+
+        def _add(modifiers, text):
+            if len(modifiers) > 0:
+                modifiers.append(nodes.Text(' '))
+            modifiers.append(addnodes.desc_annotation(text, text))
+
+        if self._print_visibility():
+            _add(modifiers, self.visibility)
+        if self.storage:
+            _add(modifiers, self.storage)
+        if self.inline:
+            _add(modifiers, 'inline')
+        if self.virtual:
+            _add(modifiers, 'virtual')
+        if self.explicit:
+            _add(modifiers, 'explicit')
+        if self.constexpr:
+            _add(modifiers, 'constexpr')
+        if self.volatile:
+            _add(modifiers, 'volatile')
+        if self.const:
+            _add(modifiers, 'const')
+        for m in modifiers:
+            signode += m
+        if self.trailingTypeSpec:
+            if len(modifiers) > 0:
+                signode += nodes.Text(' ')
+            self.trailingTypeSpec.describe_signature(signode, mode, env)
 
 
-class ClassDefExpr(NamedDefExpr):
+class ASTPtrOpPtr(ASTBase):
+    def __init__(self, volatile, const):
+        self.volatile = volatile
+        self.const = const
 
-    def __init__(self, name, visibility, static, bases):
-        NamedDefExpr.__init__(self, name, visibility, static)
+    def __unicode__(self):
+        res = ['*']
+        if self.volatile:
+            res.append('volatile ')
+        if self.const:
+            res.append('const ')
+        return u''.join(res)
+
+    def get_id(self):
+        res = ['P']
+        if self.volatile:
+            res.append('V')
+        if self.const:
+            res.append('C')
+        return u''.join(res)
+
+
+class ASTPtrOpRef(ASTBase):
+    def __unicode__(self):
+        return '&'
+
+    def get_id(self):
+        return 'R'
+
+
+class ASTPtrOpParamPack(ASTBase):
+    def __unicode__(self):
+        return '...'
+
+    def get_id(self):
+        return 'Dp'
+
+
+class ASTArray(ASTBase):
+    def __init__(self, size):
+        self.size = size
+
+    def __unicode__(self):
+        return u''.join(['[', text_type(self.size), ']'])
+
+    def get_id(self):
+        # TODO: this should maybe be done differently
+        return u'A' + text_type(self.size) + u'_'
+
+    def describe_signature(self, signode, mode, env):
+        _verify_description_mode(mode)
+        signode += nodes.Text(text_type(self))
+
+
+class ASTDeclerator(ASTBase):
+    def __init__(self, ptrOps, declId, suffixOps):
+        self.ptrOps = ptrOps
+        self.declId = declId
+        self.suffixOps = suffixOps
+
+    @property
+    def name(self):
+        return self.declId
+
+    def get_modifiers_id(self):  # only the modifiers for a function, e.g.,
+        # cv-qualifiers
+        for op in self.suffixOps:
+            if isinstance(op, ASTParametersQualifiers):
+                return op.get_modifiers_id()
+        raise Exception(
+            "This should only be called on a function: %s" % text_type(self))
+
+    def get_param_id(self):  # only the parameters (if any)
+        for op in self.suffixOps:
+            if isinstance(op, ASTParametersQualifiers):
+                return op.get_param_id()
+        return ''
+
+    def get_ptr_suffix_id(self):  # only the ptr ops and array specifiers
+        return u''.join(
+            a.get_id()
+            for a in self.ptrOps + self.suffixOps
+            if not isinstance(a, ASTParametersQualifiers))
+
+    def require_start_space(self):
+        if (len(self.ptrOps) > 0 and
+                isinstance(self.ptrOps[-1], ASTPtrOpParamPack)):
+            return False
+        else:
+            return self.declId != None
+
+    def __unicode__(self):
+        res = []
+        for op in self.ptrOps:
+            res.append(text_type(op))
+            if isinstance(op, ASTPtrOpParamPack) and self.declId:
+                res.append(' ')
+        if self.declId:
+            res.append(text_type(self.declId))
+        for op in self.suffixOps:
+            res.append(text_type(op))
+        return u''.join(res)
+
+    def describe_signature(self, signode, mode, env):
+        _verify_description_mode(mode)
+        for op in self.ptrOps:
+            signode += nodes.Text(text_type(op))
+            if isinstance(op, ASTPtrOpParamPack) and self.declId:
+                signode += nodes.Text(' ')
+        if self.declId:
+            self.declId.describe_signature(signode, mode, env)
+        for op in self.suffixOps:
+            op.describe_signature(signode, mode, env)
+
+
+class ASTInitializer(ASTBase):
+    def __init__(self, value):
+        self.value = value
+
+    def __unicode__(self):
+        return u''.join([' = ', text_type(self.value)])
+
+    def describe_signature(self, signode, mode):
+        _verify_description_mode(mode)
+        signode += nodes.Text(text_type(self))
+
+
+class ASTType(ASTBase):
+    def __init__(self, declSpecs, decl):
+        self.declSpecs = declSpecs
+        self.decl = decl
+        self.objectType = None
+
+    @property
+    def name(self):
+        name = self.decl.name
+        if not name:
+            name = self.declSpecs.name
+        return name
+
+    def get_id(self):
+        res = []
+        if self.objectType:  # needs the name
+            res.append(_id_prefix)
+            if self.objectType == 'function':  # also modifiers
+                res.append(self.decl.get_modifiers_id())
+                res.append(self.prefixedName.get_id())
+                res.append(self.decl.get_param_id())
+            elif self.objectType == 'type':  # just the name
+                res.append(self.prefixedName.get_id())
+            else:
+                print(self.objectType)
+                assert False
+        else:  # only type encoding
+            res.append(self.decl.get_ptr_suffix_id())
+            res.append(self.declSpecs.get_id())
+            res.append(self.decl.get_param_id())
+        return u''.join(res)
+
+    def __unicode__(self):
+        res = []
+        declSpecs = text_type(self.declSpecs)
+        res.append(declSpecs)
+        if self.decl.require_start_space() and len(declSpecs) > 0:
+            res.append(u' ')
+        res.append(text_type(self.decl))
+        return u''.join(res)
+
+    def describe_signature(self, signode, mode, env):
+        _verify_description_mode(mode)
+        self.declSpecs.describe_signature(signode, 'markType', env)
+        if (self.decl.require_start_space() and
+                    len(text_type(self.declSpecs)) > 0):
+            signode += nodes.Text(' ')
+        self.decl.describe_signature(signode, mode, env)
+
+
+class ASTTypeWithInit(ASTBase):
+    def __init__(self, type, init):
+        self.objectType = None
+        self.type = type
+        self.init = init
+
+    @property
+    def name(self):
+        return self.type.name
+
+    def get_id(self):
+        if self.objectType == 'member':
+            return _id_prefix + self.prefixedName.get_id()
+        else:
+            return self.type.get_id()
+
+    def __unicode__(self):
+        res = []
+        res.append(text_type(self.type))
+        if self.init:
+            res.append(text_type(self.init))
+        return u''.join(res)
+
+    def describe_signature(self, signode, mode, env):
+        _verify_description_mode(mode)
+        self.type.describe_signature(signode, mode, env)
+        if self.init:
+            self.init.describe_signature(signode, mode)
+
+
+class ASTBaseClass(ASTBase):
+    def __init__(self, name, visibility):
+        self.name = name
+        self.visibility = visibility
+
+    def __unicode__(self):
+        res = []
+        if self.visibility != 'private':
+            res.append(self.visibility)
+            res.append(' ')
+        res.append(text_type(self.name))
+        return u''.join(res)
+
+    def describe_signature(self, signode, mode, env):
+        _verify_description_mode(mode)
+        if self.visibility != 'private':
+            signode += addnodes.desc_annotation(
+                self.visibility, self.visibility)
+            signode += nodes.Text(' ')
+            self.name.describe_signature(signode, mode, env)
+
+
+class ASTClass(ASTBase):
+    def __init__(self, name, bases):
+        self.name = name
         self.bases = bases
 
     def get_id(self):
-        return self.name.get_id()
-
-    def _tostring(self, visibility='public'):
-        buf = self.get_modifiers(visibility)
-        buf.append(unicode(self.name))
-        if self.bases:
-            buf.append(u':')
-            buf.append(u', '.join(base._tostring('private')
-                                  for base in self.bases))
-        return u' '.join(buf)
+        return _id_prefix + self.prefixedName.get_id()
 
     def __unicode__(self):
-        return self._tostring('public')
+        res = []
+        res.append(text_type(self.name))
+        if len(self.bases) > 0:
+            res.append(' : ')
+            first = True
+            for b in self.bases:
+                if not first:
+                    res.append(', ')
+                first = False
+                res.append(text_type(b))
+        return u''.join(res)
+
+    def describe_signature(self, signode, mode, env):
+        _verify_description_mode(mode)
+        self.name.describe_signature(signode, mode, env)
+        if len(self.bases) > 0:
+            signode += nodes.Text(' : ')
+            for b in self.bases:
+                b.describe_signature(signode, mode, env)
+                signode += nodes.Text(', ')
+            signode.pop()
+
 
 class DefinitionParser(object):
+    # those without signedness and size modifiers
+    # see http://en.cppreference.com/w/cpp/language/types
+    _simple_fundemental_types = (
+        'void', 'bool', 'char', 'wchar_t', 'char16_t', 'char32_t', 'int',
+        'float', 'double', 'auto'
+    )
 
-    # mapping of valid type modifiers.  if the set is None it means
-    # the modifier can prefix all types, otherwise only the types
-    # (actually more keywords) in the set.  Also check
-    # _guess_typename when changing this.
-    _modifiers = {
-        'volatile':     None,
-        'register':     None,
-        'mutable':      None,
-        'const':        None,
-        'typename':     None,
-        'struct':       None,
-        'unsigned':     set(('char', 'short', 'int', 'long')),
-        'signed':       set(('char', 'short', 'int', 'long')),
-        'short':        set(('int',)),
-        'long':         set(('int', 'long', 'double'))
-    }
+    _prefix_keys = ('class', 'struct', 'union', 'typename')
 
     def __init__(self, definition):
         self.definition = definition.strip()
@@ -552,8 +1056,10 @@
         self._previous_state = (0, None)
 
     def fail(self, msg):
-        raise DefinitionError('Invalid definition: %s [error at %d]\n  %s' %
-            (msg, self.pos, self.definition))
+        indicator = '-' * self.pos + '^'
+        raise DefinitionError(
+            'Invalid definition: %s [error at %d]\n  %s\n  %s' %
+            (msg, self.pos, self.definition, indicator))
 
     def match(self, regex):
         match = regex.match(self.definition, self.pos)
@@ -602,369 +1108,6 @@
         if self.last_match is not None:
             return self.last_match.group()
 
-    def _parse_operator(self):
-        self.skip_ws()
-        # thank god, a regular operator definition
-        if self.match(_operator_re):
-            return NameDefExpr('operator' +
-                                _whitespace_re.sub('', self.matched_text))
-
-        # new/delete operator?
-        for allocop in 'new', 'delete':
-            if not self.skip_word(allocop):
-                continue
-            self.skip_ws()
-            if self.skip_string('['):
-                self.skip_ws()
-                if not self.skip_string(']'):
-                    self.fail('expected "]" for ' + allocop)
-                allocop += '[]'
-            return NameDefExpr('operator ' + allocop)
-
-        # oh well, looks like a cast operator definition.
-        # In that case, eat another type.
-        type = self._parse_type()
-        return CastOpDefExpr(type)
-
-    def _parse_name(self):
-        return self._parse_name_or_template_arg(False)
-
-    def _parse_name_or_template_arg(self, in_template):
-        if not self.match(_identifier_re):
-            if not in_template:
-                self.fail('expected name')
-            if not self.match(_template_arg_re):
-                self.fail('expected name or constant template argument')
-            return ConstantTemplateArgExpr(self.matched_text.strip())
-        identifier = self.matched_text
-
-        # strictly speaking, operators are not regular identifiers
-        # but because operator is a keyword, it might not be used
-        # for variable names anyways, so we can safely parse the
-        # operator here as identifier
-        if identifier == 'operator':
-            return self._parse_operator()
-
-        return NameDefExpr(identifier)
-
-    def _guess_typename(self, path):
-        if not path:
-            return [], 'int'
-        # for the long type, we don't want the int in there
-        if 'long' in path:
-            path = [x for x in path if x != 'int']
-            # remove one long
-            path.remove('long')
-            return path, 'long'
-        if path[-1] in ('int', 'char'):
-            return path[:-1], path[-1]
-        return path, 'int'
-
-    def _attach_crefptr(self, expr, is_const=False):
-        if is_const:
-            expr = ConstDefExpr(expr, prefix=True)
-        while 1:
-            self.skip_ws()
-            if self.skip_word('const'):
-                expr = ConstDefExpr(expr)
-            elif self.skip_string('*'):
-                expr = PtrDefExpr(expr)
-            elif self.skip_string('&'):
-                if self.skip_string('&'):
-                    expr = RValRefDefExpr(expr)
-                else:
-                    expr = LValRefDefExpr(expr)
-            else:
-                return expr
-
-    def _try_parse_type_suffixes(self):
-        rv = []
-        while self.match(_array_def_re):
-            rv.append(ArrayTypeSuffixDefExpr(self.last_match.group(1)))
-            self.skip_ws()
-        return rv
-
-    def _peek_const(self, path):
-        try:
-            path.remove('const')
-            return True
-        except ValueError:
-            return False
-
-    def _parse_builtin(self, modifiers):
-        modifier = modifiers[-1]
-        path = modifiers
-        following = self._modifiers[modifier]
-        while 1:
-            self.skip_ws()
-            if not self.match(_identifier_re):
-                break
-            identifier = self.matched_text
-            if identifier in following:
-                path.append(identifier)
-                following = self._modifiers[modifier]
-                assert following
-            else:
-                self.backout()
-                break
-
-        is_const = self._peek_const(path)
-        modifiers, typename = self._guess_typename(path)
-        rv = ModifierDefExpr(NameDefExpr(typename), modifiers)
-        return self._attach_crefptr(rv, is_const)
-
-    def _parse_type_expr(self, in_template=False):
-        typename = self._parse_name_or_template_arg(in_template)
-        self.skip_ws()
-        if not self.skip_string('<'):
-            return typename
-
-        args = []
-        while 1:
-            self.skip_ws()
-            if self.skip_string('>'):
-                break
-            if args:
-                if not self.skip_string(','):
-                    self.fail('"," or ">" in template expected')
-                self.skip_ws()
-            args.append(self._parse_type(True))
-        return TemplateDefExpr(typename, args)
-
-    def _parse_type(self, in_template=False):
-        self.skip_ws()
-        result = []
-        modifiers = []
-
-        # if there is a leading :: or not, we don't care because we
-        # treat them exactly the same.  Buf *if* there is one, we
-        # don't have to check for type modifiers
-        if not self.skip_string('::'):
-            self.skip_ws()
-            while self.match(_identifier_re):
-                modifier = self.matched_text
-                if modifier in self._modifiers:
-                    following = self._modifiers[modifier]
-                    # if the set is not none, there is a limited set
-                    # of types that might follow.  It is technically
-                    # impossible for a template to follow, so what
-                    # we do is go to a different function that just
-                    # eats types
-                    modifiers.append(modifier)
-                    if following is not None:
-                        return self._parse_builtin(modifiers)
-                    self.skip_ws()
-                else:
-                    self.backout()
-                    break
-
-        while 1:
-            self.skip_ws()
-            if (in_template and self.current_char in ',>') or \
-               (result and not self.skip_string('::')) or \
-               self.eof:
-                break
-            result.append(self._parse_type_expr(in_template))
-
-        if not result:
-            self.fail('expected type')
-        if len(result) == 1:
-            rv = result[0]
-        else:
-            rv = PathDefExpr(result)
-        is_const = self._peek_const(modifiers)
-        if modifiers:
-            rv = ModifierDefExpr(rv, modifiers)
-        return self._attach_crefptr(rv, is_const)
-
-    def _parse_default_expr(self):
-        self.skip_ws()
-        if self.match(_string_re):
-            return self.matched_text
-        paren_stack_depth = 0
-        max_pos = len(self.definition)
-        rv_start = self.pos
-        while 1:
-            idx0 = self.definition.find('(', self.pos)
-            idx1 = self.definition.find(',', self.pos)
-            idx2 = self.definition.find(')', self.pos)
-            if idx0 < 0:
-                idx0 = max_pos
-            if idx1 < 0:
-                idx1 = max_pos
-            if idx2 < 0:
-                idx2 = max_pos
-            idx = min(idx0, idx1, idx2)
-            if idx >= max_pos:
-                self.fail('unexpected end in default expression')
-            if idx == idx0:
-                paren_stack_depth += 1
-            elif idx == idx2:
-                paren_stack_depth -= 1
-                if paren_stack_depth < 0:
-                    break
-            elif paren_stack_depth == 0:
-                break
-            self.pos = idx+1
-
-        rv = self.definition[rv_start:idx]
-        self.pos = idx
-        return rv
-
-    def _parse_signature(self):
-        self.skip_ws()
-        if not self.skip_string('('):
-            self.fail('expected parentheses for function')
-
-        args = []
-        while 1:
-            self.skip_ws()
-            if self.eof:
-                self.fail('missing closing parentheses')
-            if self.skip_string(')'):
-                break
-            if args:
-                if not self.skip_string(','):
-                    self.fail('expected comma between arguments')
-                self.skip_ws()
-
-            if self.skip_string('...'):
-                args.append(ArgumentDefExpr(None, '...', [], None))
-                if self.skip_string(')'):
-                    break
-                else:
-                    self.fail('expected closing parenthesis after ellipses')
-
-            argname = default = None
-            argtype = self._parse_type()
-            self.skip_ws()
-            type_suffixes = self._try_parse_type_suffixes()
-            if self.skip_string('='):
-                default = self._parse_default_expr()
-            elif self.current_char not in ',)':
-                argname = self._parse_name()
-                self.skip_ws()
-                type_suffixes.extend(self._try_parse_type_suffixes())
-                if self.skip_string('='):
-                    default = self._parse_default_expr()
-            if argname is None:
-                argname = argtype
-                argtype = None
-
-            args.append(ArgumentDefExpr(argtype, argname,
-                                        type_suffixes, default))
-        self.skip_ws()
-        attributes = dict(
-            signature=args,
-            const=self.skip_word_and_ws('const'),
-            volatile=self.skip_word_and_ws('volatile'),
-            noexcept=self.skip_word_and_ws('noexcept'),
-            override=self.skip_word_and_ws('override'),
-            pure_virtual=False,
-            lvalue_this=False,
-            rvalue_this=False,
-            delete=False,
-            default=False)
-
-        if self.skip_string('&&'):
-            attributes['rvalue_this'] = True
-        if self.skip_string('&'):
-            attributes['lvalue_this'] = True
-
-        if attributes['lvalue_this'] and attributes['rvalue_this']:
-            self.fail('rvalue reference for *this specifier must be one of'
-                      '"&&" or "&"')
-
-        if self.skip_string('='):
-            self.skip_ws()
-            if self.skip_string('0'):
-                attributes['pure_virtual'] = True
-                return attributes
-            if self.skip_word('NULL') or self.skip_word('nullptr'):
-                attributes['pure_virtual'] = True
-                return attributes
-            if self.skip_word('delete'):
-                attributes['delete'] = True
-                return attributes
-            if self.skip_word('default'):
-                attributes['default'] = True
-                return attributes
-
-            self.fail('functions must be defined with '
-                      'either 0, NULL, nullptr, default or delete, other'
-                      'macros are not allowed')
-        return attributes
-
-    def _parse_visibility_static(self):
-        visibility = 'public'
-        if self.match(_visibility_re):
-            visibility = self.matched_text
-        static = self.skip_word_and_ws('static')
-        return visibility, static
-
-    def parse_type(self):
-        return self._parse_type()
-
-    def parse_type_object(self):
-        visibility, static = self._parse_visibility_static()
-        typename = self._parse_type()
-        self.skip_ws()
-        if not self.eof:
-            name = self._parse_type()
-            type_suffixes = self._try_parse_type_suffixes()
-        else:
-            name = typename
-            typename = None
-            type_suffixes = []
-        return TypeObjDefExpr(name, visibility, static, typename, type_suffixes)
-
-    def parse_member_object(self):
-        visibility, static = self._parse_visibility_static()
-        typename = self._parse_type()
-        name = self._parse_type()
-        type_suffixes = self._try_parse_type_suffixes()
-        self.skip_ws()
-        if self.skip_string('='):
-            value = self.read_rest().strip()
-        else:
-            value = None
-        return MemberObjDefExpr(name, visibility, static, typename,
-                                type_suffixes, value)
-
-    def parse_function(self):
-        visibility, static = self._parse_visibility_static()
-        explicit = self.skip_word_and_ws('explicit')
-        constexpr = self.skip_word_and_ws('constexpr')
-
-        rv = self._parse_type()
-        self.skip_ws()
-        # some things just don't have return values
-        if self.current_char == '(':
-            name = rv
-            rv = None
-        else:
-            name = self._parse_type()
-        return FuncDefExpr(name, visibility, static, explicit, constexpr, rv,
-                           **self._parse_signature())
-
-    def parse_class(self):
-        visibility, static = self._parse_visibility_static()
-        name = self._parse_type()
-        bases = []
-        if self.skip_string(':'):
-            self.skip_ws()
-            while 1:
-                access = 'private'
-                if self.match(_visibility_re):
-                    access = self.matched_text
-                base = self._parse_type()
-                bases.append(ClassDefExpr(base, access, False, []))
-                if self.skip_string(','):
-                    self.skip_ws()
-                else:
-                    break
-        return ClassDefExpr(name, visibility, static, bases)
-
     def read_rest(self):
         rv = self.definition[self.pos:]
         self.pos = self.end
@@ -976,6 +1119,518 @@
             self.fail('expected end of definition, got %r' %
                       self.definition[self.pos:])
 
+    def _parse_operator(self):
+        self.skip_ws()
+        # adapted from the old code
+        # thank god, a regular operator definition
+        if self.match(_operator_re):
+            return ASTOperatorBuildIn(self.matched_text)
+
+        # new/delete operator?
+        for op in 'new', 'delete':
+            if not self.skip_word(op):
+                continue
+            self.skip_ws()
+            if self.skip_string('['):
+                self.skip_ws()
+                if not self.skip_string(']'):
+                    self.fail('Expected "]" after  "operator ' + op + '["')
+                op += '[]'
+            return ASTOperatorBuildIn(op)
+
+        # oh well, looks like a cast operator definition.
+        # In that case, eat another type.
+        type = self._parse_type()
+        return ASTOperatorType(type)
+
+    def _parse_nested_name(self):
+        names = []
+
+        self.skip_ws()
+        if self.skip_string('::'):
+            names.append(u'')
+        while 1:
+            self.skip_ws()
+            # TODO: parse the "template" keyword
+            if not self.match(_identifier_re):
+                self.fail("expected identifier")
+            identifier = self.matched_text
+            if identifier == 'operator':
+                op = self._parse_operator()
+                names.append(op)
+            else:
+                templateArgs = None
+                self.skip_ws()
+                if self.skip_string('<'):
+                    templateArgs = []
+                    while 1:
+                        pos = self.pos
+                        try:
+                            type = self._parse_type(allowParams=True)
+                            templateArgs.append(type)
+                        except DefinitionError:
+                            self.pos = pos
+                            symbols = []
+                            startPos = self.pos
+                            self.skip_ws()
+                            if self.match(_string_re):
+                                value = self.matched_text
+                            else:
+                                while not self.eof:
+                                    if (len(symbols) == 0 and
+                                                self.current_char in (
+                                            ',', '>')):
+                                        break
+                                    # TODO: actually implement nice handling
+                                    # of quotes, braces, brackets, parens, and
+                                    # whatever
+                                    self.pos += 1
+                                if self.eof:
+                                    self.pos = startPos
+                                    self.fail(
+                                        'Could not find end of constant '
+                                        'template argument.')
+                                value = self.definition[
+                                        startPos:self.pos].strip()
+                            templateArgs.append(ASTTemplateArgConstant(value))
+                        self.skip_ws()
+                        if self.skip_string('>'):
+                            break
+                        elif self.skip_string(','):
+                            continue
+                        else:
+                            self.fail('Expected ">" or "," in template '
+                                      'argument list.')
+                names.append(ASTNestedNameElement(identifier, templateArgs))
+
+            self.skip_ws()
+            if not self.skip_string('::'):
+                break
+        return ASTNestedName(names)
+
+    def _parse_trailing_type_spec(self):
+        # fundemental types
+        self.skip_ws()
+        for t in self._simple_fundemental_types:
+            if self.skip_word(t):
+                return ASTTrailingTypeSpecFundamental(t)
+
+        # TODO: this could/should be more strict
+        elements = []
+        self.skip_ws()
+        if self.skip_word_and_ws('signed'):
+            elements.append('signed')
+        elif self.skip_word_and_ws('unsigned'):
+            elements.append('unsigned')
+        while 1:
+            if self.skip_word_and_ws('short'):
+                elements.append('short')
+            elif self.skip_word_and_ws('long'):
+                elements.append('long')
+            else:
+                break
+        if self.skip_word_and_ws('int'):
+            elements.append('int')
+        elif self.skip_word_and_ws('double'):
+            elements.append('double')
+        if len(elements) > 0:
+            return ASTTrailingTypeSpecFundamental(u' '.join(elements))
+
+        # decltype
+        self.skip_ws()
+        if self.skip_word_and_ws('decltype'):
+            self.fail('"decltype(.)" in trailing_type_spec not implemented')
+
+        # prefixed
+        prefix = None
+        self.skip_ws()
+        for k in self._prefix_keys:
+            if self.skip_word_and_ws(k):
+                prefix = k
+                break
+
+        nestedName = self._parse_nested_name()
+        return ASTTrailingTypeSpecName(prefix, nestedName)
+
+    def _parse_parameters_and_qualifiers(self, paramMode):
+        self.skip_ws()
+        if not self.skip_string('('):
+            if paramMode == 'function':
+                self.fail('Expecting "(" in parameters_and_qualifiers.')
+            else:
+                return None
+        args = []
+        self.skip_ws()
+        if not self.skip_string(')'):
+            while 1:
+                self.skip_ws()
+                if self.skip_string('...'):
+                    args.append(ASTFunctinoParameter(None, True))
+                    self.skip_ws()
+                    if not self.skip_string(')'):
+                        self.fail('Expected ")" after "..." in '
+                                  'parameters_and_qualifiers.')
+                    break
+                if paramMode == 'function':
+                    arg = self._parse_type_with_init(named='maybe')
+                else:
+                    arg = self._parse_type()
+                # TODO: parse default parameters
+                args.append(ASTFunctinoParameter(arg))
+
+                self.skip_ws()
+                if self.skip_string(','):
+                    continue
+                elif self.skip_string(')'):
+                    break
+                else:
+                    self.fail(
+                        'Expecting "," or ")" in parameters_and_qualifiers, '
+                        'got "%s".' % self.current_char)
+
+        if paramMode != 'function':
+            return ASTParametersQualifiers(
+                args, None, None, None, None, None, None, None)
+
+        self.skip_ws()
+        const = self.skip_word_and_ws('const')
+        volatile = self.skip_word_and_ws('volatile')
+        if not const:  # the can be permuted
+            const = self.skip_word_and_ws('const')
+
+        refQual = None
+        if self.skip_string('&&'):
+            refQual = '&&'
+        if not refQual and self.skip_string('&'):
+            refQual = '&'
+
+        exceptionSpec = None
+        override = None
+        final = None
+        initializer = None
+        self.skip_ws()
+        if self.skip_string('noexcept'):
+            exceptionSpec = 'noexcept'
+            self.skip_ws()
+            if self.skip_string('('):
+                self.fail('Parameterised "noexcept" not implemented.')
+
+        self.skip_ws()
+        override = self.skip_word_and_ws('override')
+        final = self.skip_word_and_ws('final')
+        if not override:
+            override = self.skip_word_and_ws(
+                'override')  # they can be permuted
+
+        self.skip_ws()
+        if self.skip_string('='):
+            self.skip_ws()
+            valid = ('0', 'delete', 'default')
+            for w in valid:
+                if self.skip_word_and_ws(w):
+                    initializer = w
+                    break
+            if not initializer:
+                self.fail(
+                    'Expected "%s" in initializer-specifier.'
+                    % u'" or "'.join(valid))
+
+        return ASTParametersQualifiers(
+            args, volatile, const, refQual, exceptionSpec, override, final,
+            initializer)
+
+    def _parse_decl_specs(self, outer, typed=True):
+        """
+        visibility storage-class-specifier function-specifier "constexpr"
+        "volatile" "const" trailing-type-specifier
+
+        storage-class-specifier -> "static" (only for member_object and
+        function_object)
+
+        function-specifier -> "inline" | "virtual" | "explicit" (only for
+        function_object)
+
+        "constexpr" (only for member_object and function_object)
+        """
+        visibility = None
+        storage = None
+        inline = None
+        virtual = None
+        explicit = None
+        constexpr = None
+        volatile = None
+        const = None
+
+        if outer:
+            self.skip_ws()
+            if self.match(_visibility_re):
+                visibility = self.matched_text
+
+        while 1:  # accept any permutation of a subset of some decl-specs
+            self.skip_ws()
+            if not storage:
+                if outer in ('member', 'function'):
+                    if self.skip_word('static'):
+                        storage = 'static'
+                        continue
+                if outer == 'member':
+                    if self.skip_word('mutable'):
+                        storage = 'mutable'
+                        continue
+                if outer == 'fuction':
+                    # TODO: maybe in more contexts, missing test cases
+                    if self.skip_word('register'):
+                        storage = 'register'
+                        continue
+
+            if outer == 'function':
+                # function-specifiers
+                if not inline:
+                    inline = self.skip_word('inline')
+                    if inline:
+                        continue
+                if not virtual:
+                    virtual = self.skip_word('virtual')
+                    if virtual:
+                        continue
+                if not explicit:
+                    explicit = self.skip_word('explicit')
+                    if explicit:
+                        continue
+
+            if not constexpr and outer in ('member', 'function'):
+                constexpr = self.skip_word("constexpr")
+                if constexpr:
+                    continue
+            if not volatile and typed:
+                volatile = self.skip_word('volatile')
+                if volatile:
+                    continue
+            if not const and typed:
+                const = self.skip_word('const')
+                if const:
+                    continue
+            break
+
+        if typed:
+            trailing = self._parse_trailing_type_spec()
+        else:
+            trailing = None
+        return ASTDeclSpecs(
+            outer, visibility, storage, inline, virtual, explicit, constexpr,
+            volatile, const, trailing)
+
+    def _parse_declerator(self, named, paramMode=None, typed=True):
+        if paramMode:
+            if not paramMode in ('type', 'function'):
+                raise Exception(
+                    "Internal error, unknown paramMode '%s'." % paramMode)
+        ptrOps = []
+        while 1:
+            if not typed:
+                break
+            self.skip_ws()
+            if self.skip_string('*'):
+                self.skip_ws()
+                volatile = self.skip_word_and_ws('volatile')
+                const = self.skip_word_and_ws('const')
+                ptrOps.append(ASTPtrOpPtr(volatile=volatile, const=const))
+            elif self.skip_string('&'):
+                ptrOps.append(ASTPtrOpRef())
+            elif self.skip_string('...'):
+                ptrOps.append(ASTPtrOpParamPack())
+                break
+            else:
+                break
+
+        if named == 'maybe':
+            try:
+                declId = self._parse_nested_name()
+            except DefinitionError:
+                declId = None
+        elif named:
+            declId = self._parse_nested_name()
+        else:
+            declId = None
+
+        suffixOpts = []
+        while 1:
+            self.skip_ws()
+            if typed and self.skip_string('['):
+                startPos = self.pos - 1
+                openCount = 1
+                while not self.eof:
+                    c = self.current_char
+                    if c == '[':
+                        openCount += 1
+                    elif c == ']':
+                        openCount -= 1
+                    if openCount == 0:
+                        break
+                    self.pos += 1
+                if self.eof:
+                    self.pos = startPos
+                    self.fail(
+                        "Could not find closing square bracket for array.")
+                self.pos += 1
+                suffixOpts.append(ASTArray(
+                    self.definition[startPos + 1:self.pos - 1].strip()))
+                continue
+            if paramMode:
+                paramQual = self._parse_parameters_and_qualifiers(paramMode)
+                if paramQual:
+                    suffixOpts.append(paramQual)
+            break
+
+        return ASTDeclerator(ptrOps, declId, suffixOpts)
+
+    def _parse_initializer(self, outer=None):
+        self.skip_ws()
+        # TODO: support paren and brace initialization for memberObject
+        if not self.skip_string('='):
+            return None
+        else:
+            if outer == 'member':
+                value = self.read_rest().strip()
+                return ASTInitializer(value)
+            elif outer == None:  # function parameter
+                symbols = []
+                startPos = self.pos
+                self.skip_ws()
+                if self.match(_string_re):
+                    value = self.matched_text
+                    return ASTInitializer(value)
+                while not self.eof:
+                    if len(symbols) == 0 and self.current_char in (',', ')'):
+                        break
+                    elif len(symbols) > 0 and self.current_char == symbols[-1]:
+                        symbols.pop()
+                    elif self.current_char == '(':
+                        symbols.append(')')
+                    # TODO: actually implement nice handling of quotes, braces,
+                    # brackets, parens, and whatever
+                    self.pos += 1
+                if self.eof:
+                    self.pos = startPos
+                    self.fail(
+                        'Could not find end of default value for function '
+                        'parameter.')
+                value = self.definition[startPos:self.pos].strip()
+                return ASTInitializer(value)
+            else:
+                self.fail(
+                    "Internal error, initializer for outer '%s' not "
+                    "implemented." % outer)
+
+    def _parse_type(self, outer=None, named=False, allowParams=False):
+        """
+        named=False|'maybe'|True: 'maybe' is e.g., for function objects which
+        doesn't need to name the arguments
+        """
+        if outer:  # always named
+            if not outer in ('type', 'member', 'function'):
+                raise Exception('Internal error, unknown outer "%s".' % outer)
+            assert not named
+
+        if outer in ('type', 'function'):
+            # We allow type objects to just be a name.
+            # Some functions don't have normal return types: constructors,
+            # destrutors, cast operators
+            startPos = self.pos
+            # first try without the type
+            try:
+                declSpecs = self._parse_decl_specs(outer=outer, typed=False)
+                decl = self._parse_declerator(named=True, paramMode=outer,
+                                              typed=False)
+                self.assert_end()
+            except DefinitionError as exUntyped:
+                self.pos = startPos
+                try:
+                    declSpecs = self._parse_decl_specs(outer=outer)
+                    decl = self._parse_declerator(named=True, paramMode=outer)
+                except DefinitionError as exTyped:
+                    if outer == 'type':
+                        raise DefinitionError(
+                            'Type must be either just a name or a '
+                            'typedef-like declaration.\nJust a name error: '
+                            '%s\nTypedef-like expression error: %s'
+                            % (exUntyped.description, exTyped.description))
+                    else:
+                        # do it again to get the proper traceback (how do you
+                        # relieable save a traceback when an exception is
+                        # constructed?)
+                        self.pos = startPos
+                        declSpecs = self._parse_decl_specs(outer=outer)
+                        decl = self._parse_declerator(named=True,
+                                                      paramMode=outer)
+        else:
+            if outer:
+                named = True
+                allowParams = True
+            if allowParams:
+                paramMode = 'type'
+            else:
+                paramMode = None
+            declSpecs = self._parse_decl_specs(outer=outer)
+            decl = self._parse_declerator(named=named, paramMode=paramMode)
+        return ASTType(declSpecs, decl)
+
+    def _parse_type_with_init(self, outer=None, named=False):
+        if outer:
+            assert outer in ('type', 'member', 'function')
+        type = self._parse_type(outer=outer, named=named)
+        init = self._parse_initializer(outer=outer)
+        return ASTTypeWithInit(type, init)
+
+    def _parse_class(self):
+        name = self._parse_nested_name()
+        bases = []
+        self.skip_ws()
+        if self.skip_string(':'):
+            while 1:
+                self.skip_ws()
+                visibility = 'private'
+                if self.match(_visibility_re):
+                    visibility = self.matched_text
+                baseName = self._parse_nested_name()
+                bases.append(ASTBaseClass(baseName, visibility))
+                self.skip_ws()
+                if self.skip_string(','):
+                    continue
+                else:
+                    break
+        return ASTClass(name, bases)
+
+    def parse_type_object(self):
+        res = self._parse_type(outer='type')
+        res.objectType = 'type'
+        return res
+
+    def parse_member_object(self):
+        res = self._parse_type_with_init(outer='member')
+        res.objectType = 'member'
+        return res
+
+    def parse_function_object(self):
+        res = self._parse_type(outer='function')
+        res.objectType = 'function'
+        return res
+
+    def parse_class_object(self):
+        res = self._parse_class()
+        res.objectType = 'class'
+        return res
+
+    def parse_namespace_object(self):
+        res = self._parse_nested_name()
+        res.objectType = 'namespace'
+        return res
+
+    def parse_xref_object(self):
+        res = self._parse_nested_name()
+        res.objectType = 'xref'
+        return res
+
 
 class CPPObject(ObjectDescription):
     """Description of a C++ language object."""
@@ -991,214 +1646,120 @@
               names=('returns', 'return')),
     ]
 
-    def attach_name(self, node, name):
-        owner, name = name.split_owner()
-        varname = unicode(name)
-        if owner is not None:
-            owner = unicode(owner) + '::'
-            node += addnodes.desc_addname(owner, owner)
-        node += addnodes.desc_name(varname, varname)
-
-    def attach_type_suffixes(self, node, suffixes):
-        for suffix in suffixes:
-            node += nodes.Text(unicode(suffix))
-
-    def attach_type(self, node, type):
-        # XXX: link to c?
-        text = unicode(type)
-        pnode = addnodes.pending_xref(
-            '', refdomain='cpp', reftype='type',
-            reftarget=text, modname=None, classname=None)
-        pnode['cpp:parent'] = self.env.temp_data.get('cpp:parent')
-        pnode += nodes.Text(text)
-        node += pnode
-
-    def attach_modifiers(self, node, obj, visibility='public'):
-        if obj.visibility != visibility:
-            node += addnodes.desc_annotation(obj.visibility,
-                                             obj.visibility)
-            node += nodes.Text(' ')
-        if obj.static:
-            node += addnodes.desc_annotation('static', 'static')
-            node += nodes.Text(' ')
-        if getattr(obj, 'constexpr', False):
-            node += addnodes.desc_annotation('constexpr', 'constexpr')
-            node += nodes.Text(' ')
-
-    def add_target_and_index(self, sigobj, sig, signode):
-        theid = sigobj.get_id()
-        name = unicode(sigobj.name)
+    def add_target_and_index(self, ast, sig, signode):
+        theid = ast.get_id()
+        name = text_type(ast.prefixedName)
         if theid not in self.state.document.ids:
-            signode['names'].append(theid)
+            # the name is not unique, the first one will win
+            objects = self.env.domaindata['cpp']['objects']
+            if not name in objects:
+                signode['names'].append(name)
             signode['ids'].append(theid)
             signode['first'] = (not self.names)
             self.state.document.note_explicit_target(signode)
-
-            self.env.domaindata['cpp']['objects'].setdefault(name,
-                (self.env.docname, self.objtype, theid))
+            if not name in objects:
+                objects.setdefault(name,
+                                   (self.env.docname, ast.objectType, theid))
+                # add the uninstantiated template if it doesn't exist
+                uninstantiated = ast.prefixedName.get_name_no_last_template()
+                if uninstantiated != name and uninstantiated not in objects:
+                    signode['names'].append(uninstantiated)
+                    objects.setdefault(uninstantiated, (
+                    self.env.docname, ast.objectType, theid))
+            self.env.temp_data['cpp:lastname'] = ast.prefixedName
 
         indextext = self.get_index_text(name)
-        if indextext:
-            self.indexnode['entries'].append(('single', indextext, theid, ''))
-
-    def before_content(self):
-        lastname = self.names and self.names[-1]
-        if lastname and not self.env.temp_data.get('cpp:parent'):
-            assert isinstance(lastname, NamedDefExpr)
-            self.env.temp_data['cpp:parent'] = lastname.name
-            self.parentname_set = True
-        else:
-            self.parentname_set = False
-
-    def after_content(self):
-        if self.parentname_set:
-            self.env.temp_data['cpp:parent'] = None
+        if not re.compile(r'^[a-zA-Z0-9_]*$').match(theid):
+            self.state_machine.reporter.warning(
+                'Index id generation for C++ object "%s" failed, please '
+                'report as bug (id=%s).' % (text_type(ast), theid),
+                line=self.lineno)
+        self.indexnode['entries'].append(('single', indextext, theid, ''))
 
     def parse_definition(self, parser):
         raise NotImplementedError()
 
-    def describe_signature(self, signode, arg):
+    def describe_signature(self, signode, ast):
         raise NotImplementedError()
 
     def handle_signature(self, sig, signode):
         parser = DefinitionParser(sig)
         try:
-            rv = self.parse_definition(parser)
+            ast = self.parse_definition(parser)
             parser.assert_end()
-        except DefinitionError, e:
-            self.state_machine.reporter.warning(e.description, line=self.lineno)
+        except DefinitionError as e:
+            self.state_machine.reporter.warning(e.description,
+                                                line=self.lineno)
             raise ValueError
-        self.describe_signature(signode, rv)
+        self.describe_signature(signode, ast)
 
         parent = self.env.temp_data.get('cpp:parent')
-        if parent is not None:
-            rv = rv.clone()
-            rv.name = rv.name.prefix(parent)
-        return rv
-
-
-class CPPClassObject(CPPObject):
-
-    def get_index_text(self, name):
-        return _('%s (C++ class)') % name
-
-    def parse_definition(self, parser):
-        return parser.parse_class()
-
-    def describe_signature(self, signode, cls):
-        self.attach_modifiers(signode, cls)
-        signode += addnodes.desc_annotation('class ', 'class ')
-        self.attach_name(signode, cls.name)
-        if cls.bases:
-            signode += nodes.Text(' : ')
-            for base in cls.bases:
-                self.attach_modifiers(signode, base, 'private')
-                signode += nodes.emphasis(unicode(base.name),
-                                          unicode(base.name))
-                signode += nodes.Text(', ')
-            signode.pop()  # remove the trailing comma
+        if parent and len(parent) > 0:
+            ast = ast.clone()
+            ast.prefixedName = ast.name.prefix_nested_name(parent[-1])
+        else:
+            ast.prefixedName = ast.name
+        return ast
 
 
 class CPPTypeObject(CPPObject):
-
     def get_index_text(self, name):
-        if self.objtype == 'type':
-            return _('%s (C++ type)') % name
-        return ''
+        return _('%s (C++ type)') % name
 
     def parse_definition(self, parser):
         return parser.parse_type_object()
 
-    def describe_signature(self, signode, obj):
-        self.attach_modifiers(signode, obj)
+    def describe_signature(self, signode, ast):
         signode += addnodes.desc_annotation('type ', 'type ')
-        if obj.typename is not None:
-            self.attach_type(signode, obj.typename)
-            signode += nodes.Text(' ')
-        self.attach_name(signode, obj.name)
-        self.attach_type_suffixes(signode, obj.type_suffixes)
+        ast.describe_signature(signode, 'lastIsName', self.env)
 
 
 class CPPMemberObject(CPPObject):
-
     def get_index_text(self, name):
-        if self.objtype == 'member':
-            return _('%s (C++ member)') % name
-        return ''
+        return _('%s (C++ member)') % name
 
     def parse_definition(self, parser):
         return parser.parse_member_object()
 
-    def describe_signature(self, signode, obj):
-        self.attach_modifiers(signode, obj)
-        self.attach_type(signode, obj.typename)
-        signode += nodes.Text(' ')
-        self.attach_name(signode, obj.name)
-        self.attach_type_suffixes(signode, obj.type_suffixes)
-        if obj.value is not None:
-            signode += nodes.Text(u' = ' + obj.value)
+    def describe_signature(self, signode, ast):
+        ast.describe_signature(signode, 'lastIsName', self.env)
 
 
 class CPPFunctionObject(CPPObject):
-
-    def attach_function(self, node, func):
-        owner, name = func.name.split_owner()
-        if owner is not None:
-            owner = unicode(owner) + '::'
-            node += addnodes.desc_addname(owner, owner)
-
-        # cast operator is special.  in this case the return value
-        # is reversed.
-        if isinstance(name, CastOpDefExpr):
-            node += addnodes.desc_name('operator', 'operator')
-            node += nodes.Text(u' ')
-            self.attach_type(node, name.typename)
-        else:
-            funcname = unicode(name)
-            node += addnodes.desc_name(funcname, funcname)
-
-        paramlist = addnodes.desc_parameterlist()
-        for arg in func.signature:
-            param = addnodes.desc_parameter('', '', noemph=True)
-            if arg.type is not None:
-                self.attach_type(param, arg.type)
-                param += nodes.Text(u' ')
-            param += nodes.emphasis(unicode(arg.name), unicode(arg.name))
-            self.attach_type_suffixes(param, arg.type_suffixes)
-            if arg.default is not None:
-                def_ = u'=' + unicode(arg.default)
-                param += nodes.emphasis(def_, def_)
-            paramlist += param
-
-        node += paramlist
-        if func.const:
-            node += addnodes.desc_addname(' const', ' const')
-        if func.noexcept:
-            node += addnodes.desc_addname(' noexcept', ' noexcept')
-        if func.pure_virtual:
-            node += addnodes.desc_addname(' = 0', ' = 0')
-
     def get_index_text(self, name):
         return _('%s (C++ function)') % name
 
     def parse_definition(self, parser):
-        return parser.parse_function()
+        return parser.parse_function_object()
 
-    def describe_signature(self, signode, func):
-        self.attach_modifiers(signode, func)
-        if func.explicit:
-            signode += addnodes.desc_annotation('explicit', 'explicit')
-            signode += nodes.Text(' ')
-        # return value is None for things with a reverse return value
-        # such as casting operator definitions or constructors
-        # and destructors.
-        if func.rv is not None:
-            self.attach_type(signode, func.rv)
-        signode += nodes.Text(u' ')
-        self.attach_function(signode, func)
+    def describe_signature(self, signode, ast):
+        ast.describe_signature(signode, 'lastIsName', self.env)
 
 
-class CPPCurrentNamespace(Directive):
+class CPPClassObject(CPPObject):
+    def get_index_text(self, name):
+        return _('%s (C++ class)') % name
+
+    def before_content(self):
+        lastname = self.env.temp_data['cpp:lastname']
+        assert lastname
+        if 'cpp:parent' in self.env.temp_data:
+            self.env.temp_data['cpp:parent'].append(lastname)
+        else:
+            self.env.temp_data['cpp:parent'] = [lastname]
+
+    def after_content(self):
+        self.env.temp_data['cpp:parent'].pop()
+
+    def parse_definition(self, parser):
+        return parser.parse_class_object()
+
+    def describe_signature(self, signode, ast):
+        signode += addnodes.desc_annotation('class ', 'class ')
+        ast.describe_signature(signode, 'lastIsName', self.env)
+
+
+class CPPNamespaceObject(Directive):
     """
     This directive is just to tell Sphinx that we're documenting stuff in
     namespace foo.
@@ -1213,26 +1774,27 @@
     def run(self):
         env = self.state.document.settings.env
         if self.arguments[0].strip() in ('NULL', '0', 'nullptr'):
-            env.temp_data['cpp:prefix'] = None
+            env.temp_data['cpp:parent'] = []
         else:
             parser = DefinitionParser(self.arguments[0])
             try:
-                prefix = parser.parse_type()
+                prefix = parser.parse_namespace_object()
                 parser.assert_end()
-            except DefinitionError, e:
+            except DefinitionError as e:
                 self.state_machine.reporter.warning(e.description,
                                                     line=self.lineno)
             else:
-                env.temp_data['cpp:prefix'] = prefix
+                env.temp_data['cpp:parent'] = [prefix]
         return []
 
 
 class CPPXRefRole(XRefRole):
-
     def process_link(self, env, refnode, has_explicit_title, title, target):
-        refnode['cpp:parent'] = env.temp_data.get('cpp:parent')
+        parent = env.temp_data.get('cpp:parent')
+        if parent:
+            refnode['cpp:parent'] = parent[:]
         if not has_explicit_title:
-            target = target.lstrip('~') # only has a meaning for the title
+            target = target.lstrip('~')  # only has a meaning for the title
             # if the first character is a tilde, don't display the module/class
             # parts of the contents
             if title[:1] == '~':
@@ -1248,70 +1810,69 @@
     name = 'cpp'
     label = 'C++'
     object_types = {
-        'class':    ObjType(l_('class'),    'class'),
+        'class': ObjType(l_('class'), 'class'),
         'function': ObjType(l_('function'), 'func'),
-        'member':   ObjType(l_('member'),   'member'),
-        'type':     ObjType(l_('type'),     'type')
+        'member': ObjType(l_('member'), 'member'),
+        'type': ObjType(l_('type'), 'type')
     }
 
     directives = {
-        'class':        CPPClassObject,
-        'function':     CPPFunctionObject,
-        'member':       CPPMemberObject,
-        'type':         CPPTypeObject,
-        'namespace':    CPPCurrentNamespace
+        'class': CPPClassObject,
+        'function': CPPFunctionObject,
+        'member': CPPMemberObject,
+        'type': CPPTypeObject,
+        'namespace': CPPNamespaceObject
     }
     roles = {
-        'class':  CPPXRefRole(),
-        'func' :  CPPXRefRole(fix_parens=True),
+        'class': CPPXRefRole(),
+        'func': CPPXRefRole(fix_parens=True),
         'member': CPPXRefRole(),
-        'type':   CPPXRefRole()
+        'type': CPPXRefRole()
     }
     initial_data = {
-        'objects': {},  # fullname -> docname, objtype
+        'objects': {},  # prefixedName -> (docname, objectType, id)
     }
 
     def clear_doc(self, docname):
-        for fullname, (fn, _, _) in self.data['objects'].items():
-            if fn == docname:
+        for fullname, data in list(self.data['objects'].items()):
+            if data[0] == docname:
                 del self.data['objects'][fullname]
 
     def resolve_xref(self, env, fromdocname, builder,
                      typ, target, node, contnode):
-        def _create_refnode(expr):
-            name = unicode(expr)
+        def _create_refnode(nameAst):
+            name = text_type(nameAst)
             if name not in self.data['objects']:
-                return None
-            obj = self.data['objects'][name]
-            if obj[1] not in self.objtypes_for_role(typ):
-                return None
-            return make_refnode(builder, fromdocname, obj[0], obj[2],
-                                contnode, name)
+                # try dropping the last template
+                name = nameAst.get_name_no_last_template()
+                if name not in self.data['objects']:
+                    return None
+            docname, objectType, id = self.data['objects'][name]
+            return make_refnode(builder, fromdocname, docname, id, contnode,
+                                name)
 
         parser = DefinitionParser(target)
         try:
-            expr = parser.parse_type().get_name()
+            nameAst = parser.parse_xref_object().name
             parser.skip_ws()
-            if not parser.eof or expr is None:
+            if not parser.eof:
                 raise DefinitionError('')
         except DefinitionError:
             env.warn_node('unparseable C++ definition: %r' % target, node)
             return None
 
+        # try as is the name is fully qualified
+        refNode = _create_refnode(nameAst)
+        if refNode:
+            return refNode
+
+        # try qualifying it with the parent
         parent = node.get('cpp:parent', None)
-
-        rv = _create_refnode(expr)
-        if rv is not None or parent is None:
-            return rv
-        parent = parent.get_name()
-
-        rv = _create_refnode(expr.prefix(parent))
-        if rv is not None:
-            return rv
-
-        parent, name = parent.split_owner()
-        return _create_refnode(expr.prefix(parent))
+        if parent and len(parent) > 0:
+            return _create_refnode(nameAst.prefix_nested_name(parent[-1]))
+        else:
+            return None
 
     def get_objects(self):
-        for refname, (docname, type, theid) in self.data['objects'].iteritems():
+        for refname, (docname, type, theid) in iteritems(self.data['objects']):
             yield (refname, refname, type, docname, refname, 1)
diff --git a/sphinx/domains/javascript.py b/sphinx/domains/javascript.py
index 9b7777f..2718b87 100644
--- a/sphinx/domains/javascript.py
+++ b/sphinx/domains/javascript.py
@@ -183,7 +183,7 @@
     }
 
     def clear_doc(self, docname):
-        for fullname, (fn, _) in self.data['objects'].items():
+        for fullname, (fn, _) in list(self.data['objects'].items()):
             if fn == docname:
                 del self.data['objects'][fullname]
 
@@ -215,6 +215,6 @@
                             name.replace('$', '_S_'), contnode, name)
 
     def get_objects(self):
-        for refname, (docname, type) in self.data['objects'].iteritems():
+        for refname, (docname, type) in list(self.data['objects'].items()):
             yield refname, refname, type, docname, \
                   refname.replace('$', '_S_'), 1
diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py
index 792cffd..a7a93cb 100644
--- a/sphinx/domains/python.py
+++ b/sphinx/domains/python.py
@@ -11,6 +11,7 @@
 
 import re
 
+from six import iteritems
 from docutils import nodes
 from docutils.parsers.rst import directives
 
@@ -81,6 +82,23 @@
         signode += paramlist
 
 
+# This override allows our inline type specifiers to behave like :class: link
+# when it comes to handling "." and "~" prefixes.
+class PyTypedField(TypedField):
+    def make_xref(self, rolename, domain, target, innernode=nodes.emphasis):
+        result = super(PyTypedField, self).make_xref(rolename, domain, target,
+                                                     innernode)
+        if target.startswith('.'):
+            result['reftarget'] = target[1:]
+            result['refspecific'] = True
+            result[0][0] = nodes.Text(target[1:])
+        if target.startswith('~'):
+            result['reftarget'] = target[1:]
+            title = target.split('.')[-1]
+            result[0][0] = nodes.Text(title)
+        return result
+
+
 class PyObject(ObjectDescription):
     """
     Description of a general Python object.
@@ -92,7 +110,7 @@
     }
 
     doc_field_types = [
-        TypedField('parameter', label=l_('Parameters'),
+        PyTypedField('parameter', label=l_('Parameters'),
                    names=('param', 'parameter', 'arg', 'argument',
                           'keyword', 'kwarg', 'kwparam'),
                    typerolename='obj', typenames=('paramtype', 'type'),
@@ -497,7 +515,7 @@
         ignores = self.domain.env.config['modindex_common_prefix']
         ignores = sorted(ignores, key=len, reverse=True)
         # list of all modules, sorted by module name
-        modules = sorted(self.domain.data['modules'].iteritems(),
+        modules = sorted(iteritems(self.domain.data['modules']),
                          key=lambda x: x[0].lower())
         # sort out collapsable modules
         prev_modname = ''
@@ -547,7 +565,7 @@
         collapse = len(modules) - num_toplevels < num_toplevels
 
         # sort by first letter
-        content = sorted(content.iteritems())
+        content = sorted(iteritems(content))
 
         return content, collapse
 
@@ -602,10 +620,10 @@
     ]
 
     def clear_doc(self, docname):
-        for fullname, (fn, _) in self.data['objects'].items():
+        for fullname, (fn, _) in list(self.data['objects'].items()):
             if fn == docname:
                 del self.data['objects'][fullname]
-        for modname, (fn, _, _, _) in self.data['modules'].items():
+        for modname, (fn, _, _, _) in list(self.data['modules'].items()):
             if fn == docname:
                 del self.data['modules'][modname]
 
@@ -703,8 +721,8 @@
                                 contnode, name)
 
     def get_objects(self):
-        for modname, info in self.data['modules'].iteritems():
+        for modname, info in iteritems(self.data['modules']):
             yield (modname, modname, 'module', info[0], 'module-' + modname, 0)
-        for refname, (docname, type) in self.data['objects'].iteritems():
+        for refname, (docname, type) in iteritems(self.data['objects']):
             if type != 'module':  # modules are already handled
                 yield (refname, refname, type, docname, refname, 1)
diff --git a/sphinx/domains/rst.py b/sphinx/domains/rst.py
index c51c85f..e213211 100644
--- a/sphinx/domains/rst.py
+++ b/sphinx/domains/rst.py
@@ -11,6 +11,8 @@
 
 import re
 
+from six import iteritems
+
 from sphinx import addnodes
 from sphinx.domains import Domain, ObjType
 from sphinx.locale import l_, _
@@ -117,7 +119,7 @@
     }
 
     def clear_doc(self, docname):
-        for (typ, name), doc in self.data['objects'].items():
+        for (typ, name), doc in list(self.data['objects'].items()):
             if doc == docname:
                 del self.data['objects'][typ, name]
 
@@ -133,5 +135,5 @@
                                     contnode, target + ' ' + objtype)
 
     def get_objects(self):
-        for (typ, name), docname in self.data['objects'].iteritems():
+        for (typ, name), docname in iteritems(self.data['objects']):
             yield name, name, typ, docname, typ + '-' + name, 1
diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py
index 9a7937a..b5cc81b 100644
--- a/sphinx/domains/std.py
+++ b/sphinx/domains/std.py
@@ -12,6 +12,7 @@
 import re
 import unicodedata
 
+from six import iteritems
 from docutils import nodes
 from docutils.parsers.rst import directives
 from docutils.statemachine import ViewList
@@ -508,29 +509,29 @@
     }
 
     def clear_doc(self, docname):
-        for key, (fn, _) in self.data['progoptions'].items():
+        for key, (fn, _) in list(self.data['progoptions'].items()):
             if fn == docname:
                 del self.data['progoptions'][key]
-        for key, (fn, _) in self.data['objects'].items():
+        for key, (fn, _) in list(self.data['objects'].items()):
             if fn == docname:
                 del self.data['objects'][key]
-        for key, (fn, _, _) in self.data['labels'].items():
+        for key, (fn, _, _) in list(self.data['labels'].items()):
             if fn == docname:
                 del self.data['labels'][key]
-        for key, (fn, _) in self.data['anonlabels'].items():
+        for key, (fn, _) in list(self.data['anonlabels'].items()):
             if fn == docname:
                 del self.data['anonlabels'][key]
 
     def process_doc(self, env, docname, document):
         labels, anonlabels = self.data['labels'], self.data['anonlabels']
-        for name, explicit in document.nametypes.iteritems():
+        for name, explicit in iteritems(document.nametypes):
             if not explicit:
                 continue
             labelid = document.nameids[name]
             if labelid is None:
                 continue
             node = document.ids[labelid]
-            if name.isdigit() or node.has_key('refuri') or \
+            if name.isdigit() or 'refuri' in node or \
                    node.tagname.startswith('desc_'):
                 # ignore footnote labels, labels automatically generated from a
                 # link and object descriptions
@@ -548,6 +549,13 @@
                         break
                 else:
                     continue
+            elif node.tagname == 'image' and node.parent.tagname == 'figure':
+                for n in node.parent:
+                    if n.tagname == 'caption':
+                        sectname = clean_astext(n)
+                        break
+                else:
+                    continue
             elif node.tagname == 'table':
                 for n in node:
                     if n.tagname == 'title':
@@ -621,16 +629,16 @@
                                 labelid, contnode)
 
     def get_objects(self):
-        for (prog, option), info in self.data['progoptions'].iteritems():
+        for (prog, option), info in iteritems(self.data['progoptions']):
             yield (option, option, 'option', info[0], info[1], 1)
-        for (type, name), info in self.data['objects'].iteritems():
+        for (type, name), info in iteritems(self.data['objects']):
             yield (name, name, type, info[0], info[1],
                    self.object_types[type].attrs['searchprio'])
-        for name, info in self.data['labels'].iteritems():
+        for name, info in iteritems(self.data['labels']):
             yield (name, info[2], 'label', info[0], info[1], -1)
         # add anonymous-only labels as well
         non_anon_labels = set(self.data['labels'])
-        for name, info in self.data['anonlabels'].iteritems():
+        for name, info in iteritems(self.data['anonlabels']):
             if name not in non_anon_labels:
                 yield (name, name, 'label', info[0], info[1], -1)
 
diff --git a/sphinx/environment.py b/sphinx/environment.py
index 69a8b57..d51e7a1 100644
--- a/sphinx/environment.py
+++ b/sphinx/environment.py
@@ -18,11 +18,12 @@
 import imghdr
 import string
 import unicodedata
-import cPickle as pickle
 from os import path
 from glob import glob
-from itertools import izip, groupby
+from itertools import groupby
 
+from six import iteritems, itervalues, text_type, class_types
+from six.moves import cPickle as pickle, zip
 from docutils import nodes
 from docutils.io import FileInput, NullOutput
 from docutils.core import Publisher
@@ -39,8 +40,6 @@
 from sphinx.util.nodes import clean_astext, make_refnode, WarningStream
 from sphinx.util.osutil import SEP, fs_encoding, find_catalog_files
 from sphinx.util.matching import compile_matchers
-from sphinx.util.pycompat import class_types
-from sphinx.util.compat import docutils_version
 from sphinx.util.websupport import is_commentable
 from sphinx.errors import SphinxError, ExtensionError
 from sphinx.locale import _
@@ -137,7 +136,7 @@
         del self.domains
         picklefile = open(filename, 'wb')
         # remove potentially pickling-problematic values from config
-        for key, val in vars(self.config).items():
+        for key, val in list(vars(self.config).items()):
             if key.startswith('_') or \
                    isinstance(val, types.ModuleType) or \
                    isinstance(val, types.FunctionType) or \
@@ -279,11 +278,11 @@
             self.images.purge_doc(docname)
             self.dlfiles.purge_doc(docname)
 
-            for subfn, fnset in self.files_to_rebuild.items():
+            for subfn, fnset in list(self.files_to_rebuild.items()):
                 fnset.discard(docname)
                 if not fnset:
                     del self.files_to_rebuild[subfn]
-            for key, (fn, _) in self.citations.items():
+            for key, (fn, _) in list(self.citations.items()):
                 if fn == docname:
                     del self.citations[key]
             for version, changes in self.versionchanges.items():
@@ -340,10 +339,8 @@
         """
         matchers = compile_matchers(
             config.exclude_patterns[:] +
+            config.templates_path +
             config.html_extra_path +
-            config.exclude_trees +
-            [d + config.source_suffix for d in config.unused_docs] +
-            ['**/' + d for d in config.exclude_dirnames] +
             ['**/_sources', '.#*']
         )
         self.found_docs = set(get_matching_docs(
@@ -425,7 +422,7 @@
         else:
             # check if a config value was changed that affects how
             # doctrees are read
-            for key, descr in config.values.iteritems():
+            for key, descr in iteritems(config.values):
                 if descr[1] != 'env':
                     continue
                 if self.config[key] != config[key]:
@@ -497,14 +494,14 @@
 
     def warn_and_replace(self, error):
         """Custom decoding error handler that warns and replaces."""
-        linestart = error.object.rfind('\n', 0, error.start)
-        lineend = error.object.find('\n', error.start)
+        linestart = error.object.rfind(b'\n', 0, error.start)
+        lineend = error.object.find(b'\n', error.start)
         if lineend == -1: lineend = len(error.object)
-        lineno = error.object.count('\n', 0, error.start) + 1
+        lineno = error.object.count(b'\n', 0, error.start) + 1
         self.warn(self.docname, 'undecodable source characters, '
                   'replacing with "?": %r' %
-                  (error.object[linestart+1:error.start] + '>>>' +
-                   error.object[error.start:error.end] + '<<<' +
+                  (error.object[linestart+1:error.start] + b'>>>' +
+                   error.object[error.start:error.end] + b'<<<' +
                    error.object[error.end:lineend]), lineno)
         return (u'?', error.end)
 
@@ -594,12 +591,13 @@
             def __init__(self_, *args, **kwds):
                 # don't call sys.exit() on IOErrors
                 kwds['handle_io_errors'] = False
+                kwds['error_handler'] = 'sphinx'  # py3: handle error on open.
                 FileInput.__init__(self_, *args, **kwds)
 
             def decode(self_, data):
-                if isinstance(data, unicode):
+                if isinstance(data, text_type):  # py3: `data` already decoded.
                     return data
-                return data.decode(self_.encoding, 'sphinx')
+                return data.decode(self_.encoding, 'sphinx')  # py2: decoding
 
             def read(self_):
                 data = FileInput.read(self_)
@@ -620,10 +618,7 @@
                         destination_class=NullOutput)
         pub.set_components(None, 'restructuredtext', None)
         pub.process_programmatic_settings(None, self.settings, None)
-        if docutils_version < (0, 8):  #1531
-            pub.set_source(None, src_path.encode(fs_encoding))
-        else:
-            pub.set_source(None, src_path)
+        pub.set_source(None, src_path)
         pub.set_destination(None, None)
         pub.publish()
         doctree = pub.document
@@ -639,7 +634,7 @@
         self.note_indexentries_from(docname, doctree)
         self.note_citations_from(docname, doctree)
         self.build_toc_from(docname, doctree)
-        for domain in self.domains.itervalues():
+        for domain in itervalues(self.domains):
             domain.process_doc(self, docname, doctree)
 
         # allow extension-specific post-processing
@@ -816,7 +811,7 @@
                                 imgtype = imghdr.what(f)
                             finally:
                                 f.close()
-                        except (OSError, IOError), err:
+                        except (OSError, IOError) as err:
                             self.warn_node('image file %s not readable: %s' %
                                            (filename, err), node)
                         if imgtype:
@@ -825,7 +820,7 @@
                 candidates['*'] = rel_imgpath
             # map image paths to unique image names (so that they can be put
             # into a single directory)
-            for imgpath in candidates.itervalues():
+            for imgpath in itervalues(candidates):
                 self.dependencies.setdefault(docname, set()).add(imgpath)
                 if not os.access(path.join(self.srcdir, imgpath), os.R_OK):
                     self.warn_node('image file not readable: %s' % imgpath,
@@ -856,6 +851,14 @@
             else:
                 name, body = node
                 md[name.astext()] = body.astext()
+        for name, value in md.items():
+            if name in ('tocdepth',):
+                try:
+                    value = int(value)
+                except ValueError:
+                    value = 0
+                md[name] = value
+
         del doctree[0]
 
     def process_refonly_bullet_lists(self, docname, doctree):
@@ -927,7 +930,7 @@
         longtitlenode = titlenode
         # explicit title set with title directive; use this only for
         # the <title> tag in HTML output
-        if document.has_key('title'):
+        if 'title' in document:
             longtitlenode = nodes.title()
             longtitlenode += nodes.Text(document['title'])
         # look for first section title and use that as the title
@@ -975,11 +978,6 @@
         """Build a TOC from the doctree and store it in the inventory."""
         numentries = [0] # nonlocal again...
 
-        try:
-            maxdepth = int(self.metadata[docname].get('tocdepth', 0))
-        except ValueError:
-            maxdepth = 0
-
         def traverse_in_section(node, cls):
             """Like traverse(), but stay within the same section."""
             result = []
@@ -1003,6 +1001,7 @@
                     if blist:
                         onlynode += blist.children
                         entries.append(onlynode)
+                    continue
                 if not isinstance(sectionnode, nodes.section):
                     for toctreenode in traverse_in_section(sectionnode,
                                                            addnodes.toctree):
@@ -1032,8 +1031,7 @@
                 para = addnodes.compact_paragraph('', '', reference)
                 item = nodes.list_item('', para)
                 sub_item = build_toc(sectionnode, depth + 1)
-                if maxdepth == 0 or depth < maxdepth:
-                    item += sub_item
+                item += sub_item
                 entries.append(item)
             if entries:
                 return nodes.bullet_list('', *entries)
@@ -1221,6 +1219,8 @@
                 try:
                     refdoc = None
                     if url_re.match(ref):
+                        if title is None:
+                            title = ref
                         reference = nodes.reference('', '', internal=False,
                                                     refuri=ref, anchorname='',
                                                     *[nodes.Text(title)])
@@ -1249,6 +1249,8 @@
                             continue
                         refdoc = ref
                         toc = self.tocs[ref].deepcopy()
+                        maxdepth = self.metadata[ref].get('tocdepth', 0)
+                        _toctree_prune(toc, 2, maxdepth)
                         self.process_only_nodes(toc, builder, ref)
                         if title and toc.children and len(toc.children) == 1:
                             child = toc.children[0]
@@ -1431,7 +1433,7 @@
         for node in doctree.traverse(addnodes.only):
             try:
                 ret = builder.tags.eval_condition(node['expr'])
-            except Exception, err:
+            except Exception as err:
                 self.warn_node('exception while evaluating only '
                                'directive expression: %s' % err, node)
                 node.replace_self(node.children or nodes.comment())
@@ -1446,6 +1448,7 @@
         # a list of all docnames whose section numbers changed
         rewrite_needed = []
 
+        assigned = set()
         old_secnumbers = self.toc_secnumbers
         self.toc_secnumbers = {}
 
@@ -1485,17 +1488,19 @@
             if depth == 0:
                 return
             for (title, ref) in toctreenode['entries']:
-                if url_re.match(ref) or ref == 'self':
+                if url_re.match(ref) or ref == 'self' or ref in assigned:
                     # don't mess with those
                     continue
                 if ref in self.tocs:
                     secnums = self.toc_secnumbers[ref] = {}
+                    assigned.add(ref)
                     _walk_toc(self.tocs[ref], secnums, depth,
                               self.titles.get(ref))
                     if secnums != old_secnumbers.get(ref):
                         rewrite_needed.append(ref)
 
         for docname in self.numbered_toctrees:
+            assigned.add(docname)
             doctree = self.get_doctree(docname)
             for toctreenode in doctree.traverse(addnodes.toctree):
                 depth = toctreenode.get('numbered', 0)
@@ -1515,7 +1520,7 @@
             # Force the word to be unicode if it's a ASCII bytestring.
             # This will solve problems with unicode normalization later.
             # For instance the RFC role will add bytestrings at the moment
-            word = unicode(word)
+            word = text_type(word)
             entry = dic.get(word)
             if not entry:
                 dic[word] = entry = [[], {}]
@@ -1529,7 +1534,7 @@
                 else:
                     entry[0].append((main, uri))
 
-        for fn, entries in self.indexentries.iteritems():
+        for fn, entries in iteritems(self.indexentries):
             # new entry types must be listed in directives/other.py!
             for type, value, tid, main in entries:
                 try:
@@ -1557,7 +1562,7 @@
                         add_entry(first, _('see also %s') % second, link=False)
                     else:
                         self.warn(fn, 'unknown index entry type %r' % type)
-                except ValueError, err:
+                except ValueError as err:
                     self.warn(fn, str(err))
 
         # sort the index entries; put all symbols at the front, even those
@@ -1567,8 +1572,7 @@
             if lckey[0:1] in lcletters:
                 return chr(127) + lckey
             return lckey
-        newlist = new.items()
-        newlist.sort(key=keyfunc)
+        newlist = sorted(new.items(), key=keyfunc)
 
         if group_entries:
             # fixup entries: transform
@@ -1604,7 +1608,7 @@
         def keyfunc2(item, letters=string.ascii_uppercase + '_'):
             # hack: mutating the subitems dicts to a list in the keyfunc
             k, v = item
-            v[1] = sorted((si, se) for (si, (se, void)) in v[1].iteritems())
+            v[1] = sorted((si, se) for (si, (se, void)) in iteritems(v[1]))
             # now calculate the key
             letter = unicodedata.normalize('NFD', k[0])[0].upper()
             if letter in letters:
@@ -1656,7 +1660,7 @@
                 # else it will stay None
             # same for children
             if includes:
-                for subindex, args in enumerate(izip(includes,
+                for subindex, args in enumerate(zip(includes,
                                                      [None] + includes,
                                                      includes[1:] + [None])):
                     collect([(docname, subindex)] + parents,
diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py
index 423f921..5b014d0 100644
--- a/sphinx/ext/autodoc.py
+++ b/sphinx/ext/autodoc.py
@@ -17,10 +17,12 @@
 import traceback
 from types import FunctionType, BuiltinFunctionType, MethodType
 
+from six import iteritems, itervalues, text_type, class_types
 from docutils import nodes
 from docutils.utils import assemble_option_dict
 from docutils.statemachine import ViewList
 
+import sphinx
 from sphinx.util import rpartition, force_decode
 from sphinx.locale import _
 from sphinx.pycode import ModuleAnalyzer, PycodeError
@@ -29,7 +31,6 @@
 from sphinx.util.compat import Directive
 from sphinx.util.inspect import getargspec, isdescriptor, safe_getmembers, \
      safe_getattr, safe_repr, is_builtin_class_method
-from sphinx.util.pycompat import base_exception, class_types
 from sphinx.util.docstrings import prepare_docstring
 
 
@@ -54,9 +55,10 @@
             return dict.__getitem__(self, key)
         except KeyError:
             return self.default
-    def __nonzero__(self):
+    def __bool__(self):
         # docutils check "if option_spec"
         return True
+    __nonzero__ = __bool__  # for python2 compatibility
 
 identity = lambda x: x
 
@@ -70,6 +72,35 @@
             return None
 
 
+class _MockModule(object):
+    """Used by autodoc_mock_imports."""
+    def __init__(self, *args, **kwargs):
+        pass
+
+    def __call__(self, *args, **kwargs):
+        return _MockModule()
+
+    @classmethod
+    def __getattr__(cls, name):
+        if name in ('__file__', '__path__'):
+            return '/dev/null'
+        elif name[0] == name[0].upper():
+            # Not very good, we assume Uppercase names are classes...
+            mocktype = type(name, (), {})
+            mocktype.__module__ = __name__
+            return mocktype
+        else:
+            return _MockModule()
+
+def mock_import(modname):
+    if '.' in modname:
+        pkg, _n, mods = modname.rpartition('.')
+        mock_import(pkg)
+    mod = _MockModule()
+    sys.modules[modname] = mod
+    return mod
+
+
 ALL = object()
 INSTANCEATTR = object()
 
@@ -235,7 +266,7 @@
     @staticmethod
     def get_attr(obj, name, *defargs):
         """getattr() override for types such as Zope interfaces."""
-        for typ, func in AutoDirective._special_attrgetters.iteritems():
+        for typ, func in iteritems(AutoDirective._special_attrgetters):
             if isinstance(obj, typ):
                 return func(obj, name, *defargs)
         return safe_getattr(obj, name, *defargs)
@@ -332,6 +363,9 @@
                 self.modname, '.'.join(self.objpath))
         try:
             dbg('[autodoc] import %s', self.modname)
+            for modname in self.env.config.autodoc_mock_imports:
+                dbg('[autodoc] adding a mock module %s!', self.modname)
+                mock_import(modname)
             __import__(self.modname)
             parent = None
             obj = self.module = sys.modules[self.modname]
@@ -415,7 +449,7 @@
             # try to introspect the signature
             try:
                 args = self.format_args()
-            except Exception, err:
+            except Exception as err:
                 self.directive.warn('error while formatting arguments for '
                                     '%s: %s' % (self.fullname, err))
                 args = None
@@ -452,7 +486,7 @@
         docstring = self.get_attr(self.object, '__doc__', None)
         # make sure we have Unicode docstrings, then sanitize and split
         # into lines
-        if isinstance(docstring, unicode):
+        if isinstance(docstring, text_type):
             return [prepare_docstring(docstring, ignore)]
         elif isinstance(docstring, str):  # this will not trigger on Py3
             return [prepare_docstring(force_decode(docstring, encoding),
@@ -476,9 +510,9 @@
         # set sourcename and add content from attribute documentation
         if self.analyzer:
             # prevent encoding errors when the file name is non-ASCII
-            if not isinstance(self.analyzer.srcname, unicode):
-                filename = unicode(self.analyzer.srcname,
-                                   sys.getfilesystemencoding(), 'replace')
+            if not isinstance(self.analyzer.srcname, text_type):
+                filename = text_type(self.analyzer.srcname,
+                                     sys.getfilesystemencoding(), 'replace')
             else:
                 filename = self.analyzer.srcname
             sourcename = u'%s:docstring of %s' % (filename, self.fullname)
@@ -522,7 +556,7 @@
         if self.analyzer:
             attr_docs = self.analyzer.find_attr_docs()
             namespace = '.'.join(self.objpath)
-            for item in attr_docs.iteritems():
+            for item in iteritems(attr_docs):
                 if item[0][0] == namespace:
                     analyzed_member_names.add(item[0][1])
         if not want_all:
@@ -663,7 +697,7 @@
         # document non-skipped members
         memberdocumenters = []
         for (mname, member, isattr) in self.filter_members(members, want_all):
-            classes = [cls for cls in AutoDirective._registry.itervalues()
+            classes = [cls for cls in itervalues(AutoDirective._registry)
                        if cls.can_document_member(member, mname, isattr, self)]
             if not classes:
                 # don't know how to document this member
@@ -735,7 +769,7 @@
             # parse right now, to get PycodeErrors on parsing (results will
             # be cached anyway)
             self.analyzer.find_attr_docs()
-        except PycodeError, err:
+        except PycodeError as err:
             self.env.app.debug('[autodoc] module analyzer failed: %s', err)
             # no source file -- e.g. for builtin and C modules
             self.analyzer = None
@@ -942,6 +976,23 @@
                 self.args, self.retann = result
         return Documenter.format_signature(self)
 
+class DocstringStripSignatureMixin(DocstringSignatureMixin):
+    """
+    Mixin for AttributeDocumenter to provide the
+    feature of stripping any function signature from the docstring.
+    """
+    def format_signature(self):
+        if self.args is None and self.env.config.autodoc_docstring_signature:
+            # only act if a signature is not explicitly given already, and if
+            # the feature is enabled
+            result = self._find_signature()
+            if result is not None:
+                # Discarding _args is a only difference with
+                # DocstringSignatureMixin.format_signature.
+                # Documenter.format_signature use self.args value to format.
+                _args, self.retann = result
+        return Documenter.format_signature(self)
+
 
 class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter):
     """
@@ -1100,7 +1151,7 @@
                     docstrings.append(initdocstring)
         doc = []
         for docstring in docstrings:
-            if not isinstance(docstring, unicode):
+            if not isinstance(docstring, text_type):
                 docstring = force_decode(docstring, encoding)
             doc.append(prepare_docstring(docstring))
         return doc
@@ -1135,7 +1186,7 @@
     @classmethod
     def can_document_member(cls, member, membername, isattr, parent):
         return isinstance(member, class_types) and \
-               issubclass(member, base_exception)
+               issubclass(member, BaseException)
 
 
 class DataDocumenter(ModuleLevelDocumenter):
@@ -1184,42 +1235,25 @@
         return inspect.isroutine(member) and \
                not isinstance(parent, ModuleDocumenter)
 
-    if sys.version_info >= (3, 0):
-        def import_object(self):
-            ret = ClassLevelDocumenter.import_object(self)
-            if not ret:
-                return ret
-            obj_from_parent = self.parent.__dict__.get(self.object_name)
-            if isinstance(obj_from_parent, classmethod):
-                self.directivetype = 'classmethod'
-                self.member_order = self.member_order - 1
-            elif isinstance(obj_from_parent, staticmethod):
-                self.directivetype = 'staticmethod'
-                self.member_order = self.member_order - 1
-            else:
-                self.directivetype = 'method'
+    def import_object(self):
+        ret = ClassLevelDocumenter.import_object(self)
+        if not ret:
             return ret
-    else:
-        def import_object(self):
-            ret = ClassLevelDocumenter.import_object(self)
-            if not ret:
-                return ret
-            if isinstance(self.object, classmethod) or \
-                   (isinstance(self.object, MethodType) and
-                    self.object.im_self is not None):
-                self.directivetype = 'classmethod'
-                # document class and static members before ordinary ones
-                self.member_order = self.member_order - 1
-            elif isinstance(self.object, FunctionType) or \
-                 (isinstance(self.object, BuiltinFunctionType) and
-                  hasattr(self.object, '__self__') and
-                  self.object.__self__ is not None):
-                self.directivetype = 'staticmethod'
-                # document class and static members before ordinary ones
-                self.member_order = self.member_order - 1
-            else:
-                self.directivetype = 'method'
-            return ret
+
+        # to distinguish classmethod/staticmethod
+        obj = self.parent.__dict__.get(self.object_name)
+
+        if isinstance(obj, classmethod):
+            self.directivetype = 'classmethod'
+            # document class and static members before ordinary ones
+            self.member_order = self.member_order - 1
+        elif isinstance(obj, staticmethod):
+            self.directivetype = 'staticmethod'
+            # document class and static members before ordinary ones
+            self.member_order = self.member_order - 1
+        else:
+            self.directivetype = 'method'
+        return ret
 
     def format_args(self):
         if inspect.isbuiltin(self.object) or \
@@ -1238,7 +1272,7 @@
         pass
 
 
-class AttributeDocumenter(ClassLevelDocumenter):
+class AttributeDocumenter(DocstringStripSignatureMixin,ClassLevelDocumenter):
     """
     Specialized Documenter subclass for attributes.
     """
@@ -1401,7 +1435,7 @@
         try:
             self.genopt = Options(assemble_option_dict(
                 self.options.items(), doc_class.option_spec))
-        except (KeyError, ValueError, TypeError), err:
+        except (KeyError, ValueError, TypeError) as err:
             # an option is either unknown or has a wrong type
             msg = self.reporter.error('An option to %s is either unknown or '
                                       'has an invalid value: %s' % (self.name, err),
@@ -1465,10 +1499,13 @@
     app.add_config_value('autodoc_member_order', 'alphabetic', True)
     app.add_config_value('autodoc_default_flags', [], True)
     app.add_config_value('autodoc_docstring_signature', True, True)
+    app.add_config_value('autodoc_mock_imports', [], True)
     app.add_event('autodoc-process-docstring')
     app.add_event('autodoc-process-signature')
     app.add_event('autodoc-skip-member')
 
+    return sphinx.__version__
+
 
 class testcls:
     """test doc string"""
diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py
index c5c8f15..31bbfb8 100644
--- a/sphinx/ext/autosummary/__init__.py
+++ b/sphinx/ext/autosummary/__init__.py
@@ -59,10 +59,12 @@
 import inspect
 import posixpath
 
+from six import text_type
 from docutils.parsers.rst import directives
 from docutils.statemachine import ViewList
 from docutils import nodes
 
+import sphinx
 from sphinx import addnodes
 from sphinx.util.compat import Directive
 from sphinx.pycode import ModuleAnalyzer, PycodeError
@@ -117,7 +119,7 @@
             par = col1_entry[0]
             for j, subnode in enumerate(list(par)):
                 if isinstance(subnode, nodes.Text):
-                    new_text = unicode(subnode.astext())
+                    new_text = text_type(subnode.astext())
                     new_text = new_text.replace(u" ", u"\u00a0")
                     par[j] = nodes.Text(new_text)
     except IndexError:
@@ -270,11 +272,11 @@
             # try to also get a source code analyzer for attribute docs
             try:
                 documenter.analyzer = ModuleAnalyzer.for_module(
-                    documenter.get_real_modname())
+                                            documenter.get_real_modname())
                 # parse right now, to get PycodeErrors on parsing (results will
                 # be cached anyway)
                 documenter.analyzer.find_attr_docs()
-            except PycodeError, err:
+            except PycodeError as err:
                 documenter.env.app.debug(
                     '[autodoc] module analyzer failed: %s', err)
                 # no source file -- e.g. for builtin and C modules
@@ -497,7 +499,7 @@
             return obj, parent, modname
         else:
             return sys.modules[modname], None, modname
-    except (ValueError, ImportError, AttributeError, KeyError), e:
+    except (ValueError, ImportError, AttributeError, KeyError) as e:
         raise ImportError(*e.args)
 
 
@@ -568,3 +570,4 @@
     app.connect('doctree-read', process_autosummary_toc)
     app.connect('builder-inited', process_generate_options)
     app.add_config_value('autosummary_generate', [], True)
+    return sphinx.__version__
diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py
index 47ef986..11b1dfe 100644
--- a/sphinx/ext/autosummary/generate.py
+++ b/sphinx/ext/autosummary/generate.py
@@ -17,6 +17,7 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
+from __future__ import print_function
 
 import os
 import re
@@ -70,10 +71,10 @@
                               template_dir=options.templates)
 
 def _simple_info(msg):
-    print msg
+    print(msg)
 
 def _simple_warn(msg):
-    print >> sys.stderr, 'WARNING: ' + msg
+    print('WARNING: ' + msg, file=sys.stderr)
 
 # -- Generating output ---------------------------------------------------------
 
@@ -109,14 +110,11 @@
     # read
     items = find_autosummary_in_files(sources)
 
-    # remove possible duplicates
-    items = dict([(item, True) for item in items]).keys()
-
     # keep track of new files
     new_files = []
 
     # write
-    for name, path, template_name in sorted(items, key=str):
+    for name, path, template_name in sorted(set(items), key=str):
         if path is None:
             # The corresponding autosummary:: directive did not have
             # a :toctree: option
@@ -127,7 +125,7 @@
 
         try:
             name, obj, parent, mod_name = import_by_name(name)
-        except ImportError, e:
+        except ImportError as e:
             warn('[autosummary] failed to import %r: %s' % (name, e))
             continue
 
@@ -240,9 +238,9 @@
         return find_autosummary_in_lines(lines, module=name, filename=filename)
     except AttributeError:
         pass
-    except ImportError, e:
-        print "Failed to import '%s': %s" % (name, e)
-    except SystemExit, e:
+    except ImportError as e:
+        print("Failed to import '%s': %s" % (name, e))
+    except SystemExit as e:
         print("Failed to import '%s'; the module executes module level "
               "statement and it might call sys.exit()." % name)
     return []
diff --git a/sphinx/ext/coverage.py b/sphinx/ext/coverage.py
index 52be1bd..49dc02f 100644
--- a/sphinx/ext/coverage.py
+++ b/sphinx/ext/coverage.py
@@ -13,9 +13,12 @@
 import re
 import glob
 import inspect
-import cPickle as pickle
 from os import path
 
+from six import iteritems
+from six.moves import cPickle as pickle
+
+import sphinx
 from sphinx.builders import Builder
 
 
@@ -52,7 +55,7 @@
                 self.warn('invalid regex %r in coverage_c_regexes' % exp)
 
         self.c_ignorexps = {}
-        for (name, exps) in self.config.coverage_ignore_c_items.iteritems():
+        for (name, exps) in iteritems(self.config.coverage_ignore_c_items):
             self.c_ignorexps[name] = compile_regex_list(
                 'coverage_ignore_c_items', exps, self.warn)
         self.mod_ignorexps = compile_regex_list(
@@ -109,7 +112,7 @@
                 write_header(op, 'Undocumented C API elements', '=')
             op.write('\n')
 
-            for filename, undoc in self.c_undoc.iteritems():
+            for filename, undoc in iteritems(self.c_undoc):
                 write_header(op, filename)
                 for typ, name in undoc:
                     op.write(' * %-50s [%9s]\n' % (name, typ))
@@ -134,7 +137,7 @@
 
             try:
                 mod = __import__(mod_name, fromlist=['foo'])
-            except ImportError, err:
+            except ImportError as err:
                 self.warn('module %s could not be imported: %s' %
                           (mod_name, err))
                 self.py_undoc[mod_name] = {'error': err}
@@ -211,8 +214,7 @@
         try:
             if self.config.coverage_write_headline:
                 write_header(op, 'Undocumented Python objects', '=')
-            keys = self.py_undoc.keys()
-            keys.sort()
+            keys = sorted(self.py_undoc.keys())
             for name in keys:
                 undoc = self.py_undoc[name]
                 if 'error' in undoc:
@@ -229,7 +231,7 @@
                     if undoc['classes']:
                         op.write('Classes:\n')
                         for name, methods in sorted(
-                                                 undoc['classes'].iteritems()):
+                                                 iteritems(undoc['classes'])):
                             if not methods:
                                 op.write(' * %s\n' % name)
                             else:
@@ -263,3 +265,4 @@
     app.add_config_value('coverage_ignore_c_items', {}, False)
     app.add_config_value('coverage_write_headline', True, False)
     app.add_config_value('coverage_skip_undoc_in_source', False, False)
+    return sphinx.__version__
diff --git a/sphinx/ext/doctest.py b/sphinx/ext/doctest.py
index 70beb9b..20b8692 100644
--- a/sphinx/ext/doctest.py
+++ b/sphinx/ext/doctest.py
@@ -14,20 +14,20 @@
 import sys
 import time
 import codecs
-import StringIO
 from os import path
 # circumvent relative import
 doctest = __import__('doctest')
 
+from six import itervalues, StringIO, binary_type
 from docutils import nodes
 from docutils.parsers.rst import directives
 
+import sphinx
 from sphinx.builders import Builder
 from sphinx.util import force_decode
 from sphinx.util.nodes import set_source_info
 from sphinx.util.compat import Directive
 from sphinx.util.console import bold
-from sphinx.util.pycompat import bytes
 
 blankline_re = re.compile(r'^\s*<BLANKLINE>', re.MULTILINE)
 doctestopt_re = re.compile(r'#\s*doctest:.+$', re.MULTILINE)
@@ -158,7 +158,7 @@
 
 class SphinxDocTestRunner(doctest.DocTestRunner):
     def summarize(self, out, verbose=None):
-        string_io = StringIO.StringIO()
+        string_io = StringIO()
         old_stdout = sys.stdout
         sys.stdout = string_io
         try:
@@ -233,7 +233,7 @@
         self.info(text, nonl=True)
         if self.app.quiet:
             self.warn(text)
-        if isinstance(text, bytes):
+        if isinstance(text, binary_type):
             text = force_decode(text, None)
         self.outfile.write(text)
 
@@ -289,14 +289,14 @@
         if self.config.doctest_test_doctest_blocks:
             def condition(node):
                 return (isinstance(node, (nodes.literal_block, nodes.comment))
-                        and node.has_key('testnodetype')) or \
+                        and 'testnodetype' in node) or \
                        isinstance(node, nodes.doctest_block)
         else:
             def condition(node):
                 return isinstance(node, (nodes.literal_block, nodes.comment)) \
-                        and node.has_key('testnodetype')
+                        and 'testnodetype' in node
         for node in doctree.traverse(condition):
-            source = node.has_key('test') and node['test'] or node.astext()
+            source = 'test' in node and node['test'] or node.astext()
             if not source:
                 self.warn('no code/output in %s block at %s:%s' %
                           (node.get('testnodetype', 'doctest'),
@@ -312,24 +312,24 @@
                     groups[groupname] = TestGroup(groupname)
                 groups[groupname].add_code(code)
         for code in add_to_all_groups:
-            for group in groups.itervalues():
+            for group in itervalues(groups):
                 group.add_code(code)
         if self.config.doctest_global_setup:
             code = TestCode(self.config.doctest_global_setup,
                             'testsetup', lineno=0)
-            for group in groups.itervalues():
+            for group in itervalues(groups):
                 group.add_code(code, prepend=True)
         if self.config.doctest_global_cleanup:
             code = TestCode(self.config.doctest_global_cleanup,
                             'testcleanup', lineno=0)
-            for group in groups.itervalues():
+            for group in itervalues(groups):
                 group.add_code(code)
         if not groups:
             return
 
         self._out('\nDocument: %s\n----------%s\n' %
                   (docname, '-'*len(docname)))
-        for group in groups.itervalues():
+        for group in itervalues(groups):
             self.test_group(group, self.env.doc2path(docname, base=None))
         # Separately count results from setup code
         res_f, res_t = self.setup_runner.summarize(self._out, verbose=False)
@@ -435,3 +435,4 @@
     app.add_config_value('doctest_test_doctest_blocks', 'default', False)
     app.add_config_value('doctest_global_setup', '', False)
     app.add_config_value('doctest_global_cleanup', '', False)
+    return sphinx.__version__
diff --git a/sphinx/ext/extlinks.py b/sphinx/ext/extlinks.py
index 18da573..c0cfbcd 100644
--- a/sphinx/ext/extlinks.py
+++ b/sphinx/ext/extlinks.py
@@ -24,8 +24,10 @@
     :license: BSD, see LICENSE for details.
 """
 
+from six import iteritems
 from docutils import nodes, utils
 
+import sphinx
 from sphinx.util.nodes import split_explicit_title
 
 
@@ -51,9 +53,10 @@
     return role
 
 def setup_link_roles(app):
-    for name, (base_url, prefix) in app.config.extlinks.iteritems():
+    for name, (base_url, prefix) in iteritems(app.config.extlinks):
         app.add_role(name, make_link_role(base_url, prefix))
 
 def setup(app):
     app.add_config_value('extlinks', {}, 'env')
     app.connect('builder-inited', setup_link_roles)
+    return sphinx.__version__
diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py
index 028560b..b4b8bc2 100644
--- a/sphinx/ext/graphviz.py
+++ b/sphinx/ext/graphviz.py
@@ -15,14 +15,14 @@
 import posixpath
 from os import path
 from subprocess import Popen, PIPE
-try:
-    from hashlib import sha1 as sha
-except ImportError:
-    from sha import sha
+from hashlib import sha1
 
+from six import text_type
 from docutils import nodes
 from docutils.parsers.rst import directives
+from docutils.statemachine import ViewList
 
+import sphinx
 from sphinx.errors import SphinxError
 from sphinx.locale import _
 from sphinx.util.osutil import ensuredir, ENOENT, EPIPE, EINVAL
@@ -40,6 +40,20 @@
     pass
 
 
+def figure_wrapper(directive, node, caption):
+    figure_node = nodes.figure('', node)
+
+    parsed = nodes.Element()
+    directive.state.nested_parse(ViewList([caption], source=''),
+                                 directive.content_offset, parsed)
+    caption_node = nodes.caption(parsed[0].rawsource, '',
+                                 *parsed[0].children)
+    caption_node.source = parsed[0].source
+    caption_node.line = parsed[0].line
+    figure_node += caption_node
+    return figure_node
+
+
 class Graphviz(Directive):
     """
     Directive to insert arbitrary dot markup.
@@ -85,9 +99,12 @@
         node['options'] = []
         if 'alt' in self.options:
             node['alt'] = self.options['alt']
-        if 'caption' in self.options:
-            node['caption'] = self.options['caption']
         node['inline'] = 'inline' in self.options
+
+        caption = self.options.get('caption')
+        if caption and not node['inline']:
+            node = figure_wrapper(self, node, caption)
+
         return [node]
 
 
@@ -112,9 +129,12 @@
         node['options'] = []
         if 'alt' in self.options:
             node['alt'] = self.options['alt']
-        if 'caption' in self.options:
-            node['caption'] = self.options['caption']
         node['inline'] = 'inline' in self.options
+
+        caption = self.options.get('caption')
+        if caption and not node['inline']:
+            node = figure_wrapper(self, node, caption)
+
         return [node]
 
 
@@ -125,7 +145,7 @@
               str(self.builder.config.graphviz_dot_args)
               ).encode('utf-8')
 
-    fname = '%s-%s.%s' % (prefix, sha(hashkey).hexdigest(), format)
+    fname = '%s-%s.%s' % (prefix, sha1(hashkey).hexdigest(), format)
     if hasattr(self.builder, 'imgpath'):
         # HTML
         relfn = posixpath.join(self.builder.imgpath, fname)
@@ -145,7 +165,7 @@
     ensuredir(path.dirname(outfn))
 
     # graphviz expects UTF-8 by default
-    if isinstance(code, unicode):
+    if isinstance(code, text_type):
         code = code.encode('utf-8')
 
     dot_args = [self.builder.config.graphviz_dot]
@@ -156,7 +176,7 @@
         dot_args.extend(['-Tcmapx', '-o%s.map' % outfn])
     try:
         p = Popen(dot_args, stdout=PIPE, stdin=PIPE, stderr=PIPE)
-    except OSError, err:
+    except OSError as err:
         if err.errno != ENOENT:   # No such file or directory
             raise
         self.builder.warn('dot command %r cannot be run (needed for graphviz '
@@ -168,7 +188,7 @@
         # Graphviz may close standard input when an error occurs,
         # resulting in a broken pipe on communicate()
         stdout, stderr = p.communicate(code)
-    except (OSError, IOError), err:
+    except (OSError, IOError) as err:
         if err.errno not in (EPIPE, EINVAL):
             raise
         # in this case, read the standard output and standard error streams
@@ -192,7 +212,7 @@
             raise GraphvizError("graphviz_output_format must be one of 'png', "
                                 "'svg', but is %r" % format)
         fname, outfn = render_dot(self, code, options, format, prefix)
-    except GraphvizError, exc:
+    except GraphvizError as exc:
         self.builder.warn('dot code %r: ' % code + str(exc))
         raise nodes.SkipNode
 
@@ -228,9 +248,6 @@
                 self.body.append('<img src="%s" alt="%s" usemap="#%s" %s/>\n' %
                                  (fname, alt, mapname, imgcss))
                 self.body.extend([item.decode('utf-8') for item in imgmap])
-        if node.get('caption') and not inline:
-            self.body.append('</p>\n<p class="caption">')
-            self.body.append(self.encode(node['caption']))
 
     self.body.append('</%s>\n' % wrapper)
     raise nodes.SkipNode
@@ -243,7 +260,7 @@
 def render_dot_latex(self, node, code, options, prefix='graphviz'):
     try:
         fname, outfn = render_dot(self, code, options, 'pdf', prefix)
-    except GraphvizError, exc:
+    except GraphvizError as exc:
         self.builder.warn('dot code %r: ' % code + str(exc))
         raise nodes.SkipNode
 
@@ -254,18 +271,8 @@
         para_separator = '\n'
 
     if fname is not None:
-        caption = node.get('caption')
-        # XXX add ids from previous target node
-        if caption and not inline:
-            self.body.append('\n\\begin{figure}[h!]')
-            self.body.append('\n\\begin{center}')
-            self.body.append('\n\\caption{%s}' % self.encode(caption))
-            self.body.append('\n\\includegraphics{%s}' % fname)
-            self.body.append('\n\\end{center}')
-            self.body.append('\n\\end{figure}\n')
-        else:
-            self.body.append('%s\\includegraphics{%s}%s' %
-                             (para_separator, fname, para_separator))
+        self.body.append('%s\\includegraphics{%s}%s' %
+                         (para_separator, fname, para_separator))
     raise nodes.SkipNode
 
 
@@ -276,16 +283,11 @@
 def render_dot_texinfo(self, node, code, options, prefix='graphviz'):
     try:
         fname, outfn = render_dot(self, code, options, 'png', prefix)
-    except GraphvizError, exc:
+    except GraphvizError as exc:
         self.builder.warn('dot code %r: ' % code + str(exc))
         raise nodes.SkipNode
     if fname is not None:
-        self.body.append('\n\n@float\n')
-        caption = node.get('caption')
-        if caption:
-            self.body.append('@caption{%s}\n' % self.escape_arg(caption))
-        self.body.append('@image{%s,,,[graphviz],png}\n'
-                         '@end float\n\n' % fname[:-4])
+        self.body.append('@image{%s,,,[graphviz],png}\n' % fname[:-4])
     raise nodes.SkipNode
 
 def texinfo_visit_graphviz(self, node):
@@ -321,3 +323,4 @@
     app.add_config_value('graphviz_dot', 'dot', 'html')
     app.add_config_value('graphviz_dot_args', [], 'html')
     app.add_config_value('graphviz_output_format', 'png', 'html')
+    return sphinx.__version__
diff --git a/sphinx/ext/ifconfig.py b/sphinx/ext/ifconfig.py
index 3362e56..ab15e1e 100644
--- a/sphinx/ext/ifconfig.py
+++ b/sphinx/ext/ifconfig.py
@@ -22,6 +22,7 @@
 
 from docutils import nodes
 
+import sphinx
 from sphinx.util.nodes import set_source_info
 from sphinx.util.compat import Directive
 
@@ -53,7 +54,7 @@
     for node in doctree.traverse(ifconfig):
         try:
             res = eval(node['expr'], ns)
-        except Exception, err:
+        except Exception as err:
             # handle exceptions in a clean fashion
             from traceback import format_exception_only
             msg = ''.join(format_exception_only(err.__class__, err))
@@ -72,3 +73,4 @@
     app.add_node(ifconfig)
     app.add_directive('ifconfig', IfConfig)
     app.connect('doctree-resolved', process_ifconfig_nodes)
+    return sphinx.__version__
diff --git a/sphinx/ext/inheritance_diagram.py b/sphinx/ext/inheritance_diagram.py
index 5b8eab3..bbae5c1 100644
--- a/sphinx/ext/inheritance_diagram.py
+++ b/sphinx/ext/inheritance_diagram.py
@@ -45,9 +45,11 @@
 except ImportError:
     from md5 import md5
 
+from six import text_type
 from docutils import nodes
 from docutils.parsers.rst import directives
 
+import sphinx
 from sphinx.ext.graphviz import render_dot_html, render_dot_latex, \
     render_dot_texinfo
 from sphinx.pycode import ModuleAnalyzer
@@ -162,7 +164,7 @@
                 if cls.__doc__:
                     enc = ModuleAnalyzer.for_module(cls.__module__).encoding
                     doc = cls.__doc__.strip().split("\n")[0]
-                    if not isinstance(doc, unicode):
+                    if not isinstance(doc, text_type):
                         doc = force_decode(doc, enc)
                     if doc:
                         tooltip = '"%s"' % doc.replace('"', '\\"')
@@ -311,7 +313,7 @@
                 class_names, env.temp_data.get('py:module'),
                 parts=node['parts'],
                 private_bases='private-bases' in self.options)
-        except InheritanceException, err:
+        except InheritanceException as err:
             return [node.document.reporter.warning(err.args[0],
                                                    line=self.lineno)]
 
@@ -405,3 +407,4 @@
     app.add_config_value('inheritance_graph_attrs', {}, False),
     app.add_config_value('inheritance_node_attrs', {}, False),
     app.add_config_value('inheritance_edge_attrs', {}, False),
+    return sphinx.__version__
diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py
index c3adf56..43507a3 100644
--- a/sphinx/ext/intersphinx.py
+++ b/sphinx/ext/intersphinx.py
@@ -27,27 +27,28 @@
 import time
 import zlib
 import codecs
-import urllib2
 import posixpath
 from os import path
 import re
 
+from six import iteritems
+from six.moves.urllib import request
 from docutils import nodes
 from docutils.utils import relative_path
 
+import sphinx
 from sphinx.locale import _
 from sphinx.builders.html import INVENTORY_FILENAME
-from sphinx.util.pycompat import b
 
 
-handlers = [urllib2.ProxyHandler(), urllib2.HTTPRedirectHandler(),
-            urllib2.HTTPHandler()]
+handlers = [request.ProxyHandler(), request.HTTPRedirectHandler(),
+            request.HTTPHandler()]
 try:
-    handlers.append(urllib2.HTTPSHandler)
+    handlers.append(request.HTTPSHandler)
 except AttributeError:
     pass
 
-urllib2.install_opener(urllib2.build_opener(*handlers))
+request.install_opener(request.build_opener(*handlers))
 
 UTF8StreamReader = codecs.lookup('utf-8')[2]
 
@@ -55,9 +56,9 @@
 def read_inventory_v1(f, uri, join):
     f = UTF8StreamReader(f)
     invdata = {}
-    line = f.next()
+    line = next(f)
     projname = line.rstrip()[11:]
-    line = f.next()
+    line = next(f)
     version = line.rstrip()[11:]
     for line in f:
         name, type, location = line.rstrip().split(None, 2)
@@ -85,19 +86,19 @@
 
     def read_chunks():
         decompressor = zlib.decompressobj()
-        for chunk in iter(lambda: f.read(bufsize), b('')):
+        for chunk in iter(lambda: f.read(bufsize), b''):
             yield decompressor.decompress(chunk)
         yield decompressor.flush()
 
     def split_lines(iter):
-        buf = b('')
+        buf = b''
         for chunk in iter:
             buf += chunk
-            lineend = buf.find(b('\n'))
+            lineend = buf.find(b'\n')
             while lineend != -1:
                 yield buf[:lineend].decode('utf-8')
                 buf = buf[lineend+1:]
-                lineend = buf.find(b('\n'))
+                lineend = buf.find(b'\n')
         assert not buf
 
     for line in split_lines(read_chunks()):
@@ -129,10 +130,10 @@
     join = localuri and path.join or posixpath.join
     try:
         if inv.find('://') != -1:
-            f = urllib2.urlopen(inv)
+            f = request.urlopen(inv)
         else:
             f = open(path.join(app.srcdir, inv), 'rb')
-    except Exception, err:
+    except Exception as err:
         app.warn('intersphinx inventory %r not fetchable due to '
                  '%s: %s' % (inv, err.__class__, err))
         return
@@ -149,7 +150,7 @@
         except ValueError:
             f.close()
             raise ValueError('unknown or unsupported inventory version')
-    except Exception, err:
+    except Exception as err:
         app.warn('intersphinx inventory %r not readable due to '
                  '%s: %s' % (inv, err.__class__.__name__, err))
     else:
@@ -167,7 +168,7 @@
         env.intersphinx_named_inventory = {}
     cache = env.intersphinx_cache
     update = False
-    for key, value in app.config.intersphinx_mapping.iteritems():
+    for key, value in iteritems(app.config.intersphinx_mapping):
         if isinstance(value, tuple):
             # new format
             name, (uri, inv) = key, value
@@ -179,19 +180,25 @@
         # we can safely assume that the uri<->inv mapping is not changed
         # during partial rebuilds since a changed intersphinx_mapping
         # setting will cause a full environment reread
-        if not inv:
-            inv = posixpath.join(uri, INVENTORY_FILENAME)
-        # decide whether the inventory must be read: always read local
-        # files; remote ones only if the cache time is expired
-        if '://' not in inv or uri not in cache \
-               or cache[uri][1] < cache_time:
-            app.info('loading intersphinx inventory from %s...' % inv)
-            invdata = fetch_inventory(app, uri, inv)
-            if invdata:
-                cache[uri] = (name, now, invdata)
-            else:
-                cache.pop(uri, None)
-            update = True
+        if not isinstance(inv, tuple):
+            invs = (inv, )
+        else:
+            invs = inv
+
+        for inv in invs:
+            if not inv:
+                inv = posixpath.join(uri, INVENTORY_FILENAME)
+            # decide whether the inventory must be read: always read local
+            # files; remote ones only if the cache time is expired
+            if '://' not in inv or uri not in cache \
+                    or cache[uri][1] < cache_time:
+                app.info('loading intersphinx inventory from %s...' % inv)
+                invdata = fetch_inventory(app, uri, inv)
+                if invdata:
+                    cache[uri] = (name, now, invdata)
+                    update = True
+                    break
+
     if update:
         env.intersphinx_inventory = {}
         env.intersphinx_named_inventory = {}
@@ -202,13 +209,13 @@
         # add the unnamed inventories last.  This means that the
         # unnamed inventories will shadow the named ones but the named
         # ones can still be accessed when the name is specified.
-        cached_vals = list(cache.itervalues())
+        cached_vals = list(cache.values())
         named_vals = sorted(v for v in cached_vals if v[0])
         unnamed_vals = [v for v in cached_vals if not v[0]]
         for name, _, invdata in named_vals + unnamed_vals:
             if name:
                 env.intersphinx_named_inventory[name] = invdata
-            for type, objects in invdata.iteritems():
+            for type, objects in iteritems(invdata):
                 env.intersphinx_inventory.setdefault(
                     type, {}).update(objects)
 
@@ -269,3 +276,4 @@
     app.add_config_value('intersphinx_cache_limit', 5, False)
     app.connect('missing-reference', missing_reference)
     app.connect('builder-inited', load_mappings)
+    return sphinx.__version__
diff --git a/sphinx/ext/jsmath.py b/sphinx/ext/jsmath.py
index 8907576..897d87a 100644
--- a/sphinx/ext/jsmath.py
+++ b/sphinx/ext/jsmath.py
@@ -12,6 +12,7 @@
 
 from docutils import nodes
 
+import sphinx
 from sphinx.application import ExtensionError
 from sphinx.ext.mathbase import setup_math as mathbase_setup
 
@@ -56,3 +57,4 @@
     mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
     app.add_config_value('jsmath_path', '', False)
     app.connect('builder-inited', builder_inited)
+    return sphinx.__version__
diff --git a/sphinx/ext/linkcode.py b/sphinx/ext/linkcode.py
index 77bd9f2..bbb0698 100644
--- a/sphinx/ext/linkcode.py
+++ b/sphinx/ext/linkcode.py
@@ -11,6 +11,7 @@
 
 from docutils import nodes
 
+import sphinx
 from sphinx import addnodes
 from sphinx.locale import _
 from sphinx.errors import SphinxError
@@ -70,3 +71,4 @@
 def setup(app):
     app.connect('doctree-read', doctree_read)
     app.add_config_value('linkcode_resolve', None, '')
+    return sphinx.__version__
diff --git a/sphinx/ext/mathjax.py b/sphinx/ext/mathjax.py
index ee27866..fd5c5f1 100644
--- a/sphinx/ext/mathjax.py
+++ b/sphinx/ext/mathjax.py
@@ -13,6 +13,7 @@
 
 from docutils import nodes
 
+import sphinx
 from sphinx.application import ExtensionError
 from sphinx.ext.mathbase import setup_math as mathbase_setup
 
@@ -60,9 +61,12 @@
 
 def setup(app):
     mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
+    # more information for mathjax secure url is here:
+    # http://docs.mathjax.org/en/latest/start.html#secure-access-to-the-cdn
     app.add_config_value('mathjax_path',
-                         'http://cdn.mathjax.org/mathjax/latest/MathJax.js?'
+                         'https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?'
                          'config=TeX-AMS-MML_HTMLorMML', False)
     app.add_config_value('mathjax_inline', [r'\(', r'\)'], 'html')
     app.add_config_value('mathjax_display', [r'\[', r'\]'], 'html')
     app.connect('builder-inited', builder_inited)
+    return sphinx.__version__
diff --git a/sphinx/ext/napoleon/__init__.py b/sphinx/ext/napoleon/__init__.py
new file mode 100644
index 0000000..554162e
--- /dev/null
+++ b/sphinx/ext/napoleon/__init__.py
@@ -0,0 +1,391 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.ext.napoleon
+    ~~~~~~~~~~~~~~~~~~~
+
+    Support for NumPy and Google style docstrings.
+
+    :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import sys
+
+from six import PY2, iteritems
+
+import sphinx
+from sphinx.ext.napoleon.docstring import GoogleDocstring, NumpyDocstring
+
+
+class Config(object):
+    """Sphinx napoleon extension settings in `conf.py`.
+
+    Listed below are all the settings used by napoleon and their default
+    values. These settings can be changed in the Sphinx `conf.py` file. Make
+    sure that both "sphinx.ext.autodoc" and "sphinx.ext.napoleon" are
+    enabled in `conf.py`::
+
+        # conf.py
+
+        # Add any Sphinx extension module names here, as strings
+        extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon']
+
+        # Napoleon settings
+        napoleon_google_docstring = True
+        napoleon_numpy_docstring = True
+        napoleon_include_private_with_doc = False
+        napoleon_include_special_with_doc = True
+        napoleon_use_admonition_for_examples = False
+        napoleon_use_admonition_for_notes = False
+        napoleon_use_admonition_for_references = False
+        napoleon_use_ivar = False
+        napoleon_use_param = True
+        napoleon_use_rtype = True
+
+    .. _Google style:
+       http://google-styleguide.googlecode.com/svn/trunk/pyguide.html
+    .. _NumPy style:
+       https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
+
+    Attributes
+    ----------
+    napoleon_google_docstring : bool, defaults to True
+        True to parse `Google style`_ docstrings. False to disable support
+        for Google style docstrings.
+    napoleon_numpy_docstring : bool, defaults to True
+        True to parse `NumPy style`_ docstrings. False to disable support
+        for NumPy style docstrings.
+    napoleon_include_private_with_doc : bool, defaults to False
+        True to include private members (like ``_membername``) with docstrings
+        in the documentation. False to fall back to Sphinx's default behavior.
+
+        **If True**::
+
+            def _included(self):
+                \"\"\"
+                This will be included in the docs because it has a docstring
+                \"\"\"
+                pass
+
+            def _skipped(self):
+                # This will NOT be included in the docs
+                pass
+
+    napoleon_include_special_with_doc : bool, defaults to True
+        True to include special members (like ``__membername__``) with
+        docstrings in the documentation. False to fall back to Sphinx's
+        default behavior.
+
+        **If True**::
+
+            def __str__(self):
+                \"\"\"
+                This will be included in the docs because it has a docstring
+                \"\"\"
+                return unicode(self).encode('utf-8')
+
+            def __unicode__(self):
+                # This will NOT be included in the docs
+                return unicode(self.__class__.__name__)
+
+    napoleon_use_admonition_for_examples : bool, defaults to False
+        True to use the ``.. admonition::`` directive for the **Example** and
+        **Examples** sections. False to use the ``.. rubric::`` directive
+        instead. One may look better than the other depending on what HTML
+        theme is used.
+
+        This `NumPy style`_ snippet will be converted as follows::
+
+            Example
+            -------
+            This is just a quick example
+
+        **If True**::
+
+            .. admonition:: Example
+
+               This is just a quick example
+
+        **If False**::
+
+            .. rubric:: Example
+
+            This is just a quick example
+
+    napoleon_use_admonition_for_notes : bool, defaults to False
+        True to use the ``.. admonition::`` directive for **Notes** sections.
+        False to use the ``.. rubric::`` directive instead.
+
+        Note
+        ----
+        The singular **Note** section will always be converted to a
+        ``.. note::`` directive.
+
+        See Also
+        --------
+        :attr:`napoleon_use_admonition_for_examples`
+
+    napoleon_use_admonition_for_references : bool, defaults to False
+        True to use the ``.. admonition::`` directive for **References**
+        sections. False to use the ``.. rubric::`` directive instead.
+
+        See Also
+        --------
+        :attr:`napoleon_use_admonition_for_examples`
+
+    napoleon_use_ivar : bool, defaults to False
+        True to use the ``:ivar:`` role for instance variables. False to use
+        the ``.. attribute::`` directive instead.
+
+        This `NumPy style`_ snippet will be converted as follows::
+
+            Attributes
+            ----------
+            attr1 : int
+                Description of `attr1`
+
+        **If True**::
+
+            :ivar attr1: Description of `attr1`
+            :vartype attr1: int
+
+        **If False**::
+
+            .. attribute:: attr1
+
+               *int*
+
+               Description of `attr1`
+
+    napoleon_use_param : bool, defaults to True
+        True to use a ``:param:`` role for each function parameter. False to
+        use a single ``:parameters:`` role for all the parameters.
+
+        This `NumPy style`_ snippet will be converted as follows::
+
+            Parameters
+            ----------
+            arg1 : str
+                Description of `arg1`
+            arg2 : int, optional
+                Description of `arg2`, defaults to 0
+
+        **If True**::
+
+            :param arg1: Description of `arg1`
+            :type arg1: str
+            :param arg2: Description of `arg2`, defaults to 0
+            :type arg2: int, optional
+
+        **If False**::
+
+            :parameters: * **arg1** (*str*) --
+                           Description of `arg1`
+                         * **arg2** (*int, optional*) --
+                           Description of `arg2`, defaults to 0
+
+    napoleon_use_rtype : bool, defaults to True
+        True to use the ``:rtype:`` role for the return type. False to output
+        the return type inline with the description.
+
+        This `NumPy style`_ snippet will be converted as follows::
+
+            Returns
+            -------
+            bool
+                True if successful, False otherwise
+
+        **If True**::
+
+            :returns: True if successful, False otherwise
+            :rtype: bool
+
+        **If False**::
+
+            :returns: *bool* -- True if successful, False otherwise
+
+    """
+    _config_values = {
+        'napoleon_google_docstring': (True, 'env'),
+        'napoleon_numpy_docstring': (True, 'env'),
+        'napoleon_include_private_with_doc': (False, 'env'),
+        'napoleon_include_special_with_doc': (True, 'env'),
+        'napoleon_use_admonition_for_examples': (False, 'env'),
+        'napoleon_use_admonition_for_notes': (False, 'env'),
+        'napoleon_use_admonition_for_references': (False, 'env'),
+        'napoleon_use_ivar': (False, 'env'),
+        'napoleon_use_param': (True, 'env'),
+        'napoleon_use_rtype': (True, 'env'),
+    }
+
+    def __init__(self, **settings):
+        for name, (default, rebuild) in iteritems(self._config_values):
+            setattr(self, name, default)
+        for name, value in iteritems(settings):
+            setattr(self, name, value)
+
+
+def setup(app):
+    """Sphinx extension setup function.
+
+    When the extension is loaded, Sphinx imports this module and executes
+    the ``setup()`` function, which in turn notifies Sphinx of everything
+    the extension offers.
+
+    Parameters
+    ----------
+    app : sphinx.application.Sphinx
+        Application object representing the Sphinx process
+
+    See Also
+    --------
+    The Sphinx documentation on `Extensions`_, the `Extension Tutorial`_, and
+    the `Extension API`_.
+
+    .. _Extensions: http://sphinx-doc.org/extensions.html
+    .. _Extension Tutorial: http://sphinx-doc.org/ext/tutorial.html
+    .. _Extension API: http://sphinx-doc.org/ext/appapi.html
+
+    """
+    from sphinx.application import Sphinx
+    if not isinstance(app, Sphinx):
+        return  # probably called by tests
+
+    app.connect('autodoc-process-docstring', _process_docstring)
+    app.connect('autodoc-skip-member', _skip_member)
+
+    for name, (default, rebuild) in iteritems(Config._config_values):
+        app.add_config_value(name, default, rebuild)
+    return sphinx.__version__
+
+
+def _process_docstring(app, what, name, obj, options, lines):
+    """Process the docstring for a given python object.
+
+    Called when autodoc has read and processed a docstring. `lines` is a list
+    of docstring lines that `_process_docstring` modifies in place to change
+    what Sphinx outputs.
+
+    The following settings in conf.py control what styles of docstrings will
+    be parsed:
+
+    * ``napoleon_google_docstring`` -- parse Google style docstrings
+    * ``napoleon_numpy_docstring`` -- parse NumPy style docstrings
+
+    Parameters
+    ----------
+    app : sphinx.application.Sphinx
+        Application object representing the Sphinx process.
+    what : str
+        A string specifying the type of the object to which the docstring
+        belongs. Valid values: "module", "class", "exception", "function",
+        "method", "attribute".
+    name : str
+        The fully qualified name of the object.
+    obj : module, class, exception, function, method, or attribute
+        The object to which the docstring belongs.
+    options : sphinx.ext.autodoc.Options
+        The options given to the directive: an object with attributes
+        inherited_members, undoc_members, show_inheritance and noindex that
+        are True if the flag option of same name was given to the auto
+        directive.
+    lines : list of str
+        The lines of the docstring, see above.
+
+        .. note:: `lines` is modified *in place*
+
+    """
+    result_lines = lines
+    if app.config.napoleon_numpy_docstring:
+        docstring = NumpyDocstring(result_lines, app.config, app, what, name,
+                                   obj, options)
+        result_lines = docstring.lines()
+    if app.config.napoleon_google_docstring:
+        docstring = GoogleDocstring(result_lines, app.config, app, what, name,
+                                    obj, options)
+        result_lines = docstring.lines()
+    lines[:] = result_lines[:]
+
+
+def _skip_member(app, what, name, obj, skip, options):
+    """Determine if private and special class members are included in docs.
+
+    The following settings in conf.py determine if private and special class
+    members are included in the generated documentation:
+
+    * ``napoleon_include_private_with_doc`` --
+      include private members if they have docstrings
+    * ``napoleon_include_special_with_doc`` --
+      include special members if they have docstrings
+
+    Parameters
+    ----------
+    app : sphinx.application.Sphinx
+        Application object representing the Sphinx process
+    what : str
+        A string specifying the type of the object to which the member
+        belongs. Valid values: "module", "class", "exception", "function",
+        "method", "attribute".
+    name : str
+        The name of the member.
+    obj : module, class, exception, function, method, or attribute.
+        For example, if the member is the __init__ method of class A, then
+        `obj` will be `A.__init__`.
+    skip : bool
+        A boolean indicating if autodoc will skip this member if `_skip_member`
+        does not override the decision
+    options : sphinx.ext.autodoc.Options
+        The options given to the directive: an object with attributes
+        inherited_members, undoc_members, show_inheritance and noindex that
+        are True if the flag option of same name was given to the auto
+        directive.
+
+    Returns
+    -------
+    bool
+        True if the member should be skipped during creation of the docs,
+        False if it should be included in the docs.
+
+    """
+    has_doc = getattr(obj, '__doc__', False)
+    is_member = (what == 'class' or what == 'exception' or what == 'module')
+    if name != '__weakref__' and name != '__init__' and has_doc and is_member:
+        cls_is_owner = False
+        if what == 'class' or what == 'exception':
+            if PY2:
+                cls = getattr(obj, 'im_class', getattr(obj, '__objclass__',
+                              None))
+                cls_is_owner = (cls and hasattr(cls, name) and
+                                name in cls.__dict__)
+            elif sys.version_info >= (3, 3):
+                qualname = getattr(obj, '__qualname__', '')
+                cls_path, _, _ = qualname.rpartition('.')
+                if cls_path:
+                    try:
+                        if '.' in cls_path:
+                            import importlib
+                            import functools
+
+                            mod = importlib.import_module(obj.__module__)
+                            mod_path = cls_path.split('.')
+                            cls = functools.reduce(getattr, mod_path, mod)
+                        else:
+                            cls = obj.__globals__[cls_path]
+                    except:
+                        cls_is_owner = False
+                    else:
+                        cls_is_owner = (cls and hasattr(cls, name) and
+                                        name in cls.__dict__)
+                else:
+                    cls_is_owner = False
+            else:
+                cls_is_owner = True
+
+        if what == 'module' or cls_is_owner:
+            is_special = name.startswith('__') and name.endswith('__')
+            is_private = not is_special and name.startswith('_')
+            inc_special = app.config.napoleon_include_special_with_doc
+            inc_private = app.config.napoleon_include_private_with_doc
+            if (is_special and inc_special) or (is_private and inc_private):
+                return False
+    return skip
diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py
new file mode 100644
index 0000000..19f5f39
--- /dev/null
+++ b/sphinx/ext/napoleon/docstring.py
@@ -0,0 +1,860 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.ext.napoleon.docstring
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+    Classes for docstring parsing and formatting.
+
+
+    :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import collections
+import inspect
+import re
+
+from six import string_types
+from six.moves import range
+
+from sphinx.ext.napoleon.iterators import modify_iter
+from sphinx.util.pycompat import UnicodeMixin
+
+
+_directive_regex = re.compile(r'\.\. \S+::')
+_google_untyped_arg_regex = re.compile(r'\s*(\w+)\s*:\s*(.*)')
+_google_typed_arg_regex = re.compile(r'\s*(\w+)\s*\(\s*(.+?)\s*\)\s*:\s*(.*)')
+
+
+class GoogleDocstring(UnicodeMixin):
+    """Parse Google style docstrings.
+
+    Convert Google style docstrings to reStructuredText.
+
+    Parameters
+    ----------
+    docstring : str or list of str
+        The docstring to parse, given either as a string or split into
+        individual lines.
+    config : sphinx.ext.napoleon.Config or sphinx.config.Config, optional
+        The configuration settings to use. If not given, defaults to the
+        config object on `app`; or if `app` is not given defaults to the
+        a new `sphinx.ext.napoleon.Config` object.
+
+        See Also
+        --------
+        :class:`sphinx.ext.napoleon.Config`
+
+    Other Parameters
+    ----------------
+    app : sphinx.application.Sphinx, optional
+        Application object representing the Sphinx process.
+    what : str, optional
+        A string specifying the type of the object to which the docstring
+        belongs. Valid values: "module", "class", "exception", "function",
+        "method", "attribute".
+    name : str, optional
+        The fully qualified name of the object.
+    obj : module, class, exception, function, method, or attribute
+        The object to which the docstring belongs.
+    options : sphinx.ext.autodoc.Options, optional
+        The options given to the directive: an object with attributes
+        inherited_members, undoc_members, show_inheritance and noindex that
+        are True if the flag option of same name was given to the auto
+        directive.
+
+    Example
+    -------
+    >>> from sphinx.ext.napoleon import Config
+    >>> config = Config(napoleon_use_param=True, napoleon_use_rtype=True)
+    >>> docstring = '''One line summary.
+    ...
+    ... Extended description.
+    ...
+    ... Args:
+    ...   arg1(int): Description of `arg1`
+    ...   arg2(str): Description of `arg2`
+    ... Returns:
+    ...   str: Description of return value.
+    ... '''
+    >>> print(GoogleDocstring(docstring, config))
+    One line summary.
+    <BLANKLINE>
+    Extended description.
+    <BLANKLINE>
+    :param arg1: Description of `arg1`
+    :type arg1: int
+    :param arg2: Description of `arg2`
+    :type arg2: str
+    <BLANKLINE>
+    :returns: Description of return value.
+    :rtype: str
+
+    """
+    def __init__(self, docstring, config=None, app=None, what='', name='',
+                 obj=None, options=None):
+        self._config = config
+        self._app = app
+
+        if not self._config:
+            from sphinx.ext.napoleon import Config
+            self._config = self._app and self._app.config or Config()
+
+        if not what:
+            if inspect.isclass(obj):
+                what = 'class'
+            elif inspect.ismodule(obj):
+                what = 'module'
+            elif isinstance(obj, collections.Callable):
+                what = 'function'
+            else:
+                what = 'object'
+
+        self._what = what
+        self._name = name
+        self._obj = obj
+        self._opt = options
+        if isinstance(docstring, string_types):
+            docstring = docstring.splitlines()
+        self._lines = docstring
+        self._line_iter = modify_iter(docstring, modifier=lambda s: s.rstrip())
+        self._parsed_lines = []
+        self._is_in_section = False
+        self._section_indent = 0
+        if not hasattr(self, '_directive_sections'):
+            self._directive_sections = []
+        if not hasattr(self, '_sections'):
+            self._sections = {
+                'args': self._parse_parameters_section,
+                'arguments': self._parse_parameters_section,
+                'attributes': self._parse_attributes_section,
+                'example': self._parse_examples_section,
+                'examples': self._parse_examples_section,
+                'keyword args': self._parse_keyword_arguments_section,
+                'keyword arguments': self._parse_keyword_arguments_section,
+                'methods': self._parse_methods_section,
+                'note': self._parse_note_section,
+                'notes': self._parse_notes_section,
+                'other parameters': self._parse_other_parameters_section,
+                'parameters': self._parse_parameters_section,
+                'return': self._parse_returns_section,
+                'returns': self._parse_returns_section,
+                'raises': self._parse_raises_section,
+                'references': self._parse_references_section,
+                'see also': self._parse_see_also_section,
+                'warning': self._parse_warning_section,
+                'warnings': self._parse_warning_section,
+                'warns': self._parse_warns_section,
+                'yields': self._parse_yields_section,
+            }
+        self._parse()
+
+    def __unicode__(self):
+        """Return the parsed docstring in reStructuredText format.
+
+        Returns
+        -------
+        unicode
+            Unicode version of the docstring.
+
+        """
+        return u'\n'.join(self.lines())
+
+    def lines(self):
+        """Return the parsed lines of the docstring in reStructuredText format.
+
+        Returns
+        -------
+        list of str
+            The lines of the docstring in a list.
+
+        """
+        return self._parsed_lines
+
+    def _consume_indented_block(self, indent=1):
+        lines = []
+        line = self._line_iter.peek()
+        while(not self._is_section_break()
+              and (not line or self._is_indented(line, indent))):
+            lines.append(next(self._line_iter))
+            line = self._line_iter.peek()
+        return lines
+
+    def _consume_contiguous(self):
+        lines = []
+        while (self._line_iter.has_next()
+               and self._line_iter.peek()
+               and not self._is_section_header()):
+            lines.append(next(self._line_iter))
+        return lines
+
+    def _consume_empty(self):
+        lines = []
+        line = self._line_iter.peek()
+        while self._line_iter.has_next() and not line:
+            lines.append(next(self._line_iter))
+            line = self._line_iter.peek()
+        return lines
+
+    def _consume_field(self, parse_type=True, prefer_type=False):
+        line = next(self._line_iter)
+
+        match = None
+        _name, _type, _desc = line.strip(), '', ''
+        if parse_type:
+            match = _google_typed_arg_regex.match(line)
+            if match:
+                _name = match.group(1)
+                _type = match.group(2)
+                _desc = match.group(3)
+
+        if not match:
+            match = _google_untyped_arg_regex.match(line)
+            if match:
+                _name = match.group(1)
+                _desc = match.group(2)
+
+        if prefer_type and not _type:
+            _type, _name = _name, _type
+        indent = self._get_indent(line) + 1
+        _desc = [_desc] + self._dedent(self._consume_indented_block(indent))
+        _desc = self.__class__(_desc, self._config).lines()
+        return _name, _type, _desc
+
+    def _consume_fields(self, parse_type=True, prefer_type=False):
+        self._consume_empty()
+        fields = []
+        while not self._is_section_break():
+            _name, _type, _desc = self._consume_field(parse_type, prefer_type)
+            if _name or _type or _desc:
+                fields.append((_name, _type, _desc,))
+        return fields
+
+    def _consume_returns_section(self):
+        lines = self._dedent(self._consume_to_next_section())
+        if lines:
+            _name, _type, _desc = '', '', lines
+            match = _google_typed_arg_regex.match(lines[0])
+            if match:
+                _name = match.group(1)
+                _type = match.group(2)
+                _desc = match.group(3)
+            else:
+                match = _google_untyped_arg_regex.match(lines[0])
+                if match:
+                    _type = match.group(1)
+                    _desc = match.group(2)
+            if match:
+                lines[0] = _desc
+                _desc = lines
+
+            _desc = self.__class__(_desc, self._config).lines()
+            return [(_name, _type, _desc,)]
+        else:
+            return []
+
+    def _consume_section_header(self):
+        section = next(self._line_iter)
+        stripped_section = section.strip(':')
+        if stripped_section.lower() in self._sections:
+            section = stripped_section
+        return section
+
+    def _consume_to_next_section(self):
+        self._consume_empty()
+        lines = []
+        while not self._is_section_break():
+            lines.append(next(self._line_iter))
+        return lines + self._consume_empty()
+
+    def _dedent(self, lines, full=False):
+        if full:
+            return [line.lstrip() for line in lines]
+        else:
+            min_indent = self._get_min_indent(lines)
+            return [line[min_indent:] for line in lines]
+
+    def _format_admonition(self, admonition, lines):
+        lines = self._strip_empty(lines)
+        if len(lines) == 1:
+            return ['.. %s:: %s' % (admonition, lines[0].strip()), '']
+        elif lines:
+            lines = self._indent(self._dedent(lines), 3)
+            return ['.. %s::' % admonition, ''] + lines + ['']
+        else:
+            return ['.. %s::' % admonition, '']
+
+    def _format_block(self, prefix, lines, padding=None):
+        if lines:
+            if padding is None:
+                padding = ' ' * len(prefix)
+            result_lines = []
+            for i, line in enumerate(lines):
+                if line:
+                    if i == 0:
+                        result_lines.append(prefix + line)
+                    else:
+                        result_lines.append(padding + line)
+                else:
+                    result_lines.append('')
+            return result_lines
+        else:
+            return [prefix]
+
+    def _format_field(self, _name, _type, _desc):
+        separator = any([s for s in _desc]) and ' --' or ''
+        if _name:
+            if _type:
+                if '`' in _type:
+                    field = ['**%s** (%s)%s' % (_name, _type, separator)]
+                else:
+                    field = ['**%s** (*%s*)%s' % (_name, _type, separator)]
+            else:
+                field = ['**%s**%s' % (_name, separator)]
+        elif _type:
+            if '`' in _type:
+                field = ['%s%s' % (_type, separator)]
+            else:
+                field = ['*%s*%s' % (_type, separator)]
+        else:
+            field = []
+        return field + _desc
+
+    def _format_fields(self, field_type, fields):
+        field_type = ':%s:' % field_type.strip()
+        padding = ' ' * len(field_type)
+        multi = len(fields) > 1
+        lines = []
+        for _name, _type, _desc in fields:
+            field = self._format_field(_name, _type, _desc)
+            if multi:
+                if lines:
+                    lines.extend(self._format_block(padding + ' * ', field))
+                else:
+                    lines.extend(self._format_block(field_type + ' * ', field))
+            else:
+                lines.extend(self._format_block(field_type + ' ', field))
+        return lines
+
+    def _get_current_indent(self, peek_ahead=0):
+        line = self._line_iter.peek(peek_ahead + 1)[peek_ahead]
+        while line != self._line_iter.sentinel:
+            if line:
+                return self._get_indent(line)
+            peek_ahead += 1
+            line = self._line_iter.peek(peek_ahead + 1)[peek_ahead]
+        return 0
+
+    def _get_indent(self, line):
+        for i, s in enumerate(line):
+            if not s.isspace():
+                return i
+        return len(line)
+
+    def _get_min_indent(self, lines):
+        min_indent = None
+        for line in lines:
+            if line:
+                indent = self._get_indent(line)
+                if min_indent is None:
+                    min_indent = indent
+                elif indent < min_indent:
+                    min_indent = indent
+        return min_indent or 0
+
+    def _indent(self, lines, n=4):
+        return [(' ' * n) + line for line in lines]
+
+    def _is_indented(self, line, indent=1):
+        for i, s in enumerate(line):
+            if i >= indent:
+                return True
+            elif not s.isspace():
+                return False
+        return False
+
+    def _is_section_header(self):
+        section = self._line_iter.peek().lower()
+        if section.strip(':') in self._sections:
+            header_indent = self._get_indent(section)
+            section_indent = self._get_current_indent(peek_ahead=1)
+            return section_indent > header_indent
+        elif self._directive_sections:
+            if _directive_regex.match(section):
+                for directive_section in self._directive_sections:
+                    if section.startswith(directive_section):
+                        return True
+        return False
+
+    def _is_section_break(self):
+        line = self._line_iter.peek()
+        return (not self._line_iter.has_next()
+                or self._is_section_header()
+                or (self._is_in_section
+                    and line
+                    and not self._is_indented(line, self._section_indent)))
+
+    def _parse(self):
+        self._parsed_lines = self._consume_empty()
+        while self._line_iter.has_next():
+            if self._is_section_header():
+                try:
+                    section = self._consume_section_header()
+                    self._is_in_section = True
+                    self._section_indent = self._get_current_indent()
+                    if _directive_regex.match(section):
+                        lines = [section] + self._consume_to_next_section()
+                    else:
+                        lines = self._sections[section.lower()](section)
+                finally:
+                    self._is_in_section = False
+                    self._section_indent = 0
+            else:
+                if not self._parsed_lines:
+                    lines = self._consume_contiguous() + self._consume_empty()
+                else:
+                    lines = self._consume_to_next_section()
+            self._parsed_lines.extend(lines)
+
+    def _parse_attributes_section(self, section):
+        lines = []
+        for _name, _type, _desc in self._consume_fields():
+            if self._config.napoleon_use_ivar:
+                field = ':ivar %s: ' % _name
+                lines.extend(self._format_block(field, _desc))
+                if _type:
+                    lines.append(':vartype %s: %s' % (_name, _type))
+            else:
+                lines.append('.. attribute:: ' + _name)
+                if _type:
+                    lines.append('')
+                    if '`' in _type:
+                        lines.append('   %s' % _type)
+                    else:
+                        lines.append('   *%s*' % _type)
+                if _desc:
+                    lines.extend([''] + self._indent(_desc, 3))
+                lines.append('')
+        if self._config.napoleon_use_ivar:
+            lines.append('')
+        return lines
+
+    def _parse_examples_section(self, section):
+        use_admonition = self._config.napoleon_use_admonition_for_examples
+        return self._parse_generic_section(section, use_admonition)
+
+    def _parse_generic_section(self, section, use_admonition):
+        lines = self._strip_empty(self._consume_to_next_section())
+        lines = self._dedent(lines)
+        if use_admonition:
+            header = '.. admonition:: %s' % section
+            lines = self._indent(lines, 3)
+        else:
+            header = '.. rubric:: %s' % section
+        if lines:
+            return [header, ''] + lines + ['']
+        else:
+            return [header, '']
+
+    def _parse_keyword_arguments_section(self, section):
+        return self._format_fields('Keyword Arguments', self._consume_fields())
+
+    def _parse_methods_section(self, section):
+        lines = []
+        for _name, _, _desc in self._consume_fields(parse_type=False):
+            lines.append('.. method:: %s' % _name)
+            if _desc:
+                lines.extend([''] + self._indent(_desc, 3))
+            lines.append('')
+        return lines
+
+    def _parse_note_section(self, section):
+        lines = self._consume_to_next_section()
+        return self._format_admonition('note', lines)
+
+    def _parse_notes_section(self, section):
+        use_admonition = self._config.napoleon_use_admonition_for_notes
+        return self._parse_generic_section('Notes', use_admonition)
+
+    def _parse_other_parameters_section(self, section):
+        return self._format_fields('Other Parameters', self._consume_fields())
+
+    def _parse_parameters_section(self, section):
+        fields = self._consume_fields()
+        if self._config.napoleon_use_param:
+            lines = []
+            for _name, _type, _desc in fields:
+                field = ':param %s: ' % _name
+                lines.extend(self._format_block(field, _desc))
+                if _type:
+                    lines.append(':type %s: %s' % (_name, _type))
+            return lines + ['']
+        else:
+            return self._format_fields('Parameters', fields)
+
+    def _parse_raises_section(self, section):
+        fields = self._consume_fields()
+        field_type = ':raises:'
+        padding = ' ' * len(field_type)
+        multi = len(fields) > 1
+        lines = []
+        for _name, _type, _desc in fields:
+            sep = _desc and ' -- ' or ''
+            if _name:
+                if ' ' in _name:
+                    _name = '**%s**' % _name
+                else:
+                    _name = ':exc:`%s`' % _name
+                if _type:
+                    if '`' in _type:
+                        field = ['%s (%s)%s' % (_name, _type, sep)]
+                    else:
+                        field = ['%s (*%s*)%s' % (_name, _type, sep)]
+                else:
+                    field = ['%s%s' % (_name, sep)]
+            elif _type:
+                if '`' in _type:
+                    field = ['%s%s' % (_type, sep)]
+                else:
+                    field = ['*%s*%s' % (_type, sep)]
+            else:
+                field = []
+            field = field + _desc
+            if multi:
+                if lines:
+                    lines.extend(self._format_block(padding + ' * ', field))
+                else:
+                    lines.extend(self._format_block(field_type + ' * ', field))
+            else:
+                lines.extend(self._format_block(field_type + ' ', field))
+        return lines
+
+    def _parse_references_section(self, section):
+        use_admonition = self._config.napoleon_use_admonition_for_references
+        return self._parse_generic_section('References', use_admonition)
+
+    def _parse_returns_section(self, section):
+        fields = self._consume_returns_section()
+        multi = len(fields) > 1
+        if multi:
+            use_rtype = False
+        else:
+            use_rtype = self._config.napoleon_use_rtype
+
+        lines = []
+        for _name, _type, _desc in fields:
+            if use_rtype:
+                field = self._format_field(_name, '', _desc)
+            else:
+                field = self._format_field(_name, _type, _desc)
+
+            if multi:
+                if lines:
+                    lines.extend(self._format_block('          * ', field))
+                else:
+                    lines.extend(self._format_block(':returns: * ', field))
+            else:
+                lines.extend(self._format_block(':returns: ', field))
+                if _type and use_rtype:
+                    lines.append(':rtype: %s' % _type)
+                    lines.append('')
+        return lines
+
+    def _parse_see_also_section(self, section):
+        lines = self._consume_to_next_section()
+        return self._format_admonition('seealso', lines)
+
+    def _parse_warning_section(self, section):
+        lines = self._consume_to_next_section()
+        return self._format_admonition('warning', lines)
+
+    def _parse_warns_section(self, section):
+        return self._format_fields('Warns', self._consume_fields())
+
+    def _parse_yields_section(self, section):
+        fields = self._consume_fields(prefer_type=True)
+        return self._format_fields('Yields', fields)
+
+    def _strip_empty(self, lines):
+        if lines:
+            start = -1
+            for i, line in enumerate(lines):
+                if line:
+                    start = i
+                    break
+            if start == -1:
+                lines = []
+            end = -1
+            for i in reversed(range(len(lines))):
+                line = lines[i]
+                if line:
+                    end = i
+                    break
+            if start > 0 or end + 1 < len(lines):
+                lines = lines[start:end + 1]
+        return lines
+
+
+class NumpyDocstring(GoogleDocstring):
+    """Parse NumPy style docstrings.
+
+    Convert NumPy style docstrings to reStructuredText.
+
+    Parameters
+    ----------
+    docstring : str or list of str
+        The docstring to parse, given either as a string or split into
+        individual lines.
+    config : sphinx.ext.napoleon.Config or sphinx.config.Config, optional
+        The configuration settings to use. If not given, defaults to the
+        config object on `app`; or if `app` is not given defaults to the
+        a new `sphinx.ext.napoleon.Config` object.
+
+        See Also
+        --------
+        :class:`sphinx.ext.napoleon.Config`
+
+    Other Parameters
+    ----------------
+    app : sphinx.application.Sphinx, optional
+        Application object representing the Sphinx process.
+    what : str, optional
+        A string specifying the type of the object to which the docstring
+        belongs. Valid values: "module", "class", "exception", "function",
+        "method", "attribute".
+    name : str, optional
+        The fully qualified name of the object.
+    obj : module, class, exception, function, method, or attribute
+        The object to which the docstring belongs.
+    options : sphinx.ext.autodoc.Options, optional
+        The options given to the directive: an object with attributes
+        inherited_members, undoc_members, show_inheritance and noindex that
+        are True if the flag option of same name was given to the auto
+        directive.
+
+    Example
+    -------
+    >>> from sphinx.ext.napoleon import Config
+    >>> config = Config(napoleon_use_param=True, napoleon_use_rtype=True)
+    >>> docstring = '''One line summary.
+    ...
+    ... Extended description.
+    ...
+    ... Parameters
+    ... ----------
+    ... arg1 : int
+    ...     Description of `arg1`
+    ... arg2 : str
+    ...     Description of `arg2`
+    ... Returns
+    ... -------
+    ... str
+    ...     Description of return value.
+    ... '''
+    >>> print(NumpyDocstring(docstring, config))
+    One line summary.
+    <BLANKLINE>
+    Extended description.
+    <BLANKLINE>
+    :param arg1: Description of `arg1`
+    :type arg1: int
+    :param arg2: Description of `arg2`
+    :type arg2: str
+    <BLANKLINE>
+    :returns: Description of return value.
+    :rtype: str
+
+    Methods
+    -------
+    __str__()
+        Return the parsed docstring in reStructuredText format.
+
+        Returns
+        -------
+        str
+            UTF-8 encoded version of the docstring.
+
+    __unicode__()
+        Return the parsed docstring in reStructuredText format.
+
+        Returns
+        -------
+        unicode
+            Unicode version of the docstring.
+
+    lines()
+        Return the parsed lines of the docstring in reStructuredText format.
+
+        Returns
+        -------
+        list of str
+            The lines of the docstring in a list.
+
+    """
+    def __init__(self, docstring, config=None, app=None, what='', name='',
+                 obj=None, options=None):
+        self._directive_sections = ['.. index::']
+        super(NumpyDocstring, self).__init__(docstring, config, app, what,
+                                             name, obj, options)
+
+    def _consume_field(self, parse_type=True, prefer_type=False):
+        line = next(self._line_iter)
+        if parse_type:
+            _name, _, _type = line.partition(':')
+        else:
+            _name, _type = line, ''
+        _name, _type = _name.strip(), _type.strip()
+        if prefer_type and not _type:
+            _type, _name = _name, _type
+        indent = self._get_indent(line)
+        _desc = self._dedent(self._consume_indented_block(indent + 1))
+        _desc = self.__class__(_desc, self._config).lines()
+        return _name, _type, _desc
+
+    def _consume_returns_section(self):
+        return self._consume_fields(prefer_type=True)
+
+    def _consume_section_header(self):
+        section = next(self._line_iter)
+        if not _directive_regex.match(section):
+            # Consume the header underline
+            next(self._line_iter)
+        return section
+
+    def _is_section_break(self):
+        line1, line2 = self._line_iter.peek(2)
+        return (not self._line_iter.has_next()
+                or self._is_section_header()
+                or ['', ''] == [line1, line2]
+                or (self._is_in_section
+                    and line1
+                    and not self._is_indented(line1, self._section_indent)))
+
+    def _is_section_header(self):
+        section, underline = self._line_iter.peek(2)
+        section = section.lower()
+        if section in self._sections and isinstance(underline, string_types):
+            pattern = r'[=\-`:\'"~^_*+#<>]{' + str(len(section)) + r'}$'
+            return bool(re.match(pattern, underline))
+        elif self._directive_sections:
+            if _directive_regex.match(section):
+                for directive_section in self._directive_sections:
+                    if section.startswith(directive_section):
+                        return True
+        return False
+
+    _name_rgx = re.compile(r"^\s*(:(?P<role>\w+):`(?P<name>[a-zA-Z0-9_.-]+)`|"
+                           r" (?P<name2>[a-zA-Z0-9_.-]+))\s*", re.X)
+
+    def _parse_see_also_section(self, section):
+        lines = self._consume_to_next_section()
+        try:
+            return self._parse_numpydoc_see_also_section(lines)
+        except ValueError:
+            return self._format_admonition('seealso', lines)
+
+    def _parse_numpydoc_see_also_section(self, content):
+        """
+        Derived from the NumpyDoc implementation of _parse_see_also.
+
+        func_name : Descriptive text
+            continued text
+        another_func_name : Descriptive text
+        func_name1, func_name2, :meth:`func_name`, func_name3
+
+        """
+        items = []
+
+        def parse_item_name(text):
+            """Match ':role:`name`' or 'name'"""
+            m = self._name_rgx.match(text)
+            if m:
+                g = m.groups()
+                if g[1] is None:
+                    return g[3], None
+                else:
+                    return g[2], g[1]
+            raise ValueError("%s is not a item name" % text)
+
+        def push_item(name, rest):
+            if not name:
+                return
+            name, role = parse_item_name(name)
+            items.append((name, list(rest), role))
+            del rest[:]
+
+        current_func = None
+        rest = []
+
+        for line in content:
+            if not line.strip():
+                continue
+
+            m = self._name_rgx.match(line)
+            if m and line[m.end():].strip().startswith(':'):
+                push_item(current_func, rest)
+                current_func, line = line[:m.end()], line[m.end():]
+                rest = [line.split(':', 1)[1].strip()]
+                if not rest[0]:
+                    rest = []
+            elif not line.startswith(' '):
+                push_item(current_func, rest)
+                current_func = None
+                if ',' in line:
+                    for func in line.split(','):
+                        if func.strip():
+                            push_item(func, [])
+                elif line.strip():
+                    current_func = line
+            elif current_func is not None:
+                rest.append(line.strip())
+        push_item(current_func, rest)
+
+        if not items:
+            return []
+
+        roles = {
+            'method': 'meth',
+            'meth': 'meth',
+            'function': 'func',
+            'func': 'func',
+            'class': 'class',
+            'exception': 'exc',
+            'exc': 'exc',
+            'object': 'obj',
+            'obj': 'obj',
+            'module': 'mod',
+            'mod': 'mod',
+            'data': 'data',
+            'constant': 'const',
+            'const': 'const',
+            'attribute': 'attr',
+            'attr': 'attr'
+        }
+        if self._what is None:
+            func_role = 'obj'
+        else:
+            func_role = roles.get(self._what, '')
+        lines = []
+        last_had_desc = True
+        for func, desc, role in items:
+            if role:
+                link = ':%s:`%s`' % (role, func)
+            elif func_role:
+                link = ':%s:`%s`' % (func_role, func)
+            else:
+                link = "`%s`_" % func
+            if desc or last_had_desc:
+                lines += ['']
+                lines += [link]
+            else:
+                lines[-1] += ", %s" % link
+            if desc:
+                lines += self._indent([' '.join(desc)])
+                last_had_desc = True
+            else:
+                last_had_desc = False
+        lines += ['']
+
+        return self._format_admonition('seealso', lines)
diff --git a/sphinx/ext/napoleon/iterators.py b/sphinx/ext/napoleon/iterators.py
new file mode 100644
index 0000000..482fe1d
--- /dev/null
+++ b/sphinx/ext/napoleon/iterators.py
@@ -0,0 +1,239 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.ext.napoleon.iterators
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+    A collection of helpful iterators.
+
+
+    :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import collections
+
+
+class peek_iter(object):
+    """An iterator object that supports peeking ahead.
+
+    Parameters
+    ----------
+    o : iterable or callable
+        `o` is interpreted very differently depending on the presence of
+        `sentinel`.
+
+        If `sentinel` is not given, then `o` must be a collection object
+        which supports either the iteration protocol or the sequence protocol.
+
+        If `sentinel` is given, then `o` must be a callable object.
+
+    sentinel : any value, optional
+        If given, the iterator will call `o` with no arguments for each
+        call to its `next` method; if the value returned is equal to
+        `sentinel`, :exc:`StopIteration` will be raised, otherwise the
+        value will be returned.
+
+    See Also
+    --------
+    `peek_iter` can operate as a drop in replacement for the built-in
+    `iter <http://docs.python.org/2/library/functions.html#iter>`_ function.
+
+    Attributes
+    ----------
+    sentinel
+        The value used to indicate the iterator is exhausted. If `sentinel`
+        was not given when the `peek_iter` was instantiated, then it will
+        be set to a new object instance: ``object()``.
+
+    """
+    def __init__(self, *args):
+        """__init__(o, sentinel=None)"""
+        self._iterable = iter(*args)
+        self._cache = collections.deque()
+        if len(args) == 2:
+            self.sentinel = args[1]
+        else:
+            self.sentinel = object()
+
+    def __iter__(self):
+        return self
+
+    def __next__(self, n=None):
+        # note: prevent 2to3 to transform self.next() in next(self) which
+        # causes an infinite loop !
+        return getattr(self, 'next')(n)
+
+    def _fillcache(self, n):
+        """Cache `n` items. If `n` is 0 or None, then 1 item is cached."""
+        if not n:
+            n = 1
+        try:
+            while len(self._cache) < n:
+                self._cache.append(next(self._iterable))
+        except StopIteration:
+            while len(self._cache) < n:
+                self._cache.append(self.sentinel)
+
+    def has_next(self):
+        """Determine if iterator is exhausted.
+
+        Returns
+        -------
+        bool
+            True if iterator has more items, False otherwise.
+
+        Note
+        ----
+        Will never raise :exc:`StopIteration`.
+
+        """
+        return self.peek() != self.sentinel
+
+    def next(self, n=None):
+        """Get the next item or `n` items of the iterator.
+
+        Parameters
+        ----------
+        n : int or None
+            The number of items to retrieve. Defaults to None.
+
+        Returns
+        -------
+        item or list of items
+            The next item or `n` items of the iterator. If `n` is None, the
+            item itself is returned. If `n` is an int, the items will be
+            returned in a list. If `n` is 0, an empty list is returned.
+
+        Raises
+        ------
+        StopIteration
+            Raised if the iterator is exhausted, even if `n` is 0.
+
+        """
+        self._fillcache(n)
+        if not n:
+            if self._cache[0] == self.sentinel:
+                raise StopIteration
+            if n is None:
+                result = self._cache.popleft()
+            else:
+                result = []
+        else:
+            if self._cache[n - 1] == self.sentinel:
+                raise StopIteration
+            result = [self._cache.popleft() for i in range(n)]
+        return result
+
+    def peek(self, n=None):
+        """Preview the next item or `n` items of the iterator.
+
+        The iterator is not advanced when peek is called.
+
+        Returns
+        -------
+        item or list of items
+            The next item or `n` items of the iterator. If `n` is None, the
+            item itself is returned. If `n` is an int, the items will be
+            returned in a list. If `n` is 0, an empty list is returned.
+
+            If the iterator is exhausted, `peek_iter.sentinel` is returned,
+            or placed as the last item in the returned list.
+
+        Note
+        ----
+        Will never raise :exc:`StopIteration`.
+
+        """
+        self._fillcache(n)
+        if n is None:
+            result = self._cache[0]
+        else:
+            result = [self._cache[i] for i in range(n)]
+        return result
+
+
+class modify_iter(peek_iter):
+    """An iterator object that supports modifying items as they are returned.
+
+    Parameters
+    ----------
+    o : iterable or callable
+        `o` is interpreted very differently depending on the presence of
+        `sentinel`.
+
+        If `sentinel` is not given, then `o` must be a collection object
+        which supports either the iteration protocol or the sequence protocol.
+
+        If `sentinel` is given, then `o` must be a callable object.
+
+    sentinel : any value, optional
+        If given, the iterator will call `o` with no arguments for each
+        call to its `next` method; if the value returned is equal to
+        `sentinel`, :exc:`StopIteration` will be raised, otherwise the
+        value will be returned.
+
+    modifier : callable, optional
+        The function that will be used to modify each item returned by the
+        iterator. `modifier` should take a single argument and return a
+        single value. Defaults to ``lambda x: x``.
+
+        If `sentinel` is not given, `modifier` must be passed as a keyword
+        argument.
+
+    Attributes
+    ----------
+    modifier : callable
+        `modifier` is called with each item in `o` as it is iterated. The
+        return value of `modifier` is returned in lieu of the item.
+
+        Values returned by `peek` as well as `next` are affected by
+        `modifier`. However, `modify_iter.sentinel` is never passed through
+        `modifier`; it will always be returned from `peek` unmodified.
+
+    Example
+    -------
+    >>> a = ["     A list    ",
+    ...      "   of strings  ",
+    ...      "      with     ",
+    ...      "      extra    ",
+    ...      "   whitespace. "]
+    >>> modifier = lambda s: s.strip().replace('with', 'without')
+    >>> for s in modify_iter(a, modifier=modifier):
+    ...   print('"%s"' % s)
+    "A list"
+    "of strings"
+    "without"
+    "extra"
+    "whitespace."
+
+    """
+    def __init__(self, *args, **kwargs):
+        """__init__(o, sentinel=None, modifier=lambda x: x)"""
+        if 'modifier' in kwargs:
+            self.modifier = kwargs['modifier']
+        elif len(args) > 2:
+            self.modifier = args[2]
+            args = args[:2]
+        else:
+            self.modifier = lambda x: x
+        if not callable(self.modifier):
+            raise TypeError('modify_iter(o, modifier): '
+                            'modifier must be callable')
+        super(modify_iter, self).__init__(*args)
+
+    def _fillcache(self, n):
+        """Cache `n` modified items. If `n` is 0 or None, 1 item is cached.
+
+        Each item returned by the iterator is passed through the
+        `modify_iter.modified` function before being cached.
+
+        """
+        if not n:
+            n = 1
+        try:
+            while len(self._cache) < n:
+                self._cache.append(self.modifier(next(self._iterable)))
+        except StopIteration:
+            while len(self._cache) < n:
+                self._cache.append(self.sentinel)
diff --git a/sphinx/ext/oldcmarkup.py b/sphinx/ext/oldcmarkup.py
deleted file mode 100644
index aa10246..0000000
--- a/sphinx/ext/oldcmarkup.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-    sphinx.ext.oldcmarkup
-    ~~~~~~~~~~~~~~~~~~~~~
-
-    Extension for compatibility with old C markup (directives and roles).
-
-    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
-    :license: BSD, see LICENSE for details.
-"""
-
-from docutils.parsers.rst import directives
-
-from sphinx.util.compat import Directive
-
-_warned_oldcmarkup = False
-WARNING_MSG = 'using old C markup; please migrate to new-style markup ' \
-              '(e.g. c:function instead of cfunction), see ' \
-              'http://sphinx-doc.org/domains.html'
-
-
-class OldCDirective(Directive):
-    has_content = True
-    required_arguments = 1
-    optional_arguments = 0
-    final_argument_whitespace = True
-    option_spec = {
-        'noindex': directives.flag,
-        'module': directives.unchanged,
-    }
-
-    def run(self):
-        env = self.state.document.settings.env
-        if not env.app._oldcmarkup_warned:
-            self.state_machine.reporter.warning(WARNING_MSG, line=self.lineno)
-            env.app._oldcmarkup_warned = True
-        newname = 'c:' + self.name[1:]
-        newdir = env.lookup_domain_element('directive', newname)[0]
-        return newdir(newname, self.arguments, self.options,
-                      self.content, self.lineno, self.content_offset,
-                      self.block_text, self.state, self.state_machine).run()
-
-
-def old_crole(typ, rawtext, text, lineno, inliner, options={}, content=[]):
-    env = inliner.document.settings.env
-    if not typ:
-        typ = env.config.default_role
-    if not env.app._oldcmarkup_warned:
-        inliner.reporter.warning(WARNING_MSG, line=lineno)
-        env.app._oldcmarkup_warned = True
-    newtyp = 'c:' + typ[1:]
-    newrole = env.lookup_domain_element('role', newtyp)[0]
-    return newrole(newtyp, rawtext, text, lineno, inliner, options, content)
-
-
-def setup(app):
-    app._oldcmarkup_warned = False
-    app.add_directive('cfunction', OldCDirective)
-    app.add_directive('cmember', OldCDirective)
-    app.add_directive('cmacro', OldCDirective)
-    app.add_directive('ctype', OldCDirective)
-    app.add_directive('cvar', OldCDirective)
-    app.add_role('cdata', old_crole)
-    app.add_role('cfunc', old_crole)
-    app.add_role('cmacro', old_crole)
-    app.add_role('ctype', old_crole)
-    app.add_role('cmember', old_crole)
diff --git a/sphinx/ext/pngmath.py b/sphinx/ext/pngmath.py
index b654630..ee108d1 100644
--- a/sphinx/ext/pngmath.py
+++ b/sphinx/ext/pngmath.py
@@ -16,17 +16,16 @@
 import posixpath
 from os import path, getcwd, chdir
 from subprocess import Popen, PIPE
-try:
-    from hashlib import sha1 as sha
-except ImportError:
-    from sha import sha
+from hashlib import sha1
 
+from six import text_type
 from docutils import nodes
 
+import sphinx
 from sphinx.errors import SphinxError
 from sphinx.util.png import read_png_depth, write_png_depth
 from sphinx.util.osutil import ensuredir, ENOENT
-from sphinx.util.pycompat import b, sys_encoding
+from sphinx.util.pycompat import sys_encoding
 from sphinx.ext.mathbase import setup_math as mathbase_setup, wrap_displaymath
 
 class MathExtError(SphinxError):
@@ -66,7 +65,7 @@
 \end{document}
 '''
 
-depth_re = re.compile(b(r'\[\d+ depth=(-?\d+)\]'))
+depth_re = re.compile(br'\[\d+ depth=(-?\d+)\]')
 
 def render_math(self, math):
     """Render the LaTeX math expression *math* using latex and dvipng.
@@ -85,7 +84,7 @@
     latex = DOC_HEAD + self.builder.config.pngmath_latex_preamble
     latex += (use_preview and DOC_BODY_PREVIEW or DOC_BODY) % math
 
-    shasum = "%s.png" % sha(latex.encode('utf-8')).hexdigest()
+    shasum = "%s.png" % sha1(latex.encode('utf-8')).hexdigest()
     relfn = posixpath.join(self.builder.imgpath, 'math', shasum)
     outfn = path.join(self.builder.outdir, '_images', 'math', shasum)
     if path.isfile(outfn):
@@ -123,7 +122,7 @@
     try:
         try:
             p = Popen(ltx_args, stdout=PIPE, stderr=PIPE)
-        except OSError, err:
+        except OSError as err:
             if err.errno != ENOENT:   # No such file or directory
                 raise
             self.builder.warn('LaTeX command %r cannot be run (needed for math '
@@ -150,7 +149,7 @@
     dvipng_args.append(path.join(tempdir, 'math.dvi'))
     try:
         p = Popen(dvipng_args, stdout=PIPE, stderr=PIPE)
-    except OSError, err:
+    except OSError as err:
         if err.errno != ENOENT:   # No such file or directory
             raise
         self.builder.warn('dvipng command %r cannot be run (needed for math '
@@ -190,8 +189,8 @@
 def html_visit_math(self, node):
     try:
         fname, depth = render_math(self, '$'+node['latex']+'$')
-    except MathExtError, exc:
-        msg = unicode(exc)
+    except MathExtError as exc:
+        msg = text_type(exc)
         sm = nodes.system_message(msg, type='WARNING', level=2,
                                   backrefs=[], source=node['latex'])
         sm.walkabout(self)
@@ -215,7 +214,7 @@
         latex = wrap_displaymath(node['latex'], None)
     try:
         fname, depth = render_math(self, latex)
-    except MathExtError, exc:
+    except MathExtError as exc:
         sm = nodes.system_message(str(exc), type='WARNING', level=2,
                                   backrefs=[], source=node['latex'])
         sm.walkabout(self)
@@ -247,3 +246,4 @@
     app.add_config_value('pngmath_latex_preamble', '', 'html')
     app.add_config_value('pngmath_add_tooltips', True, 'html')
     app.connect('build-finished', cleanup_tempdir)
+    return sphinx.__version__
diff --git a/sphinx/ext/todo.py b/sphinx/ext/todo.py
index 9f521fb..d70617b 100644
--- a/sphinx/ext/todo.py
+++ b/sphinx/ext/todo.py
@@ -14,6 +14,7 @@
 
 from docutils import nodes
 
+import sphinx
 from sphinx.locale import _
 from sphinx.environment import NoUri
 from sphinx.util.nodes import set_source_info
@@ -171,4 +172,4 @@
     app.connect('doctree-read', process_todos)
     app.connect('doctree-resolved', process_todo_nodes)
     app.connect('env-purge-doc', purge_todos)
-
+    return sphinx.__version__
diff --git a/sphinx/ext/viewcode.py b/sphinx/ext/viewcode.py
index 74a0046..3653a2d 100644
--- a/sphinx/ext/viewcode.py
+++ b/sphinx/ext/viewcode.py
@@ -9,37 +9,61 @@
     :license: BSD, see LICENSE for details.
 """
 
+import traceback
+
+from six import iteritems, text_type
 from docutils import nodes
 
+import sphinx
 from sphinx import addnodes
 from sphinx.locale import _
 from sphinx.pycode import ModuleAnalyzer
+from sphinx.util import get_full_modname
 from sphinx.util.nodes import make_refnode
 
 
+def _get_full_modname(app, modname, attribute):
+    try:
+        return get_full_modname(modname, attribute)
+    except AttributeError:
+        # sphinx.ext.viewcode can't follow class instance attribute
+        # then AttributeError logging output only verbose mode.
+        app.verbose('Didn\'t find %s in %s' % (attribute, modname))
+        return None
+    except Exception as e:
+        # sphinx.ext.viewcode follow python domain directives.
+        # because of that, if there are no real modules exists that specified
+        # by py:function or other directives, viewcode emits a lot of warnings.
+        # It should be displayed only verbose mode.
+        app.verbose(traceback.format_exc().rstrip())
+        app.verbose('viewcode can\'t import %s, failed with error "%s"' %
+                 (modname, e))
+        return None
+
+
 def doctree_read(app, doctree):
     env = app.builder.env
     if not hasattr(env, '_viewcode_modules'):
         env._viewcode_modules = {}
 
-    def has_tag(modname, fullname, docname):
+    def has_tag(modname, fullname, docname, refname):
         entry = env._viewcode_modules.get(modname, None)
         try:
             analyzer = ModuleAnalyzer.for_module(modname)
         except Exception:
             env._viewcode_modules[modname] = False
             return
-        if not isinstance(analyzer.code, unicode):
+        if not isinstance(analyzer.code, text_type):
             code = analyzer.code.decode(analyzer.encoding)
         else:
             code = analyzer.code
         if entry is None or entry[0] != code:
             analyzer.find_tags()
-            entry = code, analyzer.tags, {}
+            entry = code, analyzer.tags, {}, refname
             env._viewcode_modules[modname] = entry
         elif entry is False:
             return
-        code, tags, used = entry
+        _, tags, used, _ = entry
         if fullname in tags:
             used[fullname] = docname
             return True
@@ -52,10 +76,14 @@
             if not isinstance(signode, addnodes.desc_signature):
                 continue
             modname = signode.get('module')
+            fullname = signode.get('fullname')
+            refname = modname
+            if env.config.viewcode_import:
+                modname = _get_full_modname(app, modname, fullname)
             if not modname:
                 continue
             fullname = signode.get('fullname')
-            if not has_tag(modname, fullname, env.docname):
+            if not has_tag(modname, fullname, env.docname, refname):
                 continue
             if fullname in names:
                 # only one link per name, please
@@ -91,10 +119,10 @@
     app.builder.info(' (%d module code pages)' %
                      len(env._viewcode_modules), nonl=1)
 
-    for modname, entry in env._viewcode_modules.iteritems():
+    for modname, entry in iteritems(env._viewcode_modules):
         if not entry:
             continue
-        code, tags, used = entry
+        code, tags, used, refname = entry
         # construct a page name for the highlighted source
         pagename = '_modules/' + modname.replace('.', '/')
         # highlight the source using the builder's highlighter
@@ -109,9 +137,9 @@
         # the collected tags (HACK: this only works if the tag boundaries are
         # properly nested!)
         maxindex = len(lines) - 1
-        for name, docname in used.iteritems():
+        for name, docname in iteritems(used):
             type, start, end = tags[name]
-            backlink = urito(pagename, docname) + '#' + modname + '.' + name
+            backlink = urito(pagename, docname) + '#' + refname + '.' + name
             lines[start] = (
                 '<div class="viewcode-block" id="%s"><a class="viewcode-back" '
                 'href="%s">%s</a>' % (name, backlink, _('[docs]'))
@@ -170,8 +198,10 @@
 
 
 def setup(app):
+    app.add_config_value('viewcode_import', True, False)
     app.connect('doctree-read', doctree_read)
     app.connect('html-collect-pages', collect_pages)
     app.connect('missing-reference', missing_reference)
     #app.add_config_value('viewcode_include_modules', [], 'env')
     #app.add_config_value('viewcode_exclude_modules', [], 'env')
+    return sphinx.__version__
diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py
index 600a7cf..599a76a 100644
--- a/sphinx/highlighting.py
+++ b/sphinx/highlighting.py
@@ -9,7 +9,6 @@
     :license: BSD, see LICENSE for details.
 """
 
-import sys
 import re
 import textwrap
 
@@ -19,6 +18,8 @@
     # parser is not available on Jython
     parser = None
 
+from six import PY2, text_type
+
 from sphinx.util.pycompat import htmlescape
 from sphinx.util.texescape import tex_hl_escape_map_new
 from sphinx.ext import doctest
@@ -69,12 +70,6 @@
 \renewcommand\PYGZsq{\textquotesingle}
 '''
 
-parsing_exceptions = (SyntaxError, UnicodeEncodeError)
-if sys.version_info < (2, 5):
-    # Python <= 2.4 raises MemoryError when parsing an
-    # invalid encoding cookie
-    parsing_exceptions += MemoryError,
-
 
 class PygmentsBridge(object):
     # Set these attributes if you want to have different Pygments formatters
@@ -137,11 +132,7 @@
         # lines beginning with "..." are probably placeholders for suite
         src = re.sub(r"(?m)^(\s*)" + mark + "(.)", r"\1"+ mark + r"# \2", src)
 
-        # if we're using 2.5, use the with statement
-        if sys.version_info >= (2, 5):
-            src = 'from __future__ import with_statement\n' + src
-
-        if sys.version_info < (3, 0) and isinstance(src, unicode):
+        if PY2 and isinstance(src, text_type):
             # Non-ASCII chars will only occur in string literals
             # and comments.  If we wanted to give them to the parser
             # correctly, we'd have to find out the correct source
@@ -149,24 +140,18 @@
             # just replace all non-ASCII characters.
             src = src.encode('ascii', 'replace')
 
-        if (3, 0) <= sys.version_info < (3, 2):
-            # Python 3.1 can't process '\r' as linesep.
-            # `parser.suite("print('hello')\r\n")` cause error.
-            if '\r\n' in src:
-                src = src.replace('\r\n', '\n')
-
         if parser is None:
             return True
 
         try:
             parser.suite(src)
-        except parsing_exceptions:
+        except (SyntaxError, UnicodeEncodeError):
             return False
         else:
             return True
 
     def highlight_block(self, source, lang, warn=None, force=False, **kwargs):
-        if not isinstance(source, unicode):
+        if not isinstance(source, text_type):
             source = source.decode()
         if not pygments:
             return self.unhighlighted(source)
@@ -223,7 +208,7 @@
         if self.dest == 'html':
             return hlsource
         else:
-            if not isinstance(hlsource, unicode):  # Py2 / Pygments < 1.6
+            if not isinstance(hlsource, text_type):  # Py2 / Pygments < 1.6
                 hlsource = hlsource.decode()
             return hlsource.translate(tex_hl_escape_map_new)
 
diff --git a/sphinx/jinja2glue.py b/sphinx/jinja2glue.py
index f4a5a81..b161b42 100644
--- a/sphinx/jinja2glue.py
+++ b/sphinx/jinja2glue.py
@@ -12,6 +12,7 @@
 from os import path
 from pprint import pformat
 
+from six import string_types
 from jinja2 import FileSystemLoader, BaseLoader, TemplateNotFound, \
      contextfunction
 from jinja2.utils import open_if_exists
@@ -22,7 +23,7 @@
 
 
 def _tobool(val):
-    if isinstance(val, basestring):
+    if isinstance(val, string_types):
         return val.lower() in ('true', '1', 'yes', 'on')
     return bool(val)
 
@@ -113,7 +114,7 @@
         self.pathchain = pathchain
 
         # make the paths into loaders
-        self.loaders = map(SphinxFileSystemLoader, loaderchain)
+        self.loaders = [SphinxFileSystemLoader(x) for x in loaderchain]
 
         use_i18n = builder.app.translator is not None
         extensions = use_i18n and ['jinja2.ext.i18n'] or []
diff --git a/sphinx/locale/__init__.py b/sphinx/locale/__init__.py
index b76aab1..9332f47 100644
--- a/sphinx/locale/__init__.py
+++ b/sphinx/locale/__init__.py
@@ -9,12 +9,13 @@
     :license: BSD, see LICENSE for details.
 """
 
-import sys
 import gettext
-import UserString
+
+from six import PY3, text_type
+from six.moves import UserString
 
 
-class _TranslationProxy(UserString.UserString, object):
+class _TranslationProxy(UserString, object):
     """
     Class for proxy strings from gettext translations.  This is a helper for the
     lazy_* functions from this module.
@@ -32,7 +33,7 @@
     def __new__(cls, func, *args):
         if not args:
             # not called with "function" and "arguments", but a plain string
-            return unicode(func)
+            return text_type(func)
         return object.__new__(cls)
 
     def __getnewargs__(self):
@@ -59,11 +60,12 @@
     def __contains__(self, key):
         return key in self.data
 
-    def __nonzero__(self):
+    def __bool__(self):
         return bool(self.data)
+    __nonzero__ = __bool__  # for python2 compatibility
 
     def __dir__(self):
-        return dir(unicode)
+        return dir(text_type)
 
     def __iter__(self):
         return iter(self.data)
@@ -75,7 +77,7 @@
         return str(self.data)
 
     def __unicode__(self):
-        return unicode(self.data)
+        return text_type(self.data)
 
     def __add__(self, other):
         return self.data + other
@@ -132,7 +134,7 @@
 
     def __repr__(self):
         try:
-            return 'i' + repr(unicode(self.data))
+            return 'i' + repr(text_type(self.data))
         except:
             return '<%s broken>' % self.__class__.__name__
 
@@ -183,7 +185,7 @@
 
 translators = {}
 
-if sys.version_info >= (3, 0):
+if PY3:
     def _(message):
         return translators['sphinx'].gettext(message)
 else:
diff --git a/sphinx/make_mode.py b/sphinx/make_mode.py
index b4b5b74..feca51e 100644
--- a/sphinx/make_mode.py
+++ b/sphinx/make_mode.py
@@ -14,6 +14,7 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
+from __future__ import print_function
 
 import os
 import sys
@@ -69,92 +70,93 @@
         if not path.exists(self.builddir):
             return
         elif not path.isdir(self.builddir):
-            print "Error: %r is not a directory!" % self.builddir
+            print("Error: %r is not a directory!" % self.builddir)
             return 1
-        print "Removing everything under %r..." % self.builddir
+        print("Removing everything under %r..." % self.builddir)
         for item in os.listdir(self.builddir):
             shutil.rmtree(self.builddir_join(item))
 
     def build_help(self):
-        print bold("Sphinx v%s" % sphinx.__version__)
-        print "Please use `make %s' where %s is one of" % ((blue('target'),)*2)
+        print(bold("Sphinx v%s" % sphinx.__version__))
+        print("Please use `make %s' where %s is one of" % ((blue('target'),)*2))
         for osname, bname, description in BUILDERS:
             if not osname or os.name == osname:
-                print '  %s  %s' % (blue(bname.ljust(10)), description)
+                print('  %s  %s' % (blue(bname.ljust(10)), description))
 
     def build_html(self):
         if self.run_generic_build('html') > 0:
             return 1
-        print
-        print 'Build finished. The HTML pages are in %s.' % self.builddir_join('html')
+        print()
+        print('Build finished. The HTML pages are in %s.' % self.builddir_join('html'))
 
     def build_dirhtml(self):
         if self.run_generic_build('dirhtml') > 0:
             return 1
-        print
-        print 'Build finished. The HTML pages are in %s.' % self.builddir_join('dirhtml')
+        print()
+        print('Build finished. The HTML pages are in %s.' %
+              self.builddir_join('dirhtml'))
 
     def build_singlehtml(self):
         if self.run_generic_build('singlehtml') > 0:
             return 1
-        print
-        print 'Build finished. The HTML page is in %s.' % \
-            self.builddir_join('singlehtml')
+        print()
+        print('Build finished. The HTML page is in %s.' %
+              self.builddir_join('singlehtml'))
 
     def build_pickle(self):
         if self.run_generic_build('pickle') > 0:
             return 1
-        print
-        print 'Build finished; now you can process the pickle files.'
+        print()
+        print('Build finished; now you can process the pickle files.')
 
     def build_json(self):
         if self.run_generic_build('json') > 0:
             return 1
-        print
-        print 'Build finished; now you can process the JSON files.'
+        print()
+        print('Build finished; now you can process the JSON files.')
 
     def build_htmlhelp(self):
         if self.run_generic_build('htmlhelp') > 0:
             return 1
-        print
-        print ('Build finished; now you can run HTML Help Workshop with the '
-               '.hhp project file in %s.') % self.builddir_join('htmlhelp')
+        print()
+        print('Build finished; now you can run HTML Help Workshop with the '
+              '.hhp project file in %s.' % self.builddir_join('htmlhelp'))
 
     def build_qthelp(self):
         if self.run_generic_build('qthelp') > 0:
             return 1
-        print
-        print ('Build finished; now you can run "qcollectiongenerator" with the '
-               '.qhcp project file in %s, like this:') % self.builddir_join('qthelp')
-        print '$ qcollectiongenerator %s.qhcp' % self.builddir_join('qthelp', proj_name)
-        print 'To view the help file:'
-        print '$ assistant -collectionFile %s.qhc' % \
-            self.builddir_join('qthelp', proj_name)
+        print()
+        print('Build finished; now you can run "qcollectiongenerator" with the '
+              '.qhcp project file in %s, like this:' % self.builddir_join('qthelp'))
+        print('$ qcollectiongenerator %s.qhcp' % self.builddir_join('qthelp', proj_name))
+        print('To view the help file:')
+        print('$ assistant -collectionFile %s.qhc' %
+              self.builddir_join('qthelp', proj_name))
 
     def build_devhelp(self):
         if self.run_generic_build('devhelp') > 0:
             return 1
-        print
-        print "Build finished."
-        print "To view the help file:"
-        print "$ mkdir -p $HOME/.local/share/devhelp/" + proj_name
-        print "$ ln -s %s $HOME/.local/share/devhelp/%s" % \
-            (self.builddir_join('devhelp'), proj_name)
-        print "$ devhelp"
+        print()
+        print("Build finished.")
+        print("To view the help file:")
+        print("$ mkdir -p $HOME/.local/share/devhelp/" + proj_name)
+        print("$ ln -s %s $HOME/.local/share/devhelp/%s" %
+              (self.builddir_join('devhelp'), proj_name))
+        print("$ devhelp")
 
     def build_epub(self):
         if self.run_generic_build('epub') > 0:
             return 1
-        print
-        print 'Build finished. The ePub file is in %s.' % self.builddir_join('epub')
+        print()
+        print('Build finished. The ePub file is in %s.' % self.builddir_join('epub'))
 
     def build_latex(self):
         if self.run_generic_build('latex') > 0:
             return 1
-        print "Build finished; the LaTeX files are in %s." % self.builddir_join('latex')
+        print("Build finished; the LaTeX files are in %s." % self.builddir_join('latex'))
         if os.name == 'posix':
-            print "Run `make' in that directory to run these through (pdf)latex"
-            print "(use `make latexpdf' here to do that automatically)."
+            print("Run `make' in that directory to run these through (pdf)latex")
+            print("(use `make latexpdf' here to do that automatically).")
 
     def build_latexpdf(self):
         if self.run_generic_build('latex') > 0:
@@ -169,17 +171,17 @@
     def build_text(self):
         if self.run_generic_build('text') > 0:
             return 1
-        print
-        print 'Build finished. The text files are in %s.' % self.builddir_join('text')
+        print()
+        print('Build finished. The text files are in %s.' % self.builddir_join('text'))
 
     def build_texinfo(self):
         if self.run_generic_build('texinfo') > 0:
             return 1
-        print "Build finished; the Texinfo files are in %s." % \
-            self.builddir_join('texinfo')
+        print("Build finished; the Texinfo files are in %s." %
+              self.builddir_join('texinfo'))
         if os.name == 'posix':
-            print "Run `make' in that directory to run these through makeinfo"
-            print "(use `make info' here to do that automatically)."
+            print("Run `make' in that directory to run these through makeinfo")
+            print("(use `make info' here to do that automatically).")
 
     def build_info(self):
         if self.run_generic_build('texinfo') > 0:
@@ -190,50 +192,50 @@
         dtdir = self.builddir_join('gettext', '.doctrees')
         if self.run_generic_build('gettext', doctreedir=dtdir) > 0:
             return 1
-        print
-        print 'Build finished. The message catalogs are in %s.' % \
-            self.builddir_join('gettext')
+        print()
+        print('Build finished. The message catalogs are in %s.' %
+              self.builddir_join('gettext'))
 
     def build_changes(self):
         if self.run_generic_build('changes') > 0:
             return 1
-        print
-        print 'Build finished. The overview file is in %s.' % \
-            self.builddir_join('changes')
+        print()
+        print('Build finished. The overview file is in %s.' %
+              self.builddir_join('changes'))
 
     def build_linkcheck(self):
         res = self.run_generic_build('linkcheck')
-        print
-        print ('Link check complete; look for any errors in the above output '
-               'or in %s.') % self.builddir_join('linkcheck', 'output.txt')
+        print()
+        print('Link check complete; look for any errors in the above output '
+              'or in %s.' % self.builddir_join('linkcheck', 'output.txt'))
         return res
 
     def build_doctest(self):
         res = self.run_generic_build('doctest')
-        print ("Testing of doctests in the sources finished, look at the "
-               "results in %s." % self.builddir_join('doctest', 'output.txt'))
+        print("Testing of doctests in the sources finished, look at the "
+              "results in %s." % self.builddir_join('doctest', 'output.txt'))
         return res
 
     def build_coverage(self):
         if self.run_generic_build('coverage') > 0:
-            print "Has the coverage extension been enabled?"
+            print("Has the coverage extension been enabled?")
             return 1
-        print
-        print ("Testing of coverage in the sources finished, look at the "
-               "results in %s." % self.builddir_join('coverage'))
+        print()
+        print("Testing of coverage in the sources finished, look at the "
+              "results in %s." % self.builddir_join('coverage'))
 
     def build_xml(self):
         if self.run_generic_build('xml') > 0:
             return 1
-        print
-        print 'Build finished. The XML files are in %s.' % self.builddir_join('xml')
+        print()
+        print('Build finished. The XML files are in %s.' % self.builddir_join('xml'))
 
     def build_pseudoxml(self):
         if self.run_generic_build('pseudoxml') > 0:
             return 1
-        print
-        print 'Build finished. The pseudo-XML files are in %s.' % \
-            self.builddir_join('pseudoxml')
+        print()
+        print('Build finished. The pseudo-XML files are in %s.' %
+              self.builddir_join('pseudoxml'))
 
     def run_generic_build(self, builder, doctreedir=None):
         # compatibility with old Makefile
@@ -249,8 +251,8 @@
 
 def run_make_mode(args):
     if len(args) < 3:
-        print >>sys.stderr, ('Error: at least 3 arguments (builder, source '
-                             'dir, build dir) are required.')
+        print('Error: at least 3 arguments (builder, source '
+              'dir, build dir) are required.', file=sys.stderr)
         return 1
     make = Make(args[1], args[2], args[3:])
     run_method = 'build_' + args[0]
diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py
index 7a6f59b..461eea0 100644
--- a/sphinx/pycode/__init__.py
+++ b/sphinx/pycode/__init__.py
@@ -8,16 +8,19 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
+from __future__ import print_function
 
 import sys
 from os import path
 
+from six import iteritems, text_type, BytesIO, StringIO
+
 from sphinx import package_dir
 from sphinx.errors import PycodeError
 from sphinx.pycode import nodes
 from sphinx.pycode.pgen2 import driver, token, tokenize, parse, literals
 from sphinx.util import get_module_source, detect_encoding
-from sphinx.util.pycompat import next, StringIO, BytesIO, TextIOWrapper
+from sphinx.util.pycompat import TextIOWrapper
 from sphinx.util.docstrings import prepare_docstring, prepare_commentdoc
 
 
@@ -29,9 +32,9 @@
 
 # an object with attributes corresponding to token and symbol names
 class sym: pass
-for k, v in pygrammar.symbol2number.iteritems():
+for k, v in iteritems(pygrammar.symbol2number):
     setattr(sym, k, v)
-for k, v in token.tok_name.iteritems():
+for k, v in iteritems(token.tok_name):
     setattr(sym, v, k)
 
 # a dict mapping terminal and nonterminal numbers to their names
@@ -97,7 +100,7 @@
                 continue  # skip over semicolon
             if parent[idx].type == sym.NEWLINE:
                 prefix = parent[idx].get_prefix()
-                if not isinstance(prefix, unicode):
+                if not isinstance(prefix, text_type):
                     prefix = prefix.decode(self.encoding)
                 docstring = prepare_commentdoc(prefix)
                 if docstring:
@@ -115,7 +118,7 @@
             if not pnode or pnode.type not in (token.INDENT, token.DEDENT):
                 break
             prefix = pnode.get_prefix()
-        if not isinstance(prefix, unicode):
+        if not isinstance(prefix, text_type):
             prefix = prefix.decode(self.encoding)
         docstring = prepare_commentdoc(prefix)
         self.add_docstring(node, docstring)
@@ -182,7 +185,7 @@
             return cls.cache['file', filename]
         try:
             fileobj = open(filename, 'rb')
-        except Exception, err:
+        except Exception as err:
             raise PycodeError('error opening %r' % filename, err)
         obj = cls(fileobj, modname, filename)
         cls.cache['file', filename] = obj
@@ -202,7 +205,7 @@
                 obj = cls.for_string(source, modname)
             else:
                 obj = cls.for_file(source, modname)
-        except PycodeError, err:
+        except PycodeError as err:
             cls.cache['module', modname] = err
             raise
         cls.cache['module', modname] = obj
@@ -245,7 +248,7 @@
             return
         try:
             self.tokens = list(tokenize.generate_tokens(self.source.readline))
-        except tokenize.TokenError, err:
+        except tokenize.TokenError as err:
             raise PycodeError('tokenizing failed', err)
         self.source.close()
 
@@ -256,7 +259,7 @@
         self.tokenize()
         try:
             self.parsetree = pydriver.parse_tokens(self.tokens)
-        except parse.ParseError, err:
+        except parse.ParseError as err:
             raise PycodeError('parsing failed', err)
 
     def find_attr_docs(self, scope=''):
@@ -338,10 +341,10 @@
     x1 = time.time()
     ma.parse()
     x2 = time.time()
-    #for (ns, name), doc in ma.find_attr_docs().iteritems():
+    #for (ns, name), doc in iteritems(ma.find_attr_docs()):
     #    print '>>', ns, name
     #    print '\n'.join(doc)
     pprint.pprint(ma.find_tags())
     x3 = time.time()
     #print nodes.nice_repr(ma.parsetree, number2name)
-    print "tokenizing %.4f, parsing %.4f, finding %.4f" % (x1-x0, x2-x1, x3-x2)
+    print("tokenizing %.4f, parsing %.4f, finding %.4f" % (x1-x0, x2-x1, x3-x2))
diff --git a/sphinx/pycode/pgen2/driver.py b/sphinx/pycode/pgen2/driver.py
index 422671d..c531edb 100644
--- a/sphinx/pycode/pgen2/driver.py
+++ b/sphinx/pycode/pgen2/driver.py
@@ -131,7 +131,7 @@
             logger.info("Writing grammar tables to %s", gp)
             try:
                 g.dump(gp)
-            except IOError, e:
+            except IOError as e:
                 logger.info("Writing failed:"+str(e))
     else:
         g = grammar.Grammar()
diff --git a/sphinx/pycode/pgen2/grammar.py b/sphinx/pycode/pgen2/grammar.py
index 01d8434..91874fa 100644
--- a/sphinx/pycode/pgen2/grammar.py
+++ b/sphinx/pycode/pgen2/grammar.py
@@ -11,6 +11,7 @@
 fallback token code OP, but the parser needs the actual token code.
 
 """
+from __future__ import print_function
 
 # Python imports
 import pickle
@@ -100,17 +101,17 @@
     def report(self):
         """Dump the grammar tables to standard output, for debugging."""
         from pprint import pprint
-        print "s2n"
+        print("s2n")
         pprint(self.symbol2number)
-        print "n2s"
+        print("n2s")
         pprint(self.number2symbol)
-        print "states"
+        print("states")
         pprint(self.states)
-        print "dfas"
+        print("dfas")
         pprint(self.dfas)
-        print "labels"
+        print("labels")
         pprint(self.labels)
-        print "start", self.start
+        print("start", self.start)
 
 
 # Map from operator to number (since tokenize doesn't do this)
diff --git a/sphinx/pycode/pgen2/literals.py b/sphinx/pycode/pgen2/literals.py
index d489370..25e09b6 100644
--- a/sphinx/pycode/pgen2/literals.py
+++ b/sphinx/pycode/pgen2/literals.py
@@ -4,9 +4,13 @@
 # Extended to handle raw and unicode literals by Georg Brandl.
 
 """Safely evaluate Python string literals without using eval()."""
+from __future__ import print_function
 
 import re
 
+from six import text_type
+
+
 simple_escapes = {"a": "\a",
                   "b": "\b",
                   "f": "\f",
@@ -66,7 +70,7 @@
 def evalString(s, encoding=None):
     regex = escape_re
     repl = escape
-    if encoding and not isinstance(s, unicode):
+    if encoding and not isinstance(s, text_type):
         s = s.decode(encoding)
     if s.startswith('u') or s.startswith('U'):
         regex = uni_escape_re
@@ -89,7 +93,7 @@
         s = repr(c)
         e = evalString(s)
         if e != c:
-            print i, c, s, e
+            print(i, c, s, e)
 
 
 if __name__ == "__main__":
diff --git a/sphinx/pycode/pgen2/parse.c b/sphinx/pycode/pgen2/parse.c
index e09f505..96fa6c8 100644
--- a/sphinx/pycode/pgen2/parse.c
+++ b/sphinx/pycode/pgen2/parse.c
@@ -353,95 +353,6 @@
 
 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],     PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,     const char* function_name); /*proto*/
 
-#if PY_VERSION_HEX < 0x02050000
-#ifndef PyAnySet_CheckExact
-
-#define PyAnySet_CheckExact(ob) \
-    ((ob)->ob_type == &PySet_Type || \
-     (ob)->ob_type == &PyFrozenSet_Type)
-
-#define PySet_New(iterable) \
-    PyObject_CallFunctionObjArgs((PyObject *)&PySet_Type, (iterable), NULL)
-
-#define Pyx_PyFrozenSet_New(iterable) \
-    PyObject_CallFunctionObjArgs((PyObject *)&PyFrozenSet_Type, (iterable), NULL)
-
-#define PySet_Size(anyset) \
-    PyObject_Size((anyset))
-
-#define PySet_Contains(anyset, key) \
-    PySequence_Contains((anyset), (key))
-
-#define PySet_Pop(set) \
-    PyObject_CallMethod(set, (char *)"pop", NULL)
-
-static INLINE int PySet_Clear(PyObject *set) {
-    PyObject *ret = PyObject_CallMethod(set, (char *)"clear", NULL);
-    if (!ret) return -1;
-    Py_DECREF(ret); return 0;
-}
-
-static INLINE int PySet_Discard(PyObject *set, PyObject *key) {
-    PyObject *ret = PyObject_CallMethod(set, (char *)"discard", (char *)"O", key);
-    if (!ret) return -1;
-    Py_DECREF(ret); return 0;
-}
-
-static INLINE int PySet_Add(PyObject *set, PyObject *key) {
-    PyObject *ret = PyObject_CallMethod(set, (char *)"add", (char *)"O", key);
-    if (!ret) return -1;
-    Py_DECREF(ret); return 0;
-}
-
-#endif /* PyAnySet_CheckExact (<= Py2.4) */
-
-#if PY_VERSION_HEX < 0x02040000
-#ifndef Py_SETOBJECT_H
-#define Py_SETOBJECT_H
-
-static PyTypeObject *__Pyx_PySet_Type = NULL;
-static PyTypeObject *__Pyx_PyFrozenSet_Type = NULL;
-
-#define PySet_Type (*__Pyx_PySet_Type)
-#define PyFrozenSet_Type (*__Pyx_PyFrozenSet_Type)
-
-#define PyAnySet_Check(ob) \
-    (PyAnySet_CheckExact(ob) || \
-     PyType_IsSubtype((ob)->ob_type, &PySet_Type) || \
-     PyType_IsSubtype((ob)->ob_type, &PyFrozenSet_Type))
-
-#define PyFrozenSet_CheckExact(ob) ((ob)->ob_type == &PyFrozenSet_Type)
-
-static int __Pyx_Py23SetsImport(void) {
-    PyObject *sets=0, *Set=0, *ImmutableSet=0;
-
-    sets = PyImport_ImportModule((char *)"sets");
-    if (!sets) goto bad;
-    Set = PyObject_GetAttrString(sets, (char *)"Set");
-    if (!Set) goto bad;
-    ImmutableSet = PyObject_GetAttrString(sets, (char *)"ImmutableSet");
-    if (!ImmutableSet) goto bad;
-    Py_DECREF(sets);
-
-    __Pyx_PySet_Type       = (PyTypeObject*) Set;
-    __Pyx_PyFrozenSet_Type = (PyTypeObject*) ImmutableSet;
-
-    return 0;
-
- bad:
-    Py_XDECREF(sets);
-    Py_XDECREF(Set);
-    Py_XDECREF(ImmutableSet);
-    return -1;
-}
-
-#else
-static int __Pyx_Py23SetsImport(void) { return 0; }
-#endif /* !Py_SETOBJECT_H */
-#endif /* < Py2.4  */
-#endif /* < Py2.5  */
-
-
 static INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
     PyObject *r;
     if (!j) return NULL;
diff --git a/sphinx/pycode/pgen2/pgen.py b/sphinx/pycode/pgen2/pgen.py
index 0a04447..e199ed8 100644
--- a/sphinx/pycode/pgen2/pgen.py
+++ b/sphinx/pycode/pgen2/pgen.py
@@ -1,7 +1,12 @@
 # Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
 # Licensed to PSF under a Contributor Agreement.
 
+from __future__ import print_function
+
+from six import iteritems
+
 # Pgen imports
+
 from sphinx.pycode.pgen2 import grammar, token, tokenize
 
 class PgenGrammar(grammar.Grammar):
@@ -26,7 +31,7 @@
 
     def make_grammar(self):
         c = PgenGrammar()
-        names = self.dfas.keys()
+        names = list(self.dfas.keys())
         names.sort()
         names.remove(self.startsymbol)
         names.insert(0, self.startsymbol)
@@ -39,7 +44,7 @@
             states = []
             for state in dfa:
                 arcs = []
-                for label, next in state.arcs.iteritems():
+                for label, next in iteritems(state.arcs):
                     arcs.append((self.make_label(c, label), dfa.index(next)))
                 if state.isfinal:
                     arcs.append((0, dfa.index(state)))
@@ -105,7 +110,7 @@
                     return ilabel
 
     def addfirstsets(self):
-        names = self.dfas.keys()
+        names = list(self.dfas.keys())
         names.sort()
         for name in names:
             if name not in self.first:
@@ -118,7 +123,7 @@
         state = dfa[0]
         totalset = {}
         overlapcheck = {}
-        for label, next in state.arcs.iteritems():
+        for label, next in iteritems(state.arcs):
             if label in self.dfas:
                 if label in self.first:
                     fset = self.first[label]
@@ -133,7 +138,7 @@
                 totalset[label] = 1
                 overlapcheck[label] = {label: 1}
         inverse = {}
-        for label, itsfirst in overlapcheck.iteritems():
+        for label, itsfirst in iteritems(overlapcheck):
             for symbol in itsfirst:
                 if symbol in inverse:
                     raise ValueError("rule %s is ambiguous; %s is in the"
@@ -192,7 +197,7 @@
                 for label, next in nfastate.arcs:
                     if label is not None:
                         addclosure(next, arcs.setdefault(label, {}))
-            for label, nfaset in arcs.iteritems():
+            for label, nfaset in iteritems(arcs):
                 for st in states:
                     if st.nfaset == nfaset:
                         break
@@ -203,10 +208,10 @@
         return states # List of DFAState instances; first one is start
 
     def dump_nfa(self, name, start, finish):
-        print "Dump of NFA for", name
+        print("Dump of NFA for", name)
         todo = [start]
         for i, state in enumerate(todo):
-            print "  State", i, state is finish and "(final)" or ""
+            print("  State", i, state is finish and "(final)" or "")
             for label, next in state.arcs:
                 if next in todo:
                     j = todo.index(next)
@@ -214,16 +219,16 @@
                     j = len(todo)
                     todo.append(next)
                 if label is None:
-                    print "    -> %d" % j
+                    print("    -> %d" % j)
                 else:
-                    print "    %s -> %d" % (label, j)
+                    print("    %s -> %d" % (label, j))
 
     def dump_dfa(self, name, dfa):
-        print "Dump of DFA for", name
+        print("Dump of DFA for", name)
         for i, state in enumerate(dfa):
-            print "  State", i, state.isfinal and "(final)" or ""
-            for label, next in state.arcs.iteritems():
-                print "    %s -> %d" % (label, dfa.index(next))
+            print("  State", i, state.isfinal and "(final)" or "")
+            for label, next in iteritems(state.arcs):
+                print("    %s -> %d" % (label, dfa.index(next)))
 
     def simplify_dfa(self, dfa):
         # This is not theoretically optimal, but works well enough.
@@ -319,9 +324,9 @@
         return value
 
     def gettoken(self):
-        tup = self.generator.next()
+        tup = next(self.generator)
         while tup[0] in (tokenize.COMMENT, tokenize.NL):
-            tup = self.generator.next()
+            tup = next(self.generator)
         self.type, self.value, self.begin, self.end, self.line = tup
         #print token.tok_name[self.type], repr(self.value)
 
@@ -330,7 +335,7 @@
             try:
                 msg = msg % args
             except:
-                msg = " ".join([msg] + map(str, args))
+                msg = " ".join([msg] + [str(x) for x in args])
         raise SyntaxError(msg, (self.filename, self.end[0],
                                 self.end[1], self.line))
 
@@ -348,7 +353,7 @@
 
     def __init__(self, nfaset, final):
         assert isinstance(nfaset, dict)
-        assert isinstance(iter(nfaset).next(), NFAState)
+        assert isinstance(next(iter(nfaset)), NFAState)
         assert isinstance(final, NFAState)
         self.nfaset = nfaset
         self.isfinal = final in nfaset
@@ -361,7 +366,7 @@
         self.arcs[label] = next
 
     def unifystate(self, old, new):
-        for label, next in self.arcs.iteritems():
+        for label, next in iteritems(self.arcs):
             if next is old:
                 self.arcs[label] = new
 
@@ -374,7 +379,7 @@
         # would invoke this method recursively, with cycles...
         if len(self.arcs) != len(other.arcs):
             return False
-        for label, next in self.arcs.iteritems():
+        for label, next in iteritems(self.arcs):
             if next is not other.arcs.get(label):
                 return False
         return True
diff --git a/sphinx/pycode/pgen2/token.py b/sphinx/pycode/pgen2/token.py
index 56a40ce..55bf5e8 100755
--- a/sphinx/pycode/pgen2/token.py
+++ b/sphinx/pycode/pgen2/token.py
@@ -68,7 +68,7 @@
 #--end constants--
 
 tok_name = {}
-for _name, _value in globals().items():
+for _name, _value in list(globals().items()):
     if type(_value) is type(0):
         tok_name[_value] = _name
 
diff --git a/sphinx/pycode/pgen2/tokenize.py b/sphinx/pycode/pgen2/tokenize.py
index 7ad9f01..d625350 100644
--- a/sphinx/pycode/pgen2/tokenize.py
+++ b/sphinx/pycode/pgen2/tokenize.py
@@ -23,13 +23,17 @@
     tokenize(readline, tokeneater=printtoken)
 are the same, except instead of generating tokens, tokeneater is a callback
 function to which the 5 fields described above are passed as 5 arguments,
-each time a new token is found."""
+each time a new token is found.
+"""
+
+from __future__ import print_function
 
 __author__ = 'Ka-Ping Yee <ping@lfw.org>'
 __credits__ = \
     'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro'
 
 import string, re
+from six import PY3
 from sphinx.pycode.pgen2.token import *
 from sphinx.pycode.pgen2 import token
 
@@ -81,6 +85,9 @@
 
 Bracket = '[][(){}]'
 Special = group(r'\r?\n', r'[:;.,`@]')
+if PY3:
+    Ellipsis_ = r'\.{3}'
+    Special = group(Ellipsis_, Special)
 Funny = group(Operator, Bracket, Special)
 
 PlainToken = group(Number, Funny, String, Name)
@@ -94,8 +101,9 @@
 PseudoExtras = group(r'\\\r?\n', Comment, Triple)
 PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name)
 
-tokenprog, pseudoprog, single3prog, double3prog = map(
-    re.compile, (Token, PseudoToken, Single3, Double3))
+tokenprog, pseudoprog, single3prog, double3prog = [
+    re.compile(x) for x in (Token, PseudoToken, Single3, Double3)
+]
 endprogs = {"'": re.compile(Single), '"': re.compile(Double),
             "'''": single3prog, '"""': double3prog,
             "r'''": single3prog, 'r"""': double3prog,
@@ -146,8 +154,8 @@
 def printtoken(type, token, scell, ecell, line): # for testing
     srow, scol = scell
     erow, ecol = ecell
-    print "%d,%d-%d,%d:\t%s\t%s" % \
-        (srow, scol, erow, ecol, tok_name[type], repr(token))
+    print("%d,%d-%d,%d:\t%s\t%s" %
+          (srow, scol, erow, ecol, tok_name[type], repr(token)))
 
 def tokenize(readline, tokeneater=printtoken):
     """
@@ -352,8 +360,9 @@
                 spos, epos, pos = (lnum, start), (lnum, end), end
                 token, initial = line[start:end], line[start]
 
-                if initial in numchars or \
-                   (initial == '.' and token != '.'):      # ordinary number
+                if initial in numchars or (
+                   initial == '.' and token not in ('.', '...')
+                   ):                                      # ordinary number
                     yield (NUMBER, token, spos, epos, line)
                 elif initial in '\r\n':
                     newline = NEWLINE
@@ -389,6 +398,8 @@
                         yield (STRING, token, spos, epos, line)
                 elif initial in namechars:                 # ordinary name
                     yield (NAME, token, spos, epos, line)
+                elif token in ('...',):                    # ordinary name
+                    yield (NAME, token, spos, epos, line)
                 elif initial == '\\':                      # continued stmt
                     # This yield is new; needed for better idempotency:
                     yield (NL, token, spos, (lnum, pos), line)
diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py
index 5cf067e..fdfb810 100644
--- a/sphinx/quickstart.py
+++ b/sphinx/quickstart.py
@@ -8,12 +8,26 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
+from __future__ import print_function
 
 import sys, os, time, re
 from os import path
+from io import open
 
 TERM_ENCODING = getattr(sys.stdin, 'encoding', None)
 
+#try to import readline, unix specific enhancement
+try:
+    import readline
+    if readline.__doc__ and 'libedit' in readline.__doc__:
+        readline.parse_and_bind("bind ^I rl_complete")
+    else:
+        readline.parse_and_bind("tab: complete")
+except ImportError:
+    pass
+
+from six import PY2, PY3, text_type
+from six.moves import input
 from docutils.utils import column_width
 
 from sphinx import __version__
@@ -21,19 +35,14 @@
 from sphinx.util.console import purple, bold, red, turquoise, \
      nocolor, color_terminal
 from sphinx.util import texescape
-from sphinx.util.pycompat import open
 
 # function to get input from terminal -- overridden by the test suite
-try:
-    # this raw_input is not converted by 2to3
-    term_input = raw_input
-except NameError:
-    term_input = input
+term_input = input
 
 
 PROMPT_PREFIX = '> '
 
-if sys.version_info >= (3, 0):
+if PY3:
     # prevents that the file is checked for being written in Python 2.x syntax
     QUICKSTART_CONF = u'#!/usr/bin/env python3\n'
 else:
@@ -99,7 +108,10 @@
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
-#language = None
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = %(language)r
 
 # There are two options for replacing |today|: either, you set today to some
 # non-false value, then it is used:
@@ -217,10 +229,23 @@
 # This is the file name suffix for HTML files (e.g. ".xhtml").
 #html_file_suffix = None
 
+# Language to be used for generating the HTML full-text search index.
+# Sphinx supports the following languages:
+#   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
+#   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
+#html_search_language = 'en'
+
+# A dictionary with options for the search language support, empty by default.
+# Now only 'ja' uses this config value
+#html_search_options = {'type': 'default'}
+
+# The name of a javascript file (relative to the configuration directory) that
+# implements a search results scorer. If empty, the default will be used.
+#html_search_scorer = 'scorer.js'
+
 # Output file base name for HTML help builder.
 htmlhelp_basename = '%(project_fn)sdoc'
 
-
 # -- Options for LaTeX output ---------------------------------------------
 
 latex_elements = {
@@ -232,6 +257,9 @@
 
 # Additional stuff for the LaTeX preamble.
 #'preamble': '',
+
+# Latex figure (float) alignment
+#'figure_align': 'htbp',
 }
 
 # Grouping the document tree into LaTeX files. List of tuples
@@ -320,7 +348,7 @@
 #epub_theme = 'epub'
 
 # The language of the text. It defaults to the language option
-# or en if the language is not set.
+# or 'en' if the language is not set.
 #epub_language = ''
 
 # The scheme of the identifier. Typical schemes are ISBN or URL.
@@ -432,7 +460,7 @@
 I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) %(rsrcdir)s
 
 .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp \
-epub latex latexpdf text man changes linkcheck doctest gettext
+epub latex latexpdf text man changes linkcheck doctest coverage gettext
 
 help:
 \t@echo "Please use \\`make <target>' where <target> is one of"
@@ -459,6 +487,7 @@
 \t@echo "  linkcheck  to check all external links for integrity"
 \t@echo "  doctest    to run all doctests embedded in the documentation \
 (if enabled)"
+\t@echo "  coverage   to run coverage check of the documentation (if enabled)"
 
 clean:
 \trm -rf $(BUILDDIR)/*
@@ -581,6 +610,11 @@
 \t@echo "Testing of doctests in the sources finished, look at the " \\
 \t      "results in $(BUILDDIR)/doctest/output.txt."
 
+coverage:
+\t$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
+\t@echo "Testing of coverage in the sources finished, look at the " \\
+\t      "results in $(BUILDDIR)/coverage/python.txt."
+
 xml:
 \t$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
 \t@echo
@@ -632,6 +666,7 @@
 \techo.  pseudoxml  to make pseudoxml-XML files for display purposes
 \techo.  linkcheck  to check all external links for integrity
 \techo.  doctest    to run all doctests embedded in the documentation if enabled
+\techo.  coverage   to run coverage check of the documentation if enabled
 \tgoto end
 )
 
@@ -642,6 +677,14 @@
 )
 
 
+REM Check if sphinx-build is available and fallback to Python version if any
+%%SPHINXBUILD%% 2> nul
+if errorlevel 9009 goto sphinx_python
+goto sphinx_ok
+
+:sphinx_python
+
+set SPHINXBUILD=python -m sphinx.__init__
 %%SPHINXBUILD%% 2> nul
 if errorlevel 9009 (
 \techo.
@@ -655,6 +698,9 @@
 \texit /b 1
 )
 
+:sphinx_ok
+
+
 if "%%1" == "html" (
 \t%%SPHINXBUILD%% -b html %%ALLSPHINXOPTS%% %%BUILDDIR%%/html
 \tif errorlevel 1 exit /b 1
@@ -818,6 +864,15 @@
 \tgoto end
 )
 
+if "%%1" == "coverage" (
+\t%%SPHINXBUILD%% -b coverage %%ALLSPHINXOPTS%% %%BUILDDIR%%/coverage
+\tif errorlevel 1 exit /b 1
+\techo.
+\techo.Testing of coverage in the sources finished, look at the ^
+results in %%BUILDDIR%%/coverage/python.txt.
+\tgoto end
+)
+
 if "%%1" == "xml" (
 \t%%SPHINXBUILD%% -b xml %%ALLSPHINXOPTS%% %%BUILDDIR%%/xml
 \tif errorlevel 1 exit /b 1
@@ -918,6 +973,7 @@
     """Raised for validation errors."""
 
 def is_path(x):
+    x = path.expanduser(x)
     if path.exists(x) and not path.isdir(x):
         raise ValidationError("Please enter a valid path name.")
     return x
@@ -955,16 +1011,16 @@
             prompt = PROMPT_PREFIX + '%s [%s]: ' % (text, default)
         else:
             prompt = PROMPT_PREFIX + text + ': '
-        if sys.version_info < (3, 0):
+        if PY2:
             # for Python 2.x, try to get a Unicode string out of it
             if prompt.encode('ascii', 'replace').decode('ascii', 'replace') \
                     != prompt:
                 if TERM_ENCODING:
                     prompt = prompt.encode(TERM_ENCODING)
                 else:
-                    print turquoise('* Note: non-ASCII default value provided '
+                    print(turquoise('* Note: non-ASCII default value provided '
                                     'and terminal encoding unknown -- assuming '
-                                    'UTF-8 or Latin-1.')
+                                    'UTF-8 or Latin-1.'))
                     try:
                         prompt = prompt.encode('utf-8')
                     except UnicodeEncodeError:
@@ -973,29 +1029,29 @@
         x = term_input(prompt).strip()
         if default and not x:
             x = default
-        if not isinstance(x, unicode):
+        if not isinstance(x, text_type):
             # for Python 2.x, try to get a Unicode string out of it
             if x.decode('ascii', 'replace').encode('ascii', 'replace') != x:
                 if TERM_ENCODING:
                     x = x.decode(TERM_ENCODING)
                 else:
-                    print turquoise('* Note: non-ASCII characters entered '
+                    print(turquoise('* Note: non-ASCII characters entered '
                                     'and terminal encoding unknown -- assuming '
-                                    'UTF-8 or Latin-1.')
+                                    'UTF-8 or Latin-1.'))
                     try:
                         x = x.decode('utf-8')
                     except UnicodeDecodeError:
                         x = x.decode('latin1')
         try:
             x = validator(x)
-        except ValidationError, err:
-            print red('* ' + str(err))
+        except ValidationError as err:
+            print(red('* ' + str(err)))
             continue
         break
     d[key] = x
 
 
-if sys.version_info >= (3, 0):
+if PY3:
     # remove Unicode literal prefixes
     def _convert_python_source(source, rex=re.compile(r"[uU]('.*?')")):
         return rex.sub('\\1', source)
@@ -1018,6 +1074,7 @@
     * author:    author names
     * version:   version of project
     * release:   release of project
+    * language:  document language
     * suffix:    source file suffix
     * master:    master document name
     * epub:      use epub (bool)
@@ -1026,98 +1083,110 @@
     * batchfile: make command file
     """
 
-    print bold('Welcome to the Sphinx %s quickstart utility.') % __version__
-    print '''
+    print(bold('Welcome to the Sphinx %s quickstart utility.') % __version__)
+    print('''
 Please enter values for the following settings (just press Enter to
-accept a default value, if one is given in brackets).'''
+accept a default value, if one is given in brackets).''')
 
     if 'path' in d:
-        print bold('''
-Selected root path: %s''' % d['path'])
+        print(bold('''
+Selected root path: %s''' % d['path']))
     else:
-        print '''
-Enter the root path for documentation.'''
+        print('''
+Enter the root path for documentation.''')
         do_prompt(d, 'path', 'Root path for the documentation', '.', is_path)
 
     while path.isfile(path.join(d['path'], 'conf.py')) or \
           path.isfile(path.join(d['path'], 'source', 'conf.py')):
-        print
-        print bold('Error: an existing conf.py has been found in the '
-                   'selected root path.')
-        print 'sphinx-quickstart will not overwrite existing Sphinx projects.'
-        print
+        print()
+        print(bold('Error: an existing conf.py has been found in the '
+                   'selected root path.'))
+        print('sphinx-quickstart will not overwrite existing Sphinx projects.')
+        print()
         do_prompt(d, 'path', 'Please enter a new root path (or just Enter '
                   'to exit)', '', is_path)
         if not d['path']:
             sys.exit(1)
 
     if 'sep' not in d:
-        print '''
+        print('''
 You have two options for placing the build directory for Sphinx output.
 Either, you use a directory "_build" within the root path, or you separate
-"source" and "build" directories within the root path.'''
+"source" and "build" directories within the root path.''')
         do_prompt(d, 'sep', 'Separate source and build directories (y/n)', 'n',
                   boolean)
 
     if 'dot' not in d:
-        print '''
+        print('''
 Inside the root directory, two more directories will be created; "_templates"
 for custom HTML templates and "_static" for custom stylesheets and other static
-files. You can enter another prefix (such as ".") to replace the underscore.'''
+files. You can enter another prefix (such as ".") to replace the underscore.''')
         do_prompt(d, 'dot', 'Name prefix for templates and static dir', '_', ok)
 
     if 'project' not in d:
-        print '''
-The project name will occur in several places in the built documentation.'''
+        print('''
+The project name will occur in several places in the built documentation.''')
         do_prompt(d, 'project', 'Project name')
     if 'author' not in d:
         do_prompt(d, 'author', 'Author name(s)')
 
     if 'version' not in d:
-        print '''
+        print('''
 Sphinx has the notion of a "version" and a "release" for the
 software. Each version can have multiple releases. For example, for
 Python the version is something like 2.5 or 3.0, while the release is
 something like 2.5.1 or 3.0a1.  If you don't need this dual structure,
-just set both to the same value.'''
+just set both to the same value.''')
         do_prompt(d, 'version', 'Project version')
     if 'release' not in d:
         do_prompt(d, 'release', 'Project release', d['version'])
 
+    if 'language' not in d:
+        print('''
+If the documents are to be written in a language other than English,
+you can select a language here by its language code. Sphinx will then
+translate text that it generates into that language.
+
+For a list of supported codes, see
+http://sphinx-doc.org/config.html#confval-language.''')
+        do_prompt(d, 'language', 'Project language', 'en')
+        if d['language'] == 'en':
+            d['language'] = None
+
     if 'suffix' not in d:
-        print '''
+        print('''
 The file name suffix for source files. Commonly, this is either ".txt"
-or ".rst".  Only files with this suffix are considered documents.'''
+or ".rst".  Only files with this suffix are considered documents.''')
         do_prompt(d, 'suffix', 'Source file suffix', '.rst', suffix)
 
     if 'master' not in d:
-        print '''
+        print('''
 One document is special in that it is considered the top node of the
 "contents tree", that is, it is the root of the hierarchical structure
 of the documents. Normally, this is "index", but if your "index"
-document is a custom template, you can also set this to another filename.'''
+document is a custom template, you can also set this to another filename.''')
         do_prompt(d, 'master', 'Name of your master document (without suffix)',
                   'index')
 
     while path.isfile(path.join(d['path'], d['master']+d['suffix'])) or \
           path.isfile(path.join(d['path'], 'source', d['master']+d['suffix'])):
-        print
-        print bold('Error: the master file %s has already been found in the '
-                   'selected root path.' % (d['master']+d['suffix']))
-        print 'sphinx-quickstart will not overwrite the existing file.'
-        print
+        print()
+        print(bold('Error: the master file %s has already been found in the '
+                   'selected root path.' % (d['master']+d['suffix'])))
+        print('sphinx-quickstart will not overwrite the existing file.')
+        print()
         do_prompt(d, 'master', 'Please enter a new file name, or rename the '
                   'existing file and press Enter', d['master'])
 
     if 'epub' not in d:
-        print '''
-Sphinx can also add configuration for epub output:'''
+        print('''
+Sphinx can also add configuration for epub output:''')
         do_prompt(d, 'epub', 'Do you want to use the epub builder (y/n)',
                   'n', boolean)
 
     if 'ext_autodoc' not in d:
-        print '''
-Please indicate if you want to use one of the following Sphinx extensions:'''
+        print('''
+Please indicate if you want to use one of the following Sphinx extensions:''')
         do_prompt(d, 'ext_autodoc', 'autodoc: automatically insert docstrings '
                   'from modules (y/n)', 'n', boolean)
     if 'ext_doctest' not in d:
@@ -1139,8 +1208,8 @@
         do_prompt(d, 'ext_mathjax', 'mathjax: include math, rendered in the '
                   'browser by MathJax (y/n)', 'n', boolean)
     if d['ext_pngmath'] and d['ext_mathjax']:
-        print '''Note: pngmath and mathjax cannot be enabled at the same time.
-pngmath has been deselected.'''
+        print('''Note: pngmath and mathjax cannot be enabled at the same time.
+pngmath has been deselected.''')
         d['ext_pngmath'] = False
     if 'ext_ifconfig' not in d:
         do_prompt(d, 'ext_ifconfig', 'ifconfig: conditional inclusion of '
@@ -1150,15 +1219,15 @@
                   'code of documented Python objects (y/n)', 'n', boolean)
 
     if 'makefile' not in d:
-        print '''
+        print('''
 A Makefile and a Windows command file can be generated for you so that you
 only have to run e.g. `make html' instead of invoking sphinx-build
-directly.'''
+directly.''')
         do_prompt(d, 'makefile', 'Create Makefile? (y/n)', 'y', boolean)
     if 'batchfile' not in d:
         do_prompt(d, 'batchfile', 'Create Windows command file? (y/n)',
                   'y', boolean)
-    print
+    print()
 
 
 def generate(d, overwrite=True, silent=False):
@@ -1186,10 +1255,10 @@
     else:
         d['extensions'] = extensions
     d['copyright'] = time.strftime('%Y') + ', ' + d['author']
-    d['author_texescaped'] = unicode(d['author']).\
+    d['author_texescaped'] = text_type(d['author']).\
                              translate(texescape.tex_escape_map)
     d['project_doc'] = d['project'] + ' Documentation'
-    d['project_doc_texescaped'] = unicode(d['project'] + ' Documentation').\
+    d['project_doc_texescaped'] = text_type(d['project'] + ' Documentation').\
                                   translate(texescape.tex_escape_map)
 
     # escape backslashes and single quotes in strings that are put into
@@ -1217,14 +1286,14 @@
 
     def write_file(fpath, content, newline=None):
         if overwrite or not path.isfile(fpath):
-            print 'Creating file %s.' % fpath
+            print('Creating file %s.' % fpath)
             f = open(fpath, 'wt', encoding='utf-8', newline=newline)
             try:
                 f.write(content)
             finally:
                 f.close()
         else:
-            print 'File %s already exists, skipping.' % fpath
+            print('File %s already exists, skipping.' % fpath)
 
     conf_text = QUICKSTART_CONF % d
     if d['epub']:
@@ -1250,9 +1319,9 @@
 
     if silent:
         return
-    print
-    print bold('Finished: An initial directory structure has been created.')
-    print '''
+    print()
+    print(bold('Finished: An initial directory structure has been created.'))
+    print('''
 You should now populate your master file %s and create other documentation
 source files. ''' % masterfile + ((d['makefile'] or d['batchfile']) and '''\
 Use the Makefile to build the docs, like so:
@@ -1262,7 +1331,7 @@
    sphinx-build -b builder %s %s
 ''' % (srcdir, builddir)) + '''\
 where "builder" is one of the supported builders, e.g. html, latex or linkcheck.
-'''
+''')
 
 
 def main(argv=sys.argv):
@@ -1271,14 +1340,18 @@
 
     d = {}
     if len(argv) > 3:
-        print 'Usage: sphinx-quickstart [root]'
+        print('Usage: sphinx-quickstart [root]')
         sys.exit(1)
     elif len(argv) == 2:
         d['path'] = argv[1]
     try:
         ask_user(d)
     except (KeyboardInterrupt, EOFError):
-        print
-        print '[Interrupted.]'
+        print()
+        print('[Interrupted.]')
         return
     generate(d)
+
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))
diff --git a/sphinx/roles.py b/sphinx/roles.py
index c31ec05..aaf6272 100644
--- a/sphinx/roles.py
+++ b/sphinx/roles.py
@@ -11,6 +11,7 @@
 
 import re
 
+from six import iteritems
 from docutils import nodes, utils
 from docutils.parsers.rst import roles
 
@@ -22,19 +23,19 @@
 
 
 generic_docroles = {
-    'command' : nodes.strong,
+    'command' : addnodes.literal_strong,
     'dfn' : nodes.emphasis,
     'kbd' : nodes.literal,
     'mailheader' : addnodes.literal_emphasis,
-    'makevar' : nodes.strong,
+    'makevar' : addnodes.literal_strong,
     'manpage' : addnodes.literal_emphasis,
     'mimetype' : addnodes.literal_emphasis,
     'newsgroup' : addnodes.literal_emphasis,
-    'program' : nodes.strong,  # XXX should be an x-ref
+    'program' : addnodes.literal_strong,  # XXX should be an x-ref
     'regexp' : nodes.literal,
 }
 
-for rolename, nodeclass in generic_docroles.iteritems():
+for rolename, nodeclass in iteritems(generic_docroles):
     generic = roles.GenericRole(rolename, nodeclass)
     role = roles.CustomRole(rolename, generic, {'classes': [rolename]})
     roles.register_local_role(rolename, role)
@@ -157,7 +158,7 @@
         return [node], []
 
 
-def indexmarkup_role(typ, rawtext, etext, lineno, inliner,
+def indexmarkup_role(typ, rawtext, text, lineno, inliner,
                      options={}, content=[]):
     """Role for PEP/RFC references that generate an index entry."""
     env = inliner.document.settings.env
@@ -165,47 +166,53 @@
         typ = env.config.default_role
     else:
         typ = typ.lower()
-    text = utils.unescape(etext)
+    has_explicit_title, title, target = split_explicit_title(text)
+    title = utils.unescape(title)
+    target = utils.unescape(target)
     targetid = 'index-%s' % env.new_serialno('index')
     indexnode = addnodes.index()
     targetnode = nodes.target('', '', ids=[targetid])
     inliner.document.note_explicit_target(targetnode)
     if typ == 'pep':
         indexnode['entries'] = [
-            ('single', _('Python Enhancement Proposals; PEP %s') % text,
+            ('single', _('Python Enhancement Proposals; PEP %s') % target,
              targetid, '')]
         anchor = ''
-        anchorindex = text.find('#')
+        anchorindex = target.find('#')
         if anchorindex > 0:
-            text, anchor = text[:anchorindex], text[anchorindex:]
+            target, anchor = target[:anchorindex], target[anchorindex:]
+        if not has_explicit_title:
+            title = "PEP " + utils.unescape(title)
         try:
-            pepnum = int(text)
+            pepnum = int(target)
         except ValueError:
-            msg = inliner.reporter.error('invalid PEP number %s' % text,
+            msg = inliner.reporter.error('invalid PEP number %s' % target,
                                          line=lineno)
             prb = inliner.problematic(rawtext, rawtext, msg)
             return [prb], [msg]
         ref = inliner.document.settings.pep_base_url + 'pep-%04d' % pepnum
-        sn = nodes.strong('PEP '+text, 'PEP '+text)
+        sn = nodes.strong(title, title)
         rn = nodes.reference('', '', internal=False, refuri=ref+anchor,
                              classes=[typ])
         rn += sn
         return [indexnode, targetnode, rn], []
     elif typ == 'rfc':
-        indexnode['entries'] = [('single', 'RFC; RFC %s' % text, targetid, '')]
+        indexnode['entries'] = [('single', 'RFC; RFC %s' % target, targetid, '')]
         anchor = ''
-        anchorindex = text.find('#')
+        anchorindex = target.find('#')
         if anchorindex > 0:
-            text, anchor = text[:anchorindex], text[anchorindex:]
+            target, anchor = target[:anchorindex], target[anchorindex:]
+        if not has_explicit_title:
+            title = "RFC " + utils.unescape(title)
         try:
-            rfcnum = int(text)
+            rfcnum = int(target)
         except ValueError:
-            msg = inliner.reporter.error('invalid RFC number %s' % text,
+            msg = inliner.reporter.error('invalid RFC number %s' % target,
                                          line=lineno)
             prb = inliner.problematic(rawtext, rawtext, msg)
             return [prb], [msg]
         ref = inliner.document.settings.rfc_base_url + inliner.rfc_url % rfcnum
-        sn = nodes.strong('RFC '+text, 'RFC '+text)
+        sn = nodes.strong(title, title)
         rn = nodes.reference('', '', internal=False, refuri=ref+anchor,
                              classes=[typ])
         rn += sn
@@ -263,10 +270,12 @@
     text = utils.unescape(text)
     m = _abbr_re.search(text)
     if m is None:
-        return [addnodes.abbreviation(text, text)], []
+        return [addnodes.abbreviation(text, text, **options)], []
     abbr = text[:m.start()].strip()
     expl = m.group(1)
-    return [addnodes.abbreviation(abbr, abbr, explanation=expl)], []
+    options = options.copy()
+    options['explanation'] = expl
+    return [addnodes.abbreviation(abbr, abbr, **options)], []
 
 
 def index_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
@@ -313,5 +322,5 @@
     'index': index_role,
 }
 
-for rolename, func in specific_docroles.iteritems():
+for rolename, func in iteritems(specific_docroles):
     roles.register_local_role(rolename, func)
diff --git a/sphinx/search/__init__.py b/sphinx/search/__init__.py
index bd95ecc..b81e08b 100644
--- a/sphinx/search/__init__.py
+++ b/sphinx/search/__init__.py
@@ -9,9 +9,11 @@
     :license: BSD, see LICENSE for details.
 """
 from __future__ import with_statement
-import re
-import cPickle as pickle
 
+import re
+
+from six import iteritems, itervalues, text_type, string_types
+from six.moves import cPickle as pickle
 from docutils.nodes import raw, comment, title, Text, NodeVisitor, SkipNode
 
 from sphinx.util import jsdump, rpartition
@@ -40,6 +42,7 @@
        type, before searching index. Default implementation does nothing.
     """
     lang = None
+    language_name = None
     stopwords = set()
     js_stemmer_code = """
 /**
@@ -89,16 +92,49 @@
         Return true if the target word should be registered in the search index.
         This method is called after stemming.
         """
-        return not (((len(word) < 3) and (12353 < ord(word[0]) < 12436)) or
-            (ord(word[0]) < 256 and (len(word) < 3 or word in self.stopwords or
-                                     word.isdigit())))
+        return (
+            len(word) == 0 or not (
+                ((len(word) < 3) and (12353 < ord(word[0]) < 12436)) or
+                (ord(word[0]) < 256 and (
+                    len(word) < 3 or word in self.stopwords or word.isdigit()
+                ))))
 
 
-from sphinx.search import en, ja
+# SearchEnglish imported after SearchLanguage is defined due to circular import
+from sphinx.search.en import SearchEnglish
 
+
+def parse_stop_word(source):
+    """
+    parse snowball style word list like this:
+
+    * http://snowball.tartarus.org/algorithms/finnish/stop.txt
+    """
+    result = set()
+    for line in source.splitlines():
+        line = line.split('|')[0] # remove comment
+        result.update(line.split())
+    return result
+
+
+# maps language name to module.class or directly a class
 languages = {
-    'en': en.SearchEnglish,
-    'ja': ja.SearchJapanese,
+    'da': 'sphinx.search.da.SearchDanish',
+    'de': 'sphinx.search.de.SearchGerman',
+    'en': SearchEnglish,
+    'es': 'sphinx.search.es.SearchSpanish',
+    'fi': 'sphinx.search.fi.SearchFinnish',
+    'fr': 'sphinx.search.fr.SearchFrench',
+    'hu': 'sphinx.search.hu.SearchHungarian',
+    'it': 'sphinx.search.it.SearchItalian',
+    'ja': 'sphinx.search.ja.SearchJapanese',
+    'nl': 'sphinx.search.nl.SearchDutch',
+    'no': 'sphinx.search.no.SearchNorwegian',
+    'pt': 'sphinx.search.pt.SearchPortuguese',
+    'ro': 'sphinx.search.ro.SearchRomanian',
+    'ru': 'sphinx.search.ru.SearchRussian',
+    'sv': 'sphinx.search.sv.SearchSwedish',
+    'tr': 'sphinx.search.tr.SearchTurkish',
 }
 
 
@@ -185,7 +221,17 @@
         # objtype index -> (domain, type, objname (localized))
         self._objnames = {}
         # add language-specific SearchLanguage instance
-        self.lang = languages[lang](options)
+        lang_class = languages.get(lang)
+        if lang_class is None:
+            self.lang = SearchEnglish(options)
+        elif isinstance(lang_class, str):
+            module, classname = lang_class.rsplit('.', 1)
+            lang_class = getattr(__import__(module, None, None, [classname]),
+                                 classname)
+            self.lang = lang_class(options)
+        else:
+            # it's directly a class (e.g. added by app.add_search_language)
+            self.lang = lang_class(options)
 
         if scoring:
             with open(scoring, 'rb') as fp:
@@ -195,7 +241,7 @@
 
     def load(self, stream, format):
         """Reconstruct from frozen data."""
-        if isinstance(format, basestring):
+        if isinstance(format, string_types):
             format = self.formats[format]
         frozen = format.load(stream)
         # if an old index is present, we treat it as not existing.
@@ -207,7 +253,7 @@
 
         def load_terms(mapping):
             rv = {}
-            for k, v in mapping.iteritems():
+            for k, v in iteritems(mapping):
                 if isinstance(v, int):
                     rv[k] = set([index2fn[v]])
                 else:
@@ -220,7 +266,7 @@
 
     def dump(self, stream, format):
         """Dump the frozen index to a stream."""
-        if isinstance(format, basestring):
+        if isinstance(format, string_types):
             format = self.formats[format]
         format.dump(self.freeze(), stream)
 
@@ -228,7 +274,7 @@
         rv = {}
         otypes = self._objtypes
         onames = self._objnames
-        for domainname, domain in self.env.domains.iteritems():
+        for domainname, domain in iteritems(self.env.domains):
             for fullname, dispname, type, docname, anchor, prio in \
                     domain.get_objects():
                 # XXX use dispname?
@@ -247,7 +293,7 @@
                     if otype:
                         # use unicode() to fire translation proxies
                         onames[typeindex] = (domainname, type,
-                            unicode(domain.get_type_name(otype)))
+                            text_type(domain.get_type_name(otype)))
                     else:
                         onames[typeindex] = (domainname, type, type)
                 if anchor == fullname:
@@ -262,7 +308,7 @@
     def get_terms(self, fn2index):
         rvs = {}, {}
         for rv, mapping in zip(rvs, (self._mapping, self._title_mapping)):
-            for k, v in mapping.iteritems():
+            for k, v in iteritems(mapping):
                 if len(v) == 1:
                     fn, = v
                     if fn in fn2index:
@@ -273,19 +319,22 @@
 
     def freeze(self):
         """Create a usable data structure for serializing."""
-        filenames = self._titles.keys()
-        titles = self._titles.values()
+        filenames = list(self._titles.keys())
+        titles = list(self._titles.values())
         fn2index = dict((f, i) for (i, f) in enumerate(filenames))
         terms, title_terms = self.get_terms(fn2index)
 
         objects = self.get_objects(fn2index)  # populates _objtypes
         objtypes = dict((v, k[0] + ':' + k[1])
-                        for (k, v) in self._objtypes.iteritems())
+                        for (k, v) in iteritems(self._objtypes))
         objnames = self._objnames
         return dict(filenames=filenames, titles=titles, terms=terms,
                     objects=objects, objtypes=objtypes, objnames=objnames,
                     titleterms=title_terms, envversion=self.env.version)
 
+    def label(self):
+        return "%s (code: %s)" % (self.lang.language_name, self.lang.lang)
+
     def prune(self, filenames):
         """Remove data for all filenames not in the list."""
         new_titles = {}
@@ -293,9 +342,9 @@
             if filename in self._titles:
                 new_titles[filename] = self._titles[filename]
         self._titles = new_titles
-        for wordnames in self._mapping.itervalues():
+        for wordnames in itervalues(self._mapping):
             wordnames.intersection_update(filenames)
-        for wordnames in self._title_mapping.itervalues():
+        for wordnames in itervalues(self._title_mapping):
             wordnames.intersection_update(filenames)
 
     def feed(self, filename, title, doctree):
diff --git a/sphinx/search/da.py b/sphinx/search/da.py
new file mode 100644
index 0000000..755122b
--- /dev/null
+++ b/sphinx/search/da.py
@@ -0,0 +1,130 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.search.da
+    ~~~~~~~~~~~~~~~~
+
+    Danish search language: includes the JS Danish stemmer.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from sphinx.search import SearchLanguage, parse_stop_word
+
+import snowballstemmer
+
+danish_stopwords = parse_stop_word(u'''
+| source: http://snowball.tartarus.org/algorithms/danish/stop.txt
+og           | and
+i            | in
+jeg          | I
+det          | that (dem. pronoun)/it (pers. pronoun)
+at           | that (in front of a sentence)/to (with infinitive)
+en           | a/an
+den          | it (pers. pronoun)/that (dem. pronoun)
+til          | to/at/for/until/against/by/of/into, more
+er           | present tense of "to be"
+som          | who, as
+på           | on/upon/in/on/at/to/after/of/with/for, on
+de           | they
+med          | with/by/in, along
+han          | he
+af           | of/by/from/off/for/in/with/on, off
+for          | at/for/to/from/by/of/ago, in front/before, because
+ikke         | not
+der          | who/which, there/those
+var          | past tense of "to be"
+mig          | me/myself
+sig          | oneself/himself/herself/itself/themselves
+men          | but
+et           | a/an/one, one (number), someone/somebody/one
+har          | present tense of "to have"
+om           | round/about/for/in/a, about/around/down, if
+vi           | we
+min          | my
+havde        | past tense of "to have"
+ham          | him
+hun          | she
+nu           | now
+over         | over/above/across/by/beyond/past/on/about, over/past
+da           | then, when/as/since
+fra          | from/off/since, off, since
+du           | you
+ud           | out
+sin          | his/her/its/one's
+dem          | them
+os           | us/ourselves
+op           | up
+man          | you/one
+hans         | his
+hvor         | where
+eller        | or
+hvad         | what
+skal         | must/shall etc.
+selv         | myself/youself/herself/ourselves etc., even
+her          | here
+alle         | all/everyone/everybody etc.
+vil          | will (verb)
+blev         | past tense of "to stay/to remain/to get/to become"
+kunne        | could
+ind          | in
+når          | when
+være         | present tense of "to be"
+dog          | however/yet/after all
+noget        | something
+ville        | would
+jo           | you know/you see (adv), yes
+deres        | their/theirs
+efter        | after/behind/according to/for/by/from, later/afterwards
+ned          | down
+skulle       | should
+denne        | this
+end          | than
+dette        | this
+mit          | my/mine
+også         | also
+under        | under/beneath/below/during, below/underneath
+have         | have
+dig          | you
+anden        | other
+hende        | her
+mine         | my
+alt          | everything
+meget        | much/very, plenty of
+sit          | his, her, its, one's
+sine         | his, her, its, one's
+vor          | our
+mod          | against
+disse        | these
+hvis         | if
+din          | your/yours
+nogle        | some
+hos          | by/at
+blive        | be/become
+mange        | many
+ad           | by/through
+bliver       | present tense of "to be/to become"
+hendes       | her/hers
+været        | be
+thi          | for (conj)
+jer          | you
+sådan        | such, like this/like that
+''')
+
+js_stemmer = u"""
+var JSX={};(function(g){function j(b,e){var a=function(){};a.prototype=e.prototype;var c=new a;for(var d in b){b[d].prototype=c}}function I(c,b){for(var a in b.prototype)if(b.prototype.hasOwnProperty(a))c.prototype[a]=b.prototype[a]}function i(a,b,d){function c(a,b,c){delete a[b];a[b]=c;return c}Object.defineProperty(a,b,{get:function(){return c(a,b,d())},set:function(d){c(a,b,d)},enumerable:true,configurable:true})}function J(a,b,c){return a[b]=a[b]/c|0}var E=parseInt;var D=parseFloat;function K(a){return a!==a}var A=isFinite;var z=encodeURIComponent;var y=decodeURIComponent;var x=encodeURI;var w=decodeURI;var u=Object.prototype.toString;var C=Object.prototype.hasOwnProperty;function f(){}g.require=function(b){var a=p[b];return a!==undefined?a:null};g.profilerIsRunning=function(){return f.getResults!=null};g.getProfileResults=function(){return(f.getResults||function(){return{}})()};g.postProfileResults=function(a,b){if(f.postResults==null)throw new Error('profiler has not been turned on');return f.postResults(a,b)};g.resetProfileResults=function(){if(f.resetResults==null)throw new Error('profiler has not been turned on');return f.resetResults()};g.DEBUG=false;function t(){};j([t],Error);function b(a,b,c){this.G=a.length;this.S=a;this.V=b;this.J=c;this.I=null;this.W=null};j([b],Object);function l(){};j([l],Object);function d(){var a;var b;var c;this.F={};a=this.D='';b=this._=0;c=this.A=a.length;this.B=0;this.C=b;this.E=c};j([d],l);function v(a,b){a.D=b.D;a._=b._;a.A=b.A;a.B=b.B;a.C=b.C;a.E=b.E};function n(b,d,c,e){var a;if(b._>=b.A){return false}a=b.D.charCodeAt(b._);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._++;return true};function m(b,d,c,e){var a;if(b._<=b.B){return false}a=b.D.charCodeAt(b._-1);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._--;return true};function r(a,d,c,e){var b;if(a._>=a.A){return false}b=a.D.charCodeAt(a._);if(b>e||b<c){a._++;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._++;return true}return false};function q(a,d,c,e){var b;if(a._<=a.B){return false}b=a.D.charCodeAt(a._-1);if(b>e||b<c){a._--;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._--;return true}return false};function h(a,b,d){var c;if(a._-a.B<b){return false}if(a.D.slice((c=a._)-b,c)!==d){return false}a._-=b;return true};function e(d,m,p){var b;var g;var e;var n;var f;var k;var l;var i;var h;var c;var a;var j;var o;b=0;g=p;e=d._;n=d.B;f=0;k=0;l=false;while(true){i=b+(g-b>>1);h=0;c=f<k?f:k;a=m[i];for(j=a.G-1-c;j>=0;j--){if(e-c===n){h=-1;break}h=d.D.charCodeAt(e-1-c)-a.S.charCodeAt(j);if(h!==0){break}c++}if(h<0){g=i;k=c}else{b=i;f=c}if(g-b<=1){if(b>0){break}if(g===b){break}if(l){break}l=true}}while(true){a=m[b];if(f>=a.G){d._=e-a.G|0;if(a.I==null){return a.J}o=a.I(d);d._=e-a.G|0;if(o){return a.J}}b=a.V;if(b<0){return 0}}return-1};function s(a,b,d,e){var c;c=e.length-(d-b);a.D=a.D.slice(0,b)+e+a.D.slice(d);a.A+=c|0;if(a._>=d){a._+=c|0}else if(a._>b){a._=b}return c|0};function c(a,f){var b;var c;var d;var e;b=false;if((c=a.C)<0||c>(d=a.E)||d>(e=a.A)||e>a.D.length?false:true){s(a,a.C,a.E,f);b=true}return b};function o(a,f){var b;var c;var d;var e;b='';if((c=a.C)<0||c>(d=a.E)||d>(e=a.A)||e>a.D.length?false:true){b=a.D.slice(a.C,a.E)}return b};d.prototype.H=function(){return false};d.prototype.T=function(b){var a;var c;var d;var e;a=this.F['.'+b];if(a==null){c=this.D=b;d=this._=0;e=this.A=c.length;this.B=0;this.C=d;this.E=e;this.H();a=this.D;this.F['.'+b]=a}return a};d.prototype.stemWord=d.prototype.T;d.prototype.U=function(e){var d;var b;var c;var a;var f;var g;var h;d=[];for(b=0;b<e.length;b++){c=e[b];a=this.F['.'+c];if(a==null){f=this.D=c;g=this._=0;h=this.A=f.length;this.B=0;this.C=g;this.E=h;this.H();a=this.D;this.F['.'+c]=a}d.push(a)}return d};d.prototype.stemWords=d.prototype.U;function a(){d.call(this);this.I_x=0;this.I_p1=0;this.S_ch=''};j([a],d);a.prototype.K=function(a){this.I_x=a.I_x;this.I_p1=a.I_p1;this.S_ch=a.S_ch;v(this,a)};a.prototype.copy_from=a.prototype.K;a.prototype.P=function(){var g;var d;var b;var e;var c;var f;var i;var j;var k;var h;this.I_p1=j=this.A;g=i=this._;b=i+3|0;if(0>b||b>j){return false}h=this._=b;this.I_x=h;this._=g;a:while(true){d=this._;e=true;b:while(e===true){e=false;if(!n(this,a.g_v,97,248)){break b}this._=d;break a}k=this._=d;if(k>=this.A){return false}this._++}a:while(true){c=true;b:while(c===true){c=false;if(!r(this,a.g_v,97,248)){break b}break a}if(this._>=this.A){return false}this._++}this.I_p1=this._;f=true;a:while(f===true){f=false;if(!(this.I_p1<this.I_x)){break a}this.I_p1=this.I_x}return true};a.prototype.r_mark_regions=a.prototype.P;function G(b){var h;var e;var c;var f;var d;var g;var j;var k;var l;var i;b.I_p1=k=b.A;h=j=b._;c=j+3|0;if(0>c||c>k){return false}i=b._=c;b.I_x=i;b._=h;a:while(true){e=b._;f=true;b:while(f===true){f=false;if(!n(b,a.g_v,97,248)){break b}b._=e;break a}l=b._=e;if(l>=b.A){return false}b._++}a:while(true){d=true;b:while(d===true){d=false;if(!r(b,a.g_v,97,248)){break b}break a}if(b._>=b.A){return false}b._++}b.I_p1=b._;g=true;a:while(g===true){g=false;if(!(b.I_p1<b.I_x)){break a}b.I_p1=b.I_x}return true};a.prototype.O=function(){var b;var f;var d;var g;var h;var i;f=this.A-(g=this._);if(g<this.I_p1){return false}h=this._=this.I_p1;d=this.B;this.B=h;i=this._=this.A-f;this.E=i;b=e(this,a.a_0,32);if(b===0){this.B=d;return false}this.C=this._;this.B=d;switch(b){case 0:return false;case 1:if(!c(this,'')){return false}break;case 2:if(!m(this,a.g_s_ending,97,229)){return false}if(!c(this,'')){return false}break}return true};a.prototype.r_main_suffix=a.prototype.O;function H(b){var d;var g;var f;var h;var i;var j;g=b.A-(h=b._);if(h<b.I_p1){return false}i=b._=b.I_p1;f=b.B;b.B=i;j=b._=b.A-g;b.E=j;d=e(b,a.a_0,32);if(d===0){b.B=f;return false}b.C=b._;b.B=f;switch(d){case 0:return false;case 1:if(!c(b,'')){return false}break;case 2:if(!m(b,a.g_s_ending,97,229)){return false}if(!c(b,'')){return false}break}return true};a.prototype.N=function(){var f;var g;var b;var h;var d;var i;var j;var k;var l;f=(h=this.A)-(d=this._);g=h-d;if(d<this.I_p1){return false}i=this._=this.I_p1;b=this.B;this.B=i;j=this._=this.A-g;this.E=j;if(e(this,a.a_1,4)===0){this.B=b;return false}this.C=this._;l=this.B=b;k=this._=this.A-f;if(k<=l){return false}this._--;this.C=this._;return!c(this,'')?false:true};a.prototype.r_consonant_pair=a.prototype.N;function k(b){var i;var j;var d;var g;var f;var k;var l;var m;var h;i=(g=b.A)-(f=b._);j=g-f;if(f<b.I_p1){return false}k=b._=b.I_p1;d=b.B;b.B=k;l=b._=b.A-j;b.E=l;if(e(b,a.a_1,4)===0){b.B=d;return false}b.C=b._;h=b.B=d;m=b._=b.A-i;if(m<=h){return false}b._--;b.C=b._;return!c(b,'')?false:true};a.prototype.Q=function(){var f;var l;var m;var d;var j;var b;var g;var n;var i;var p;var o;l=this.A-this._;b=true;a:while(b===true){b=false;this.E=this._;if(!h(this,2,'st')){break a}this.C=this._;if(!h(this,2,'ig')){break a}if(!c(this,'')){return false}}i=this._=(n=this.A)-l;m=n-i;if(i<this.I_p1){return false}p=this._=this.I_p1;d=this.B;this.B=p;o=this._=this.A-m;this.E=o;f=e(this,a.a_2,5);if(f===0){this.B=d;return false}this.C=this._;this.B=d;switch(f){case 0:return false;case 1:if(!c(this,'')){return false}j=this.A-this._;g=true;a:while(g===true){g=false;if(!k(this)){break a}}this._=this.A-j;break;case 2:if(!c(this,'løs')){return false}break}return true};a.prototype.r_other_suffix=a.prototype.Q;function F(b){var d;var p;var m;var f;var l;var g;var i;var o;var j;var q;var n;p=b.A-b._;g=true;a:while(g===true){g=false;b.E=b._;if(!h(b,2,'st')){break a}b.C=b._;if(!h(b,2,'ig')){break a}if(!c(b,'')){return false}}j=b._=(o=b.A)-p;m=o-j;if(j<b.I_p1){return false}q=b._=b.I_p1;f=b.B;b.B=q;n=b._=b.A-m;b.E=n;d=e(b,a.a_2,5);if(d===0){b.B=f;return false}b.C=b._;b.B=f;switch(d){case 0:return false;case 1:if(!c(b,'')){return false}l=b.A-b._;i=true;a:while(i===true){i=false;if(!k(b)){break a}}b._=b.A-l;break;case 2:if(!c(b,'løs')){return false}break}return true};a.prototype.R=function(){var e;var b;var d;var f;var g;var i;var j;e=this.A-(f=this._);if(f<this.I_p1){return false}g=this._=this.I_p1;b=this.B;this.B=g;i=this._=this.A-e;this.E=i;if(!q(this,a.g_v,97,248)){this.B=b;return false}this.C=this._;j=this.S_ch=o(this,this.S_ch);if(j===''){return false}this.B=b;return!(d=this.S_ch,h(this,d.length,d))?false:!c(this,'')?false:true};a.prototype.r_undouble=a.prototype.R;function B(b){var f;var d;var e;var g;var i;var j;var k;f=b.A-(g=b._);if(g<b.I_p1){return false}i=b._=b.I_p1;d=b.B;b.B=i;j=b._=b.A-f;b.E=j;if(!q(b,a.g_v,97,248)){b.B=d;return false}b.C=b._;k=b.S_ch=o(b,b.S_ch);if(k===''){return false}b.B=d;return!(e=b.S_ch,h(b,e.length,e))?false:!c(b,'')?false:true};a.prototype.H=function(){var i;var g;var h;var j;var b;var c;var d;var a;var e;var l;var m;var n;var o;var p;var q;var f;i=this._;b=true;a:while(b===true){b=false;if(!G(this)){break a}}l=this._=i;this.B=l;n=this._=m=this.A;g=m-n;c=true;a:while(c===true){c=false;if(!H(this)){break a}}p=this._=(o=this.A)-g;h=o-p;d=true;a:while(d===true){d=false;if(!k(this)){break a}}f=this._=(q=this.A)-h;j=q-f;a=true;a:while(a===true){a=false;if(!F(this)){break a}}this._=this.A-j;e=true;a:while(e===true){e=false;if(!B(this)){break a}}this._=this.B;return true};a.prototype.stem=a.prototype.H;a.prototype.L=function(b){return b instanceof a};a.prototype.equals=a.prototype.L;a.prototype.M=function(){var c;var a;var b;var d;c='DanishStemmer';a=0;for(b=0;b<c.length;b++){d=c.charCodeAt(b);a=(a<<5)-a+d;a=a&a}return a|0};a.prototype.hashCode=a.prototype.M;a.serialVersionUID=1;i(a,'methodObject',function(){return new a});i(a,'a_0',function(){return[new b('hed',-1,1),new b('ethed',0,1),new b('ered',-1,1),new b('e',-1,1),new b('erede',3,1),new b('ende',3,1),new b('erende',5,1),new b('ene',3,1),new b('erne',3,1),new b('ere',3,1),new b('en',-1,1),new b('heden',10,1),new b('eren',10,1),new b('er',-1,1),new b('heder',13,1),new b('erer',13,1),new b('s',-1,2),new b('heds',16,1),new b('es',16,1),new b('endes',18,1),new b('erendes',19,1),new b('enes',18,1),new b('ernes',18,1),new b('eres',18,1),new b('ens',16,1),new b('hedens',24,1),new b('erens',24,1),new b('ers',16,1),new b('ets',16,1),new b('erets',28,1),new b('et',-1,1),new b('eret',30,1)]});i(a,'a_1',function(){return[new b('gd',-1,-1),new b('dt',-1,-1),new b('gt',-1,-1),new b('kt',-1,-1)]});i(a,'a_2',function(){return[new b('ig',-1,1),new b('lig',0,1),new b('elig',1,1),new b('els',-1,1),new b('løst',-1,2)]});i(a,'g_v',function(){return[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128]});i(a,'g_s_ending',function(){return[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16]});var p={'src/stemmer.jsx':{Stemmer:l},'src/danish-stemmer.jsx':{DanishStemmer:a}}}(JSX))
+var Stemmer = JSX.require("src/danish-stemmer.jsx").DanishStemmer;
+"""
+
+
+class SearchDanish(SearchLanguage):
+    lang = 'da'
+    language_name = 'Danish'
+    js_stemmer_code = js_stemmer
+    stopwords = danish_stopwords
+
+    def init(self, options):
+        self.stemmer = snowballstemmer.stemmer('danish')
+
+    def stem(self, word):
+        return self.stemmer.stemWord(word)
diff --git a/sphinx/search/de.py b/sphinx/search/de.py
new file mode 100644
index 0000000..b46c7dd
--- /dev/null
+++ b/sphinx/search/de.py
@@ -0,0 +1,313 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.search.de
+    ~~~~~~~~~~~~~~~~
+
+    German search language: includes the JS German stemmer.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from sphinx.search import SearchLanguage, parse_stop_word
+
+import snowballstemmer
+
+german_stopwords = parse_stop_word(u'''
+|source: http://snowball.tartarus.org/algorithms/german/stop.txt
+aber           |  but
+
+alle           |  all
+allem
+allen
+aller
+alles
+
+als            |  than, as
+also           |  so
+am             |  an + dem
+an             |  at
+
+ander          |  other
+andere
+anderem
+anderen
+anderer
+anderes
+anderm
+andern
+anderr
+anders
+
+auch           |  also
+auf            |  on
+aus            |  out of
+bei            |  by
+bin            |  am
+bis            |  until
+bist           |  art
+da             |  there
+damit          |  with it
+dann           |  then
+
+der            |  the
+den
+des
+dem
+die
+das
+
+daß            |  that
+
+derselbe       |  the same
+derselben
+denselben
+desselben
+demselben
+dieselbe
+dieselben
+dasselbe
+
+dazu           |  to that
+
+dein           |  thy
+deine
+deinem
+deinen
+deiner
+deines
+
+denn           |  because
+
+derer          |  of those
+dessen         |  of him
+
+dich           |  thee
+dir            |  to thee
+du             |  thou
+
+dies           |  this
+diese
+diesem
+diesen
+dieser
+dieses
+
+
+doch           |  (several meanings)
+dort           |  (over) there
+
+
+durch          |  through
+
+ein            |  a
+eine
+einem
+einen
+einer
+eines
+
+einig          |  some
+einige
+einigem
+einigen
+einiger
+einiges
+
+einmal         |  once
+
+er             |  he
+ihn            |  him
+ihm            |  to him
+
+es             |  it
+etwas          |  something
+
+euer           |  your
+eure
+eurem
+euren
+eurer
+eures
+
+für            |  for
+gegen          |  towards
+gewesen        |  p.p. of sein
+hab            |  have
+habe           |  have
+haben          |  have
+hat            |  has
+hatte          |  had
+hatten         |  had
+hier           |  here
+hin            |  there
+hinter         |  behind
+
+ich            |  I
+mich           |  me
+mir            |  to me
+
+
+ihr            |  you, to her
+ihre
+ihrem
+ihren
+ihrer
+ihres
+euch           |  to you
+
+im             |  in + dem
+in             |  in
+indem          |  while
+ins            |  in + das
+ist            |  is
+
+jede           |  each, every
+jedem
+jeden
+jeder
+jedes
+
+jene           |  that
+jenem
+jenen
+jener
+jenes
+
+jetzt          |  now
+kann           |  can
+
+kein           |  no
+keine
+keinem
+keinen
+keiner
+keines
+
+können         |  can
+könnte         |  could
+machen         |  do
+man            |  one
+
+manche         |  some, many a
+manchem
+manchen
+mancher
+manches
+
+mein           |  my
+meine
+meinem
+meinen
+meiner
+meines
+
+mit            |  with
+muss           |  must
+musste         |  had to
+nach           |  to(wards)
+nicht          |  not
+nichts         |  nothing
+noch           |  still, yet
+nun            |  now
+nur            |  only
+ob             |  whether
+oder           |  or
+ohne           |  without
+sehr           |  very
+
+sein           |  his
+seine
+seinem
+seinen
+seiner
+seines
+
+selbst         |  self
+sich           |  herself
+
+sie            |  they, she
+ihnen          |  to them
+
+sind           |  are
+so             |  so
+
+solche         |  such
+solchem
+solchen
+solcher
+solches
+
+soll           |  shall
+sollte         |  should
+sondern        |  but
+sonst          |  else
+über           |  over
+um             |  about, around
+und            |  and
+
+uns            |  us
+unse
+unsem
+unsen
+unser
+unses
+
+unter          |  under
+viel           |  much
+vom            |  von + dem
+von            |  from
+vor            |  before
+während        |  while
+war            |  was
+waren          |  were
+warst          |  wast
+was            |  what
+weg            |  away, off
+weil           |  because
+weiter         |  further
+
+welche         |  which
+welchem
+welchen
+welcher
+welches
+
+wenn           |  when
+werde          |  will
+werden         |  will
+wie            |  how
+wieder         |  again
+will           |  want
+wir            |  we
+wird           |  will
+wirst          |  willst
+wo             |  where
+wollen         |  want
+wollte         |  wanted
+würde          |  would
+würden         |  would
+zu             |  to
+zum            |  zu + dem
+zur            |  zu + der
+zwar           |  indeed
+zwischen       |  between
+''')
+
+js_stemmer = u"""
+var JSX={};(function(j){function l(b,e){var a=function(){};a.prototype=e.prototype;var c=new a;for(var d in b){b[d].prototype=c}}function H(c,b){for(var a in b.prototype)if(b.prototype.hasOwnProperty(a))c.prototype[a]=b.prototype[a]}function g(a,b,d){function c(a,b,c){delete a[b];a[b]=c;return c}Object.defineProperty(a,b,{get:function(){return c(a,b,d())},set:function(d){c(a,b,d)},enumerable:true,configurable:true})}function I(a,b,c){return a[b]=a[b]/c|0}var C=parseInt;var r=parseFloat;function J(a){return a!==a}var z=isFinite;var y=encodeURIComponent;var x=decodeURIComponent;var w=encodeURI;var u=decodeURI;var t=Object.prototype.toString;var B=Object.prototype.hasOwnProperty;function i(){}j.require=function(b){var a=q[b];return a!==undefined?a:null};j.profilerIsRunning=function(){return i.getResults!=null};j.getProfileResults=function(){return(i.getResults||function(){return{}})()};j.postProfileResults=function(a,b){if(i.postResults==null)throw new Error('profiler has not been turned on');return i.postResults(a,b)};j.resetProfileResults=function(){if(i.resetResults==null)throw new Error('profiler has not been turned on');return i.resetResults()};j.DEBUG=false;function s(){};l([s],Error);function c(a,b,c){this.F=a.length;this.K=a;this.L=b;this.I=c;this.H=null;this.P=null};l([c],Object);function o(){};l([o],Object);function e(){var a;var b;var c;this.G={};a=this.D='';b=this._=0;c=this.A=a.length;this.E=0;this.C=b;this.B=c};l([e],o);function v(a,b){a.D=b.D;a._=b._;a.A=b.A;a.E=b.E;a.C=b.C;a.B=b.B};function f(b,d,c,e){var a;if(b._>=b.A){return false}a=b.D.charCodeAt(b._);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._++;return true};function m(b,d,c,e){var a;if(b._<=b.E){return false}a=b.D.charCodeAt(b._-1);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._--;return true};function n(a,d,c,e){var b;if(a._>=a.A){return false}b=a.D.charCodeAt(a._);if(b>e||b<c){a._++;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._++;return true}return false};function k(a,b,d){var c;if(a.A-a._<b){return false}if(a.D.slice(c=a._,c+b)!==d){return false}a._+=b;return true};function d(a,b,d){var c;if(a._-a.E<b){return false}if(a.D.slice((c=a._)-b,c)!==d){return false}a._-=b;return true};function p(f,m,p){var b;var d;var e;var n;var g;var k;var l;var i;var h;var c;var a;var j;var o;b=0;d=p;e=f._;n=f.A;g=0;k=0;l=false;while(true){i=b+(d-b>>>1);h=0;c=g<k?g:k;a=m[i];for(j=c;j<a.F;j++){if(e+c===n){h=-1;break}h=f.D.charCodeAt(e+c)-a.K.charCodeAt(j);if(h!==0){break}c++}if(h<0){d=i;k=c}else{b=i;g=c}if(d-b<=1){if(b>0){break}if(d===b){break}if(l){break}l=true}}while(true){a=m[b];if(g>=a.F){f._=e+a.F|0;if(a.H==null){return a.I}o=a.H(a.P);f._=e+a.F|0;if(o){return a.I}}b=a.L;if(b<0){return 0}}return-1};function h(d,m,p){var b;var g;var e;var n;var f;var k;var l;var i;var h;var c;var a;var j;var o;b=0;g=p;e=d._;n=d.E;f=0;k=0;l=false;while(true){i=b+(g-b>>1);h=0;c=f<k?f:k;a=m[i];for(j=a.F-1-c;j>=0;j--){if(e-c===n){h=-1;break}h=d.D.charCodeAt(e-1-c)-a.K.charCodeAt(j);if(h!==0){break}c++}if(h<0){g=i;k=c}else{b=i;f=c}if(g-b<=1){if(b>0){break}if(g===b){break}if(l){break}l=true}}while(true){a=m[b];if(f>=a.F){d._=e-a.F|0;if(a.H==null){return a.I}o=a.H(d);d._=e-a.F|0;if(o){return a.I}}b=a.L;if(b<0){return 0}}return-1};function D(a,b,d,e){var c;c=e.length-(d-b);a.D=a.D.slice(0,b)+e+a.D.slice(d);a.A+=c|0;if(a._>=d){a._+=c|0}else if(a._>b){a._=b}return c|0};function b(a,f){var b;var c;var d;var e;b=false;if((c=a.C)<0||c>(d=a.B)||d>(e=a.A)||e>a.D.length?false:true){D(a,a.C,a.B,f);b=true}return b};e.prototype.J=function(){return false};e.prototype.W=function(b){var a;var c;var d;var e;a=this.G['.'+b];if(a==null){c=this.D=b;d=this._=0;e=this.A=c.length;this.E=0;this.C=d;this.B=e;this.J();a=this.D;this.G['.'+b]=a}return a};e.prototype.stemWord=e.prototype.W;e.prototype.X=function(e){var d;var b;var c;var a;var f;var g;var h;d=[];for(b=0;b<e.length;b++){c=e[b];a=this.G['.'+c];if(a==null){f=this.D=c;g=this._=0;h=this.A=f.length;this.E=0;this.C=g;this.B=h;this.J();a=this.D;this.G['.'+c]=a}d.push(a)}return d};e.prototype.stemWords=e.prototype.X;function a(){e.call(this);this.I_x=0;this.I_p2=0;this.I_p1=0};l([a],e);a.prototype.M=function(a){this.I_x=a.I_x;this.I_p2=a.I_p2;this.I_p1=a.I_p1;v(this,a)};a.prototype.copy_from=a.prototype.M;a.prototype.U=function(){var m;var r;var n;var o;var d;var q;var e;var c;var g;var h;var i;var j;var l;var s;var p;m=this._;a:while(true){r=this._;e=true;b:while(e===true){e=false;c=true;c:while(c===true){c=false;n=this._;g=true;d:while(g===true){g=false;this.C=this._;if(!k(this,1,'ß')){break d}this.B=this._;if(!b(this,'ss')){return false}break c}s=this._=n;if(s>=this.A){break b}this._++}continue a}this._=r;break a}this._=m;b:while(true){o=this._;h=true;d:while(h===true){h=false;e:while(true){d=this._;i=true;a:while(i===true){i=false;if(!f(this,a.g_v,97,252)){break a}this.C=this._;j=true;f:while(j===true){j=false;q=this._;l=true;c:while(l===true){l=false;if(!k(this,1,'u')){break c}this.B=this._;if(!f(this,a.g_v,97,252)){break c}if(!b(this,'U')){return false}break f}this._=q;if(!k(this,1,'y')){break a}this.B=this._;if(!f(this,a.g_v,97,252)){break a}if(!b(this,'Y')){return false}}this._=d;break e}p=this._=d;if(p>=this.A){break d}this._++}continue b}this._=o;break b}return true};a.prototype.r_prelude=a.prototype.U;function G(c){var s;var n;var o;var p;var e;var r;var d;var g;var h;var i;var j;var l;var m;var t;var q;s=c._;a:while(true){n=c._;d=true;b:while(d===true){d=false;g=true;c:while(g===true){g=false;o=c._;h=true;d:while(h===true){h=false;c.C=c._;if(!k(c,1,'ß')){break d}c.B=c._;if(!b(c,'ss')){return false}break c}t=c._=o;if(t>=c.A){break b}c._++}continue a}c._=n;break a}c._=s;b:while(true){p=c._;i=true;d:while(i===true){i=false;e:while(true){e=c._;j=true;a:while(j===true){j=false;if(!f(c,a.g_v,97,252)){break a}c.C=c._;l=true;f:while(l===true){l=false;r=c._;m=true;c:while(m===true){m=false;if(!k(c,1,'u')){break c}c.B=c._;if(!f(c,a.g_v,97,252)){break c}if(!b(c,'U')){return false}break f}c._=r;if(!k(c,1,'y')){break a}c.B=c._;if(!f(c,a.g_v,97,252)){break a}if(!b(c,'Y')){return false}}c._=e;break e}q=c._=e;if(q>=c.A){break d}c._++}continue b}c._=p;break b}return true};a.prototype.S=function(){var j;var b;var d;var e;var c;var g;var h;var i;var l;var k;this.I_p1=i=this.A;this.I_p2=i;j=l=this._;b=l+3|0;if(0>b||b>i){return false}k=this._=b;this.I_x=k;this._=j;a:while(true){d=true;b:while(d===true){d=false;if(!f(this,a.g_v,97,252)){break b}break a}if(this._>=this.A){return false}this._++}a:while(true){e=true;b:while(e===true){e=false;if(!n(this,a.g_v,97,252)){break b}break a}if(this._>=this.A){return false}this._++}this.I_p1=this._;c=true;a:while(c===true){c=false;if(!(this.I_p1<this.I_x)){break a}this.I_p1=this.I_x}a:while(true){g=true;b:while(g===true){g=false;if(!f(this,a.g_v,97,252)){break b}break a}if(this._>=this.A){return false}this._++}a:while(true){h=true;b:while(h===true){h=false;if(!n(this,a.g_v,97,252)){break b}break a}if(this._>=this.A){return false}this._++}this.I_p2=this._;return true};a.prototype.r_mark_regions=a.prototype.S;function F(b){var k;var c;var e;var g;var d;var h;var i;var j;var m;var l;b.I_p1=j=b.A;b.I_p2=j;k=m=b._;c=m+3|0;if(0>c||c>j){return false}l=b._=c;b.I_x=l;b._=k;a:while(true){e=true;b:while(e===true){e=false;if(!f(b,a.g_v,97,252)){break b}break a}if(b._>=b.A){return false}b._++}a:while(true){g=true;b:while(g===true){g=false;if(!n(b,a.g_v,97,252)){break b}break a}if(b._>=b.A){return false}b._++}b.I_p1=b._;d=true;a:while(d===true){d=false;if(!(b.I_p1<b.I_x)){break a}b.I_p1=b.I_x}a:while(true){h=true;b:while(h===true){h=false;if(!f(b,a.g_v,97,252)){break b}break a}if(b._>=b.A){return false}b._++}a:while(true){i=true;b:while(i===true){i=false;if(!n(b,a.g_v,97,252)){break b}break a}if(b._>=b.A){return false}b._++}b.I_p2=b._;return true};a.prototype.T=function(){var c;var e;var d;b:while(true){e=this._;d=true;a:while(d===true){d=false;this.C=this._;c=p(this,a.a_0,6);if(c===0){break a}this.B=this._;switch(c){case 0:break a;case 1:if(!b(this,'y')){return false}break;case 2:if(!b(this,'u')){return false}break;case 3:if(!b(this,'a')){return false}break;case 4:if(!b(this,'o')){return false}break;case 5:if(!b(this,'u')){return false}break;case 6:if(this._>=this.A){break a}this._++;break}continue b}this._=e;break b}return true};a.prototype.r_postlude=a.prototype.T;function E(c){var d;var f;var e;b:while(true){f=c._;e=true;a:while(e===true){e=false;c.C=c._;d=p(c,a.a_0,6);if(d===0){break a}c.B=c._;switch(d){case 0:break a;case 1:if(!b(c,'y')){return false}break;case 2:if(!b(c,'u')){return false}break;case 3:if(!b(c,'a')){return false}break;case 4:if(!b(c,'o')){return false}break;case 5:if(!b(c,'u')){return false}break;case 6:if(c._>=c.A){break a}c._++;break}continue b}c._=f;break b}return true};a.prototype.Q=function(){return!(this.I_p1<=this._)?false:true};a.prototype.r_R1=a.prototype.Q;a.prototype.R=function(){return!(this.I_p2<=this._)?false:true};a.prototype.r_R2=a.prototype.R;a.prototype.V=function(){var c;var z;var n;var x;var y;var f;var A;var B;var p;var w;var g;var j;var k;var l;var e;var o;var i;var q;var r;var s;var t;var u;var v;var D;var E;var F;var G;var H;var I;var J;var K;var L;var M;var C;z=this.A-this._;j=true;a:while(j===true){j=false;this.B=this._;c=h(this,a.a_1,7);if(c===0){break a}this.C=D=this._;if(!(!(this.I_p1<=D)?false:true)){break a}switch(c){case 0:break a;case 1:if(!b(this,'')){return false}break;case 2:if(!b(this,'')){return false}n=this.A-this._;k=true;b:while(k===true){k=false;this.B=this._;if(!d(this,1,'s')){this._=this.A-n;break b}this.C=this._;if(!d(this,3,'nis')){this._=this.A-n;break b}if(!b(this,'')){return false}}break;case 3:if(!m(this,a.g_s_ending,98,116)){break a}if(!b(this,'')){return false}break}}G=this._=(F=this.A)-z;x=F-G;l=true;a:while(l===true){l=false;this.B=this._;c=h(this,a.a_2,4);if(c===0){break a}this.C=E=this._;if(!(!(this.I_p1<=E)?false:true)){break a}switch(c){case 0:break a;case 1:if(!b(this,'')){return false}break;case 2:if(!m(this,a.g_st_ending,98,116)){break a}e=this._-3|0;if(this.E>e||e>this.A){break a}this._=e;if(!b(this,'')){return false}break}}C=this._=(M=this.A)-x;y=M-C;o=true;a:while(o===true){o=false;this.B=this._;c=h(this,a.a_4,8);if(c===0){break a}this.C=H=this._;if(!(!(this.I_p2<=H)?false:true)){break a}switch(c){case 0:break a;case 1:if(!b(this,'')){return false}f=this.A-this._;i=true;b:while(i===true){i=false;this.B=this._;if(!d(this,2,'ig')){this._=this.A-f;break b}this.C=I=this._;A=this.A-I;q=true;c:while(q===true){q=false;if(!d(this,1,'e')){break c}this._=this.A-f;break b}J=this._=this.A-A;if(!(!(this.I_p2<=J)?false:true)){this._=this.A-f;break b}if(!b(this,'')){return false}}break;case 2:B=this.A-this._;r=true;b:while(r===true){r=false;if(!d(this,1,'e')){break b}break a}this._=this.A-B;if(!b(this,'')){return false}break;case 3:if(!b(this,'')){return false}p=this.A-this._;s=true;b:while(s===true){s=false;this.B=this._;t=true;c:while(t===true){t=false;w=this.A-this._;u=true;d:while(u===true){u=false;if(!d(this,2,'er')){break d}break c}this._=this.A-w;if(!d(this,2,'en')){this._=this.A-p;break b}}this.C=K=this._;if(!(!(this.I_p1<=K)?false:true)){this._=this.A-p;break b}if(!b(this,'')){return false}}break;case 4:if(!b(this,'')){return false}g=this.A-this._;v=true;b:while(v===true){v=false;this.B=this._;c=h(this,a.a_3,2);if(c===0){this._=this.A-g;break b}this.C=L=this._;if(!(!(this.I_p2<=L)?false:true)){this._=this.A-g;break b}switch(c){case 0:this._=this.A-g;break b;case 1:if(!b(this,'')){return false}break}}break}}this._=this.A-y;return true};a.prototype.r_standard_suffix=a.prototype.V;function A(c){var e;var A;var j;var y;var z;var g;var B;var C;var q;var x;var i;var k;var l;var n;var f;var p;var o;var r;var s;var t;var u;var v;var w;var E;var F;var G;var H;var I;var J;var K;var L;var M;var N;var D;A=c.A-c._;k=true;a:while(k===true){k=false;c.B=c._;e=h(c,a.a_1,7);if(e===0){break a}c.C=E=c._;if(!(!(c.I_p1<=E)?false:true)){break a}switch(e){case 0:break a;case 1:if(!b(c,'')){return false}break;case 2:if(!b(c,'')){return false}j=c.A-c._;l=true;b:while(l===true){l=false;c.B=c._;if(!d(c,1,'s')){c._=c.A-j;break b}c.C=c._;if(!d(c,3,'nis')){c._=c.A-j;break b}if(!b(c,'')){return false}}break;case 3:if(!m(c,a.g_s_ending,98,116)){break a}if(!b(c,'')){return false}break}}H=c._=(G=c.A)-A;y=G-H;n=true;a:while(n===true){n=false;c.B=c._;e=h(c,a.a_2,4);if(e===0){break a}c.C=F=c._;if(!(!(c.I_p1<=F)?false:true)){break a}switch(e){case 0:break a;case 1:if(!b(c,'')){return false}break;case 2:if(!m(c,a.g_st_ending,98,116)){break a}f=c._-3|0;if(c.E>f||f>c.A){break a}c._=f;if(!b(c,'')){return false}break}}D=c._=(N=c.A)-y;z=N-D;p=true;a:while(p===true){p=false;c.B=c._;e=h(c,a.a_4,8);if(e===0){break a}c.C=I=c._;if(!(!(c.I_p2<=I)?false:true)){break a}switch(e){case 0:break a;case 1:if(!b(c,'')){return false}g=c.A-c._;o=true;b:while(o===true){o=false;c.B=c._;if(!d(c,2,'ig')){c._=c.A-g;break b}c.C=J=c._;B=c.A-J;r=true;c:while(r===true){r=false;if(!d(c,1,'e')){break c}c._=c.A-g;break b}K=c._=c.A-B;if(!(!(c.I_p2<=K)?false:true)){c._=c.A-g;break b}if(!b(c,'')){return false}}break;case 2:C=c.A-c._;s=true;b:while(s===true){s=false;if(!d(c,1,'e')){break b}break a}c._=c.A-C;if(!b(c,'')){return false}break;case 3:if(!b(c,'')){return false}q=c.A-c._;t=true;b:while(t===true){t=false;c.B=c._;u=true;c:while(u===true){u=false;x=c.A-c._;v=true;d:while(v===true){v=false;if(!d(c,2,'er')){break d}break c}c._=c.A-x;if(!d(c,2,'en')){c._=c.A-q;break b}}c.C=L=c._;if(!(!(c.I_p1<=L)?false:true)){c._=c.A-q;break b}if(!b(c,'')){return false}}break;case 4:if(!b(c,'')){return false}i=c.A-c._;w=true;b:while(w===true){w=false;c.B=c._;e=h(c,a.a_3,2);if(e===0){c._=c.A-i;break b}c.C=M=c._;if(!(!(c.I_p2<=M)?false:true)){c._=c.A-i;break b}switch(e){case 0:c._=c.A-i;break b;case 1:if(!b(c,'')){return false}break}}break}}c._=c.A-z;return true};a.prototype.J=function(){var f;var g;var h;var b;var a;var c;var d;var i;var j;var e;f=this._;b=true;a:while(b===true){b=false;if(!G(this)){break a}}i=this._=f;g=i;a=true;a:while(a===true){a=false;if(!F(this)){break a}}j=this._=g;this.E=j;this._=this.A;c=true;a:while(c===true){c=false;if(!A(this)){break a}}e=this._=this.E;h=e;d=true;a:while(d===true){d=false;if(!E(this)){break a}}this._=h;return true};a.prototype.stem=a.prototype.J;a.prototype.N=function(b){return b instanceof a};a.prototype.equals=a.prototype.N;a.prototype.O=function(){var c;var a;var b;var d;c='GermanStemmer';a=0;for(b=0;b<c.length;b++){d=c.charCodeAt(b);a=(a<<5)-a+d;a=a&a}return a|0};a.prototype.hashCode=a.prototype.O;a.serialVersionUID=1;g(a,'methodObject',function(){return new a});g(a,'a_0',function(){return[new c('',-1,6),new c('U',0,2),new c('Y',0,1),new c('ä',0,3),new c('ö',0,4),new c('ü',0,5)]});g(a,'a_1',function(){return[new c('e',-1,2),new c('em',-1,1),new c('en',-1,2),new c('ern',-1,1),new c('er',-1,1),new c('s',-1,3),new c('es',5,2)]});g(a,'a_2',function(){return[new c('en',-1,1),new c('er',-1,1),new c('st',-1,2),new c('est',2,1)]});g(a,'a_3',function(){return[new c('ig',-1,1),new c('lich',-1,1)]});g(a,'a_4',function(){return[new c('end',-1,1),new c('ig',-1,2),new c('ung',-1,1),new c('lich',-1,3),new c('isch',-1,2),new c('ik',-1,2),new c('heit',-1,3),new c('keit',-1,4)]});g(a,'g_v',function(){return[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32,8]});g(a,'g_s_ending',function(){return[117,30,5]});g(a,'g_st_ending',function(){return[117,30,4]});var q={'src/stemmer.jsx':{Stemmer:o},'src/german-stemmer.jsx':{GermanStemmer:a}}}(JSX))
+var Stemmer = JSX.require("src/german-stemmer.jsx").GermanStemmer;
+"""
+
+
+class SearchGerman(SearchLanguage):
+    lang = 'de'
+    language_name = 'German'
+    js_stemmer_code = js_stemmer
+    stopwords = german_stopwords
+
+    def init(self, options):
+        self.stemmer = snowballstemmer.stemmer('german')
+
+    def stem(self, word):
+        return self.stemmer.stemWord(word)
diff --git a/sphinx/search/en.py b/sphinx/search/en.py
index 33e8177..3e7aadd 100644
--- a/sphinx/search/en.py
+++ b/sphinx/search/en.py
@@ -15,10 +15,15 @@
     # http://bitbucket.org/methane/porterstemmer/
     from porterstemmer import Stemmer as CStemmer
     CSTEMMER = True
+    PYSTEMMER = False
 except ImportError:
-    from sphinx.util.stemmer import PorterStemmer
     CSTEMMER = False
-
+    try:
+        from Stemmer import Stemmer as PyStemmer
+        PYSTEMMER = True
+    except ImportError:
+        from sphinx.util.stemmer import PorterStemmer
+        PYSTEMMER = False
 
 english_stopwords = set("""
 a  and  are  as  at
@@ -221,6 +226,7 @@
 
 class SearchEnglish(SearchLanguage):
     lang = 'en'
+    language_name = 'English'
     js_stemmer_code = js_porter_stemmer
     stopwords = english_stopwords
 
@@ -229,6 +235,13 @@
             class Stemmer(CStemmer):
                 def stem(self, word):
                     return self(word.lower())
+        elif PYSTEMMER:
+            class Stemmer(object):
+                def __init__(self):
+                    self.stemmer = PyStemmer('porter')
+
+                def stem(self, word):
+                    return self.stemmer.stemWord(word)
         else:
             class Stemmer(PorterStemmer):
                 """All those porter stemmer implementations look hideous;
diff --git a/sphinx/search/es.py b/sphinx/search/es.py
new file mode 100644
index 0000000..659d00f
--- /dev/null
+++ b/sphinx/search/es.py
@@ -0,0 +1,373 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.search.es
+    ~~~~~~~~~~~~~~~~
+
+    Spanish search language: includes the JS Spanish stemmer.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from sphinx.search import SearchLanguage, parse_stop_word
+
+import snowballstemmer
+
+spanish_stopwords = parse_stop_word(u'''
+|source: http://snowball.tartarus.org/algorithms/spanish/stop.txt
+de             |  from, of
+la             |  the, her
+que            |  who, that
+el             |  the
+en             |  in
+y              |  and
+a              |  to
+los            |  the, them
+del            |  de + el
+se             |  himself, from him etc
+las            |  the, them
+por            |  for, by, etc
+un             |  a
+para           |  for
+con            |  with
+no             |  no
+una            |  a
+su             |  his, her
+al             |  a + el
+  | es         from SER
+lo             |  him
+como           |  how
+más            |  more
+pero           |  pero
+sus            |  su plural
+le             |  to him, her
+ya             |  already
+o              |  or
+  | fue        from SER
+este           |  this
+  | ha         from HABER
+sí             |  himself etc
+porque         |  because
+esta           |  this
+  | son        from SER
+entre          |  between
+  | está     from ESTAR
+cuando         |  when
+muy            |  very
+sin            |  without
+sobre          |  on
+  | ser        from SER
+  | tiene      from TENER
+también        |  also
+me             |  me
+hasta          |  until
+hay            |  there is/are
+donde          |  where
+  | han        from HABER
+quien          |  whom, that
+  | están      from ESTAR
+  | estado     from ESTAR
+desde          |  from
+todo           |  all
+nos            |  us
+durante        |  during
+  | estados    from ESTAR
+todos          |  all
+uno            |  a
+les            |  to them
+ni             |  nor
+contra         |  against
+otros          |  other
+  | fueron     from SER
+ese            |  that
+eso            |  that
+  | había      from HABER
+ante           |  before
+ellos          |  they
+e              |  and (variant of y)
+esto           |  this
+mí             |  me
+antes          |  before
+algunos        |  some
+qué            |  what?
+unos           |  a
+yo             |  I
+otro           |  other
+otras          |  other
+otra           |  other
+él             |  he
+tanto          |  so much, many
+esa            |  that
+estos          |  these
+mucho          |  much, many
+quienes        |  who
+nada           |  nothing
+muchos         |  many
+cual           |  who
+  | sea        from SER
+poco           |  few
+ella           |  she
+estar          |  to be
+  | haber      from HABER
+estas          |  these
+  | estaba     from ESTAR
+  | estamos    from ESTAR
+algunas        |  some
+algo           |  something
+nosotros       |  we
+
+      | other forms
+
+mi             |  me
+mis            |  mi plural
+tú             |  thou
+te             |  thee
+ti             |  thee
+tu             |  thy
+tus            |  tu plural
+ellas          |  they
+nosotras       |  we
+vosotros       |  you
+vosotras       |  you
+os             |  you
+mío            |  mine
+mía            |
+míos           |
+mías           |
+tuyo           |  thine
+tuya           |
+tuyos          |
+tuyas          |
+suyo           |  his, hers, theirs
+suya           |
+suyos          |
+suyas          |
+nuestro        |  ours
+nuestra        |
+nuestros       |
+nuestras       |
+vuestro        |  yours
+vuestra        |
+vuestros       |
+vuestras       |
+esos           |  those
+esas           |  those
+
+               | forms of estar, to be (not including the infinitive):
+estoy
+estás
+está
+estamos
+estáis
+están
+esté
+estés
+estemos
+estéis
+estén
+estaré
+estarás
+estará
+estaremos
+estaréis
+estarán
+estaría
+estarías
+estaríamos
+estaríais
+estarían
+estaba
+estabas
+estábamos
+estabais
+estaban
+estuve
+estuviste
+estuvo
+estuvimos
+estuvisteis
+estuvieron
+estuviera
+estuvieras
+estuviéramos
+estuvierais
+estuvieran
+estuviese
+estuvieses
+estuviésemos
+estuvieseis
+estuviesen
+estando
+estado
+estada
+estados
+estadas
+estad
+
+               | forms of haber, to have (not including the infinitive):
+he
+has
+ha
+hemos
+habéis
+han
+haya
+hayas
+hayamos
+hayáis
+hayan
+habré
+habrás
+habrá
+habremos
+habréis
+habrán
+habría
+habrías
+habríamos
+habríais
+habrían
+había
+habías
+habíamos
+habíais
+habían
+hube
+hubiste
+hubo
+hubimos
+hubisteis
+hubieron
+hubiera
+hubieras
+hubiéramos
+hubierais
+hubieran
+hubiese
+hubieses
+hubiésemos
+hubieseis
+hubiesen
+habiendo
+habido
+habida
+habidos
+habidas
+
+               | forms of ser, to be (not including the infinitive):
+soy
+eres
+es
+somos
+sois
+son
+sea
+seas
+seamos
+seáis
+sean
+seré
+serás
+será
+seremos
+seréis
+serán
+sería
+serías
+seríamos
+seríais
+serían
+era
+eras
+éramos
+erais
+eran
+fui
+fuiste
+fue
+fuimos
+fuisteis
+fueron
+fuera
+fueras
+fuéramos
+fuerais
+fueran
+fuese
+fueses
+fuésemos
+fueseis
+fuesen
+siendo
+sido
+  |  sed also means 'thirst'
+
+               | forms of tener, to have (not including the infinitive):
+tengo
+tienes
+tiene
+tenemos
+tenéis
+tienen
+tenga
+tengas
+tengamos
+tengáis
+tengan
+tendré
+tendrás
+tendrá
+tendremos
+tendréis
+tendrán
+tendría
+tendrías
+tendríamos
+tendríais
+tendrían
+tenía
+tenías
+teníamos
+teníais
+tenían
+tuve
+tuviste
+tuvo
+tuvimos
+tuvisteis
+tuvieron
+tuviera
+tuvieras
+tuviéramos
+tuvierais
+tuvieran
+tuviese
+tuvieses
+tuviésemos
+tuvieseis
+tuviesen
+teniendo
+tenido
+tenida
+tenidos
+tenidas
+tened
+''')
+
+js_stemmer = u"""
+var JSX={};(function(k){function l(b,e){var a=function(){};a.prototype=e.prototype;var c=new a;for(var d in b){b[d].prototype=c}}function I(c,b){for(var a in b.prototype)if(b.prototype.hasOwnProperty(a))c.prototype[a]=b.prototype[a]}function g(a,b,d){function c(a,b,c){delete a[b];a[b]=c;return c}Object.defineProperty(a,b,{get:function(){return c(a,b,d())},set:function(d){c(a,b,d)},enumerable:true,configurable:true})}function J(a,b,c){return a[b]=a[b]/c|0}var p=parseInt;var z=parseFloat;function K(a){return a!==a}var x=isFinite;var w=encodeURIComponent;var u=decodeURIComponent;var t=encodeURI;var s=decodeURI;var A=Object.prototype.toString;var q=Object.prototype.hasOwnProperty;function j(){}k.require=function(b){var a=o[b];return a!==undefined?a:null};k.profilerIsRunning=function(){return j.getResults!=null};k.getProfileResults=function(){return(j.getResults||function(){return{}})()};k.postProfileResults=function(a,b){if(j.postResults==null)throw new Error('profiler has not been turned on');return j.postResults(a,b)};k.resetProfileResults=function(){if(j.resetResults==null)throw new Error('profiler has not been turned on');return j.resetResults()};k.DEBUG=false;function r(){};l([r],Error);function a(a,b,c){this.F=a.length;this.K=a;this.L=b;this.I=c;this.H=null;this.P=null};l([a],Object);function m(){};l([m],Object);function i(){var a;var b;var c;this.G={};a=this.E='';b=this._=0;c=this.A=a.length;this.D=0;this.B=b;this.C=c};l([i],m);function v(a,b){a.E=b.E;a._=b._;a.A=b.A;a.D=b.D;a.B=b.B;a.C=b.C};function f(b,d,c,e){var a;if(b._>=b.A){return false}a=b.E.charCodeAt(b._);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._++;return true};function h(a,d,c,e){var b;if(a._>=a.A){return false}b=a.E.charCodeAt(a._);if(b>e||b<c){a._++;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._++;return true}return false};function d(a,b,d){var c;if(a._-a.D<b){return false}if(a.E.slice((c=a._)-b,c)!==d){return false}a._-=b;return true};function n(f,m,p){var b;var d;var e;var n;var g;var k;var l;var i;var h;var c;var a;var j;var o;b=0;d=p;e=f._;n=f.A;g=0;k=0;l=false;while(true){i=b+(d-b>>>1);h=0;c=g<k?g:k;a=m[i];for(j=c;j<a.F;j++){if(e+c===n){h=-1;break}h=f.E.charCodeAt(e+c)-a.K.charCodeAt(j);if(h!==0){break}c++}if(h<0){d=i;k=c}else{b=i;g=c}if(d-b<=1){if(b>0){break}if(d===b){break}if(l){break}l=true}}while(true){a=m[b];if(g>=a.F){f._=e+a.F|0;if(a.H==null){return a.I}o=a.H(a.P);f._=e+a.F|0;if(o){return a.I}}b=a.L;if(b<0){return 0}}return-1};function e(d,m,p){var b;var g;var e;var n;var f;var k;var l;var i;var h;var c;var a;var j;var o;b=0;g=p;e=d._;n=d.D;f=0;k=0;l=false;while(true){i=b+(g-b>>1);h=0;c=f<k?f:k;a=m[i];for(j=a.F-1-c;j>=0;j--){if(e-c===n){h=-1;break}h=d.E.charCodeAt(e-1-c)-a.K.charCodeAt(j);if(h!==0){break}c++}if(h<0){g=i;k=c}else{b=i;f=c}if(g-b<=1){if(b>0){break}if(g===b){break}if(l){break}l=true}}while(true){a=m[b];if(f>=a.F){d._=e-a.F|0;if(a.H==null){return a.I}o=a.H(d);d._=e-a.F|0;if(o){return a.I}}b=a.L;if(b<0){return 0}}return-1};function B(a,b,d,e){var c;c=e.length-(d-b);a.E=a.E.slice(0,b)+e+a.E.slice(d);a.A+=c|0;if(a._>=d){a._+=c|0}else if(a._>b){a._=b}return c|0};function c(a,f){var b;var c;var d;var e;b=false;if((c=a.B)<0||c>(d=a.C)||d>(e=a.A)||e>a.E.length?false:true){B(a,a.B,a.C,f);b=true}return b};i.prototype.J=function(){return false};i.prototype.a=function(b){var a;var c;var d;var e;a=this.G['.'+b];if(a==null){c=this.E=b;d=this._=0;e=this.A=c.length;this.D=0;this.B=d;this.C=e;this.J();a=this.E;this.G['.'+b]=a}return a};i.prototype.stemWord=i.prototype.a;i.prototype.b=function(e){var d;var b;var c;var a;var f;var g;var h;d=[];for(b=0;b<e.length;b++){c=e[b];a=this.G['.'+c];if(a==null){f=this.E=c;g=this._=0;h=this.A=f.length;this.D=0;this.B=g;this.C=h;this.J();a=this.E;this.G['.'+c]=a}d.push(a)}return d};i.prototype.stemWords=i.prototype.b;function b(){i.call(this);this.I_p2=0;this.I_p1=0;this.I_pV=0};l([b],i);b.prototype.M=function(a){this.I_p2=a.I_p2;this.I_p1=a.I_p1;this.I_pV=a.I_pV;v(this,a)};b.prototype.copy_from=b.prototype.M;b.prototype.U=function(){var u;var w;var x;var y;var t;var l;var d;var e;var g;var i;var c;var j;var k;var a;var m;var n;var o;var p;var q;var r;var s;var v;this.I_pV=s=this.A;this.I_p1=s;this.I_p2=s;u=this._;l=true;a:while(l===true){l=false;d=true;g:while(d===true){d=false;w=this._;e=true;b:while(e===true){e=false;if(!f(this,b.g_v,97,252)){break b}g=true;f:while(g===true){g=false;x=this._;i=true;c:while(i===true){i=false;if(!h(this,b.g_v,97,252)){break c}d:while(true){c=true;e:while(c===true){c=false;if(!f(this,b.g_v,97,252)){break e}break d}if(this._>=this.A){break c}this._++}break f}this._=x;if(!f(this,b.g_v,97,252)){break b}c:while(true){j=true;d:while(j===true){j=false;if(!h(this,b.g_v,97,252)){break d}break c}if(this._>=this.A){break b}this._++}}break g}this._=w;if(!h(this,b.g_v,97,252)){break a}k=true;c:while(k===true){k=false;y=this._;a=true;b:while(a===true){a=false;if(!h(this,b.g_v,97,252)){break b}e:while(true){m=true;d:while(m===true){m=false;if(!f(this,b.g_v,97,252)){break d}break e}if(this._>=this.A){break b}this._++}break c}this._=y;if(!f(this,b.g_v,97,252)){break a}if(this._>=this.A){break a}this._++}}this.I_pV=this._}v=this._=u;t=v;n=true;a:while(n===true){n=false;b:while(true){o=true;c:while(o===true){o=false;if(!f(this,b.g_v,97,252)){break c}break b}if(this._>=this.A){break a}this._++}b:while(true){p=true;c:while(p===true){p=false;if(!h(this,b.g_v,97,252)){break c}break b}if(this._>=this.A){break a}this._++}this.I_p1=this._;b:while(true){q=true;c:while(q===true){q=false;if(!f(this,b.g_v,97,252)){break c}break b}if(this._>=this.A){break a}this._++}c:while(true){r=true;b:while(r===true){r=false;if(!h(this,b.g_v,97,252)){break b}break c}if(this._>=this.A){break a}this._++}this.I_p2=this._}this._=t;return true};b.prototype.r_mark_regions=b.prototype.U;function E(a){var x;var y;var z;var u;var v;var l;var d;var e;var g;var i;var j;var k;var c;var m;var n;var o;var p;var q;var r;var s;var t;var w;a.I_pV=t=a.A;a.I_p1=t;a.I_p2=t;x=a._;l=true;a:while(l===true){l=false;d=true;g:while(d===true){d=false;y=a._;e=true;b:while(e===true){e=false;if(!f(a,b.g_v,97,252)){break b}g=true;f:while(g===true){g=false;z=a._;i=true;c:while(i===true){i=false;if(!h(a,b.g_v,97,252)){break c}d:while(true){j=true;e:while(j===true){j=false;if(!f(a,b.g_v,97,252)){break e}break d}if(a._>=a.A){break c}a._++}break f}a._=z;if(!f(a,b.g_v,97,252)){break b}c:while(true){k=true;d:while(k===true){k=false;if(!h(a,b.g_v,97,252)){break d}break c}if(a._>=a.A){break b}a._++}}break g}a._=y;if(!h(a,b.g_v,97,252)){break a}c=true;c:while(c===true){c=false;u=a._;m=true;b:while(m===true){m=false;if(!h(a,b.g_v,97,252)){break b}e:while(true){n=true;d:while(n===true){n=false;if(!f(a,b.g_v,97,252)){break d}break e}if(a._>=a.A){break b}a._++}break c}a._=u;if(!f(a,b.g_v,97,252)){break a}if(a._>=a.A){break a}a._++}}a.I_pV=a._}w=a._=x;v=w;o=true;a:while(o===true){o=false;b:while(true){p=true;c:while(p===true){p=false;if(!f(a,b.g_v,97,252)){break c}break b}if(a._>=a.A){break a}a._++}b:while(true){q=true;c:while(q===true){q=false;if(!h(a,b.g_v,97,252)){break c}break b}if(a._>=a.A){break a}a._++}a.I_p1=a._;b:while(true){r=true;c:while(r===true){r=false;if(!f(a,b.g_v,97,252)){break c}break b}if(a._>=a.A){break a}a._++}c:while(true){s=true;b:while(s===true){s=false;if(!h(a,b.g_v,97,252)){break b}break c}if(a._>=a.A){break a}a._++}a.I_p2=a._}a._=v;return true};b.prototype.V=function(){var a;var e;var d;b:while(true){e=this._;d=true;a:while(d===true){d=false;this.B=this._;a=n(this,b.a_0,6);if(a===0){break a}this.C=this._;switch(a){case 0:break a;case 1:if(!c(this,'a')){return false}break;case 2:if(!c(this,'e')){return false}break;case 3:if(!c(this,'i')){return false}break;case 4:if(!c(this,'o')){return false}break;case 5:if(!c(this,'u')){return false}break;case 6:if(this._>=this.A){break a}this._++;break}continue b}this._=e;break b}return true};b.prototype.r_postlude=b.prototype.V;function F(a){var d;var f;var e;b:while(true){f=a._;e=true;a:while(e===true){e=false;a.B=a._;d=n(a,b.a_0,6);if(d===0){break a}a.C=a._;switch(d){case 0:break a;case 1:if(!c(a,'a')){return false}break;case 2:if(!c(a,'e')){return false}break;case 3:if(!c(a,'i')){return false}break;case 4:if(!c(a,'o')){return false}break;case 5:if(!c(a,'u')){return false}break;case 6:if(a._>=a.A){break a}a._++;break}continue b}a._=f;break b}return true};b.prototype.S=function(){return!(this.I_pV<=this._)?false:true};b.prototype.r_RV=b.prototype.S;b.prototype.Q=function(){return!(this.I_p1<=this._)?false:true};b.prototype.r_R1=b.prototype.Q;b.prototype.R=function(){return!(this.I_p2<=this._)?false:true};b.prototype.r_R2=b.prototype.R;b.prototype.T=function(){var a;this.C=this._;if(e(this,b.a_1,13)===0){return false}this.B=this._;a=e(this,b.a_2,11);if(a===0){return false}if(!(!(this.I_pV<=this._)?false:true)){return false}switch(a){case 0:return false;case 1:this.B=this._;if(!c(this,'iendo')){return false}break;case 2:this.B=this._;if(!c(this,'ando')){return false}break;case 3:this.B=this._;if(!c(this,'ar')){return false}break;case 4:this.B=this._;if(!c(this,'er')){return false}break;case 5:this.B=this._;if(!c(this,'ir')){return false}break;case 6:if(!c(this,'')){return false}break;case 7:if(!d(this,1,'u')){return false}if(!c(this,'')){return false}break}return true};b.prototype.r_attached_pronoun=b.prototype.T;function G(a){var f;a.C=a._;if(e(a,b.a_1,13)===0){return false}a.B=a._;f=e(a,b.a_2,11);if(f===0){return false}if(!(!(a.I_pV<=a._)?false:true)){return false}switch(f){case 0:return false;case 1:a.B=a._;if(!c(a,'iendo')){return false}break;case 2:a.B=a._;if(!c(a,'ando')){return false}break;case 3:a.B=a._;if(!c(a,'ar')){return false}break;case 4:a.B=a._;if(!c(a,'er')){return false}break;case 5:a.B=a._;if(!c(a,'ir')){return false}break;case 6:if(!c(a,'')){return false}break;case 7:if(!d(a,1,'u')){return false}if(!c(a,'')){return false}break}return true};b.prototype.X=function(){var a;var j;var f;var g;var h;var i;var k;var l;var m;var n;var o;var q;var r;var s;var p;this.C=this._;a=e(this,b.a_6,46);if(a===0){return false}this.B=this._;switch(a){case 0:return false;case 1:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'')){return false}break;case 2:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'')){return false}j=this.A-this._;k=true;a:while(k===true){k=false;this.C=this._;if(!d(this,2,'ic')){this._=this.A-j;break a}this.B=q=this._;if(!(!(this.I_p2<=q)?false:true)){this._=this.A-j;break a}if(!c(this,'')){return false}}break;case 3:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'log')){return false}break;case 4:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'u')){return false}break;case 5:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'ente')){return false}break;case 6:if(!(!(this.I_p1<=this._)?false:true)){return false}if(!c(this,'')){return false}f=this.A-this._;l=true;a:while(l===true){l=false;this.C=this._;a=e(this,b.a_3,4);if(a===0){this._=this.A-f;break a}this.B=r=this._;if(!(!(this.I_p2<=r)?false:true)){this._=this.A-f;break a}if(!c(this,'')){return false}switch(a){case 0:this._=this.A-f;break a;case 1:this.C=this._;if(!d(this,2,'at')){this._=this.A-f;break a}this.B=s=this._;if(!(!(this.I_p2<=s)?false:true)){this._=this.A-f;break a}if(!c(this,'')){return false}break}}break;case 7:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'')){return false}g=this.A-this._;m=true;a:while(m===true){m=false;this.C=this._;a=e(this,b.a_4,3);if(a===0){this._=this.A-g;break a}this.B=this._;switch(a){case 0:this._=this.A-g;break a;case 1:if(!(!(this.I_p2<=this._)?false:true)){this._=this.A-g;break a}if(!c(this,'')){return false}break}}break;case 8:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'')){return false}h=this.A-this._;n=true;a:while(n===true){n=false;this.C=this._;a=e(this,b.a_5,3);if(a===0){this._=this.A-h;break a}this.B=this._;switch(a){case 0:this._=this.A-h;break a;case 1:if(!(!(this.I_p2<=this._)?false:true)){this._=this.A-h;break a}if(!c(this,'')){return false}break}}break;case 9:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'')){return false}i=this.A-this._;o=true;a:while(o===true){o=false;this.C=this._;if(!d(this,2,'at')){this._=this.A-i;break a}this.B=p=this._;if(!(!(this.I_p2<=p)?false:true)){this._=this.A-i;break a}if(!c(this,'')){return false}}break}return true};b.prototype.r_standard_suffix=b.prototype.X;function H(a){var f;var k;var g;var h;var i;var j;var l;var m;var n;var o;var p;var r;var s;var t;var q;a.C=a._;f=e(a,b.a_6,46);if(f===0){return false}a.B=a._;switch(f){case 0:return false;case 1:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'')){return false}break;case 2:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'')){return false}k=a.A-a._;l=true;a:while(l===true){l=false;a.C=a._;if(!d(a,2,'ic')){a._=a.A-k;break a}a.B=r=a._;if(!(!(a.I_p2<=r)?false:true)){a._=a.A-k;break a}if(!c(a,'')){return false}}break;case 3:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'log')){return false}break;case 4:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'u')){return false}break;case 5:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'ente')){return false}break;case 6:if(!(!(a.I_p1<=a._)?false:true)){return false}if(!c(a,'')){return false}g=a.A-a._;m=true;a:while(m===true){m=false;a.C=a._;f=e(a,b.a_3,4);if(f===0){a._=a.A-g;break a}a.B=s=a._;if(!(!(a.I_p2<=s)?false:true)){a._=a.A-g;break a}if(!c(a,'')){return false}switch(f){case 0:a._=a.A-g;break a;case 1:a.C=a._;if(!d(a,2,'at')){a._=a.A-g;break a}a.B=t=a._;if(!(!(a.I_p2<=t)?false:true)){a._=a.A-g;break a}if(!c(a,'')){return false}break}}break;case 7:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'')){return false}h=a.A-a._;n=true;a:while(n===true){n=false;a.C=a._;f=e(a,b.a_4,3);if(f===0){a._=a.A-h;break a}a.B=a._;switch(f){case 0:a._=a.A-h;break a;case 1:if(!(!(a.I_p2<=a._)?false:true)){a._=a.A-h;break a}if(!c(a,'')){return false}break}}break;case 8:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'')){return false}i=a.A-a._;o=true;a:while(o===true){o=false;a.C=a._;f=e(a,b.a_5,3);if(f===0){a._=a.A-i;break a}a.B=a._;switch(f){case 0:a._=a.A-i;break a;case 1:if(!(!(a.I_p2<=a._)?false:true)){a._=a.A-i;break a}if(!c(a,'')){return false}break}}break;case 9:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'')){return false}j=a.A-a._;p=true;a:while(p===true){p=false;a.C=a._;if(!d(a,2,'at')){a._=a.A-j;break a}a.B=q=a._;if(!(!(a.I_p2<=q)?false:true)){a._=a.A-j;break a}if(!c(a,'')){return false}}break}return true};b.prototype.Z=function(){var a;var g;var f;var h;var i;var j;g=this.A-(h=this._);if(h<this.I_pV){return false}i=this._=this.I_pV;f=this.D;this.D=i;j=this._=this.A-g;this.C=j;a=e(this,b.a_7,12);if(a===0){this.D=f;return false}this.B=this._;this.D=f;switch(a){case 0:return false;case 1:if(!d(this,1,'u')){return false}if(!c(this,'')){return false}break}return true};b.prototype.r_y_verb_suffix=b.prototype.Z;function D(a){var f;var h;var g;var i;var j;var k;h=a.A-(i=a._);if(i<a.I_pV){return false}j=a._=a.I_pV;g=a.D;a.D=j;k=a._=a.A-h;a.C=k;f=e(a,b.a_7,12);if(f===0){a.D=g;return false}a.B=a._;a.D=g;switch(f){case 0:return false;case 1:if(!d(a,1,'u')){return false}if(!c(a,'')){return false}break}return true};b.prototype.Y=function(){var a;var i;var f;var g;var j;var h;var k;var l;var m;i=this.A-(k=this._);if(k<this.I_pV){return false}l=this._=this.I_pV;f=this.D;this.D=l;m=this._=this.A-i;this.C=m;a=e(this,b.a_8,96);if(a===0){this.D=f;return false}this.B=this._;this.D=f;switch(a){case 0:return false;case 1:g=this.A-this._;h=true;a:while(h===true){h=false;if(!d(this,1,'u')){this._=this.A-g;break a}j=this.A-this._;if(!d(this,1,'g')){this._=this.A-g;break a}this._=this.A-j}this.B=this._;if(!c(this,'')){return false}break;case 2:if(!c(this,'')){return false}break}return true};b.prototype.r_verb_suffix=b.prototype.Y;function C(a){var g;var j;var h;var f;var k;var i;var m;var n;var l;j=a.A-(m=a._);if(m<a.I_pV){return false}n=a._=a.I_pV;h=a.D;a.D=n;l=a._=a.A-j;a.C=l;g=e(a,b.a_8,96);if(g===0){a.D=h;return false}a.B=a._;a.D=h;switch(g){case 0:return false;case 1:f=a.A-a._;i=true;a:while(i===true){i=false;if(!d(a,1,'u')){a._=a.A-f;break a}k=a.A-a._;if(!d(a,1,'g')){a._=a.A-f;break a}a._=a.A-k}a.B=a._;if(!c(a,'')){return false}break;case 2:if(!c(a,'')){return false}break}return true};b.prototype.W=function(){var f;var a;var h;var g;var i;var j;this.C=this._;f=e(this,b.a_9,8);if(f===0){return false}this.B=this._;switch(f){case 0:return false;case 1:if(!(!(this.I_pV<=this._)?false:true)){return false}if(!c(this,'')){return false}break;case 2:if(!(!(this.I_pV<=this._)?false:true)){return false}if(!c(this,'')){return false}a=this.A-this._;g=true;a:while(g===true){g=false;this.C=this._;if(!d(this,1,'u')){this._=this.A-a;break a}this.B=i=this._;h=this.A-i;if(!d(this,1,'g')){this._=this.A-a;break a}j=this._=this.A-h;if(!(!(this.I_pV<=j)?false:true)){this._=this.A-a;break a}if(!c(this,'')){return false}}break}return true};b.prototype.r_residual_suffix=b.prototype.W;function y(a){var g;var f;var i;var h;var j;var k;a.C=a._;g=e(a,b.a_9,8);if(g===0){return false}a.B=a._;switch(g){case 0:return false;case 1:if(!(!(a.I_pV<=a._)?false:true)){return false}if(!c(a,'')){return false}break;case 2:if(!(!(a.I_pV<=a._)?false:true)){return false}if(!c(a,'')){return false}f=a.A-a._;h=true;a:while(h===true){h=false;a.C=a._;if(!d(a,1,'u')){a._=a.A-f;break a}a.B=j=a._;i=a.A-j;if(!d(a,1,'g')){a._=a.A-f;break a}k=a._=a.A-i;if(!(!(a.I_pV<=k)?false:true)){a._=a.A-f;break a}if(!c(a,'')){return false}}break}return true};b.prototype.J=function(){var k;var l;var m;var b;var j;var c;var d;var e;var f;var a;var g;var h;var i;var o;var p;var q;var r;var s;var n;k=this._;c=true;a:while(c===true){c=false;if(!E(this)){break a}}o=this._=k;this.D=o;q=this._=p=this.A;l=p-q;d=true;a:while(d===true){d=false;if(!G(this)){break a}}s=this._=(r=this.A)-l;m=r-s;e=true;b:while(e===true){e=false;f=true;a:while(f===true){f=false;b=this.A-this._;a=true;c:while(a===true){a=false;if(!H(this)){break c}break a}this._=this.A-b;g=true;c:while(g===true){g=false;if(!D(this)){break c}break a}this._=this.A-b;if(!C(this)){break b}}}this._=this.A-m;h=true;a:while(h===true){h=false;if(!y(this)){break a}}n=this._=this.D;j=n;i=true;a:while(i===true){i=false;if(!F(this)){break a}}this._=j;return true};b.prototype.stem=b.prototype.J;b.prototype.N=function(a){return a instanceof b};b.prototype.equals=b.prototype.N;b.prototype.O=function(){var c;var a;var b;var d;c='SpanishStemmer';a=0;for(b=0;b<c.length;b++){d=c.charCodeAt(b);a=(a<<5)-a+d;a=a&a}return a|0};b.prototype.hashCode=b.prototype.O;b.serialVersionUID=1;g(b,'methodObject',function(){return new b});g(b,'a_0',function(){return[new a('',-1,6),new a('á',0,1),new a('é',0,2),new a('í',0,3),new a('ó',0,4),new a('ú',0,5)]});g(b,'a_1',function(){return[new a('la',-1,-1),new a('sela',0,-1),new a('le',-1,-1),new a('me',-1,-1),new a('se',-1,-1),new a('lo',-1,-1),new a('selo',5,-1),new a('las',-1,-1),new a('selas',7,-1),new a('les',-1,-1),new a('los',-1,-1),new a('selos',10,-1),new a('nos',-1,-1)]});g(b,'a_2',function(){return[new a('ando',-1,6),new a('iendo',-1,6),new a('yendo',-1,7),new a('ándo',-1,2),new a('iéndo',-1,1),new a('ar',-1,6),new a('er',-1,6),new a('ir',-1,6),new a('ár',-1,3),new a('ér',-1,4),new a('ír',-1,5)]});g(b,'a_3',function(){return[new a('ic',-1,-1),new a('ad',-1,-1),new a('os',-1,-1),new a('iv',-1,1)]});g(b,'a_4',function(){return[new a('able',-1,1),new a('ible',-1,1),new a('ante',-1,1)]});g(b,'a_5',function(){return[new a('ic',-1,1),new a('abil',-1,1),new a('iv',-1,1)]});g(b,'a_6',function(){return[new a('ica',-1,1),new a('ancia',-1,2),new a('encia',-1,5),new a('adora',-1,2),new a('osa',-1,1),new a('ista',-1,1),new a('iva',-1,9),new a('anza',-1,1),new a('logía',-1,3),new a('idad',-1,8),new a('able',-1,1),new a('ible',-1,1),new a('ante',-1,2),new a('mente',-1,7),new a('amente',13,6),new a('ación',-1,2),new a('ución',-1,4),new a('ico',-1,1),new a('ismo',-1,1),new a('oso',-1,1),new a('amiento',-1,1),new a('imiento',-1,1),new a('ivo',-1,9),new a('ador',-1,2),new a('icas',-1,1),new a('ancias',-1,2),new a('encias',-1,5),new a('adoras',-1,2),new a('osas',-1,1),new a('istas',-1,1),new a('ivas',-1,9),new a('anzas',-1,1),new a('logías',-1,3),new a('idades',-1,8),new a('ables',-1,1),new a('ibles',-1,1),new a('aciones',-1,2),new a('uciones',-1,4),new a('adores',-1,2),new a('antes',-1,2),new a('icos',-1,1),new a('ismos',-1,1),new a('osos',-1,1),new a('amientos',-1,1),new a('imientos',-1,1),new a('ivos',-1,9)]});g(b,'a_7',function(){return[new a('ya',-1,1),new a('ye',-1,1),new a('yan',-1,1),new a('yen',-1,1),new a('yeron',-1,1),new a('yendo',-1,1),new a('yo',-1,1),new a('yas',-1,1),new a('yes',-1,1),new a('yais',-1,1),new a('yamos',-1,1),new a('yó',-1,1)]});g(b,'a_8',function(){return[new a('aba',-1,2),new a('ada',-1,2),new a('ida',-1,2),new a('ara',-1,2),new a('iera',-1,2),new a('ía',-1,2),new a('aría',5,2),new a('ería',5,2),new a('iría',5,2),new a('ad',-1,2),new a('ed',-1,2),new a('id',-1,2),new a('ase',-1,2),new a('iese',-1,2),new a('aste',-1,2),new a('iste',-1,2),new a('an',-1,2),new a('aban',16,2),new a('aran',16,2),new a('ieran',16,2),new a('ían',16,2),new a('arían',20,2),new a('erían',20,2),new a('irían',20,2),new a('en',-1,1),new a('asen',24,2),new a('iesen',24,2),new a('aron',-1,2),new a('ieron',-1,2),new a('arán',-1,2),new a('erán',-1,2),new a('irán',-1,2),new a('ado',-1,2),new a('ido',-1,2),new a('ando',-1,2),new a('iendo',-1,2),new a('ar',-1,2),new a('er',-1,2),new a('ir',-1,2),new a('as',-1,2),new a('abas',39,2),new a('adas',39,2),new a('idas',39,2),new a('aras',39,2),new a('ieras',39,2),new a('ías',39,2),new a('arías',45,2),new a('erías',45,2),new a('irías',45,2),new a('es',-1,1),new a('ases',49,2),new a('ieses',49,2),new a('abais',-1,2),new a('arais',-1,2),new a('ierais',-1,2),new a('íais',-1,2),new a('aríais',55,2),new a('eríais',55,2),new a('iríais',55,2),new a('aseis',-1,2),new a('ieseis',-1,2),new a('asteis',-1,2),new a('isteis',-1,2),new a('áis',-1,2),new a('éis',-1,1),new a('aréis',64,2),new a('eréis',64,2),new a('iréis',64,2),new a('ados',-1,2),new a('idos',-1,2),new a('amos',-1,2),new a('ábamos',70,2),new a('áramos',70,2),new a('iéramos',70,2),new a('íamos',70,2),new a('aríamos',74,2),new a('eríamos',74,2),new a('iríamos',74,2),new a('emos',-1,1),new a('aremos',78,2),new a('eremos',78,2),new a('iremos',78,2),new a('ásemos',78,2),new a('iésemos',78,2),new a('imos',-1,2),new a('arás',-1,2),new a('erás',-1,2),new a('irás',-1,2),new a('ís',-1,2),new a('ará',-1,2),new a('erá',-1,2),new a('irá',-1,2),new a('aré',-1,2),new a('eré',-1,2),new a('iré',-1,2),new a('ió',-1,2)]});g(b,'a_9',function(){return[new a('a',-1,1),new a('e',-1,2),new a('o',-1,1),new a('os',-1,1),new a('á',-1,1),new a('é',-1,2),new a('í',-1,1),new a('ó',-1,1)]});g(b,'g_v',function(){return[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,4,10]});var o={'src/stemmer.jsx':{Stemmer:m},'src/spanish-stemmer.jsx':{SpanishStemmer:b}}}(JSX))
+var Stemmer = JSX.require("src/spanish-stemmer.jsx").SpanishStemmer;
+"""
+
+
+class SearchSpanish(SearchLanguage):
+    lang = 'es'
+    language_name = 'Spanish'
+    js_stemmer_code = js_stemmer
+    stopwords = spanish_stopwords
+
+    def init(self, options):
+        self.stemmer = snowballstemmer.stemmer('spanish')
+
+    def stem(self, word):
+        return self.stemmer.stemWord(word)
diff --git a/sphinx/search/fi.py b/sphinx/search/fi.py
new file mode 100644
index 0000000..7350d88
--- /dev/null
+++ b/sphinx/search/fi.py
@@ -0,0 +1,123 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.search.fi
+    ~~~~~~~~~~~~~~~~
+
+    Finnish search language: includes the JS Finnish stemmer.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from sphinx.search import SearchLanguage, parse_stop_word
+
+import snowballstemmer
+
+finnish_stopwords = parse_stop_word(u'''
+| source: http://snowball.tartarus.org/algorithms/finnish/stop.txt
+| forms of BE
+
+olla
+olen
+olet
+on
+olemme
+olette
+ovat
+ole        | negative form
+
+oli
+olisi
+olisit
+olisin
+olisimme
+olisitte
+olisivat
+olit
+olin
+olimme
+olitte
+olivat
+ollut
+olleet
+
+en         | negation
+et
+ei
+emme
+ette
+eivät
+
+|Nom   Gen    Acc    Part   Iness   Elat    Illat  Adess   Ablat   Allat   Ess    Trans
+minä   minun  minut  minua  minussa minusta minuun minulla minulta minulle               | I
+sinä   sinun  sinut  sinua  sinussa sinusta sinuun sinulla sinulta sinulle               | you
+hän    hänen  hänet  häntä  hänessä hänestä häneen hänellä häneltä hänelle               | he she
+me     meidän meidät meitä  meissä  meistä  meihin meillä  meiltä  meille                | we
+te     teidän teidät teitä  teissä  teistä  teihin teillä  teiltä  teille                | you
+he     heidän heidät heitä  heissä  heistä  heihin heillä  heiltä  heille                | they
+
+tämä   tämän         tätä   tässä   tästä   tähän  tällä   tältä   tälle   tänä   täksi  | this
+tuo    tuon          tuota  tuossa  tuosta  tuohon tuolla  tuolta  tuolle  tuona  tuoksi | that
+se     sen           sitä   siinä   siitä   siihen sillä   siltä   sille   sinä   siksi  | it
+nämä   näiden        näitä  näissä  näistä  näihin näillä  näiltä  näille  näinä  näiksi | these
+nuo    noiden        noita  noissa  noista  noihin noilla  noilta  noille  noina  noiksi | those
+ne     niiden        niitä  niissä  niistä  niihin niillä  niiltä  niille  niinä  niiksi | they
+
+kuka   kenen kenet   ketä   kenessä kenestä keneen kenellä keneltä kenelle kenenä keneksi| who
+ketkä  keiden ketkä  keitä  keissä  keistä  keihin keillä  keiltä  keille  keinä  keiksi | (pl)
+mikä   minkä minkä   mitä   missä   mistä   mihin  millä   miltä   mille   minä   miksi  | which what
+mitkä                                                                                    | (pl)
+
+joka   jonka         jota   jossa   josta   johon  jolla   jolta   jolle   jona   joksi  | who which
+jotka  joiden        joita  joissa  joista  joihin joilla  joilta  joille  joina  joiksi | (pl)
+
+| conjunctions
+
+että   | that
+ja     | and
+jos    | if
+koska  | because
+kuin   | than
+mutta  | but
+niin   | so
+sekä   | and
+sillä  | for
+tai    | or
+vaan   | but
+vai    | or
+vaikka | although
+
+
+| prepositions
+
+kanssa  | with
+mukaan  | according to
+noin    | about
+poikki  | across
+yli     | over, across
+
+| other
+
+kun    | when
+niin   | so
+nyt    | now
+itse   | self
+''')
+
+js_stemmer = u"""
+var JSX={};(function(j){function l(b,e){var a=function(){};a.prototype=e.prototype;var c=new a;for(var d in b){b[d].prototype=c}}function M(c,b){for(var a in b.prototype)if(b.prototype.hasOwnProperty(a))c.prototype[a]=b.prototype[a]}function f(a,b,d){function c(a,b,c){delete a[b];a[b]=c;return c}Object.defineProperty(a,b,{get:function(){return c(a,b,d())},set:function(d){c(a,b,d)},enumerable:true,configurable:true})}function N(a,b,c){return a[b]=a[b]/c|0}var s=parseInt;var C=parseFloat;function O(a){return a!==a}var A=isFinite;var z=encodeURIComponent;var y=decodeURIComponent;var x=encodeURI;var v=decodeURI;var u=Object.prototype.toString;var E=Object.prototype.hasOwnProperty;function k(){}j.require=function(b){var a=q[b];return a!==undefined?a:null};j.profilerIsRunning=function(){return k.getResults!=null};j.getProfileResults=function(){return(k.getResults||function(){return{}})()};j.postProfileResults=function(a,b){if(k.postResults==null)throw new Error('profiler has not been turned on');return k.postResults(a,b)};j.resetProfileResults=function(){if(k.resetResults==null)throw new Error('profiler has not been turned on');return k.resetResults()};j.DEBUG=false;function t(){};l([t],Error);function b(a,b,c){this.F=a.length;this.M=a;this.N=b;this.H=c;this.G=null;this.S=null};function m(a,b,c,d,e){this.F=a.length;this.M=a;this.N=b;this.H=c;this.G=d;this.S=e};l([b,m],Object);function p(){};l([p],Object);function g(){var a;var b;var c;this.I={};a=this.E='';b=this._=0;c=this.A=a.length;this.B=0;this.C=b;this.D=c};l([g],p);function w(a,b){a.E=b.E;a._=b._;a.A=b.A;a.B=b.B;a.C=b.C;a.D=b.D};function n(b,d,c,e){var a;if(b._>=b.A){return false}a=b.E.charCodeAt(b._);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._++;return true};g.prototype.L=function(c,b,d){var a;if(this._<=this.B){return false}a=this.E.charCodeAt(this._-1);if(a>d||a<b){return false}a-=b;if((c[a>>>3]&1<<(a&7))===0){return false}this._--;return true};function h(b,d,c,e){var a;if(b._<=b.B){return false}a=b.E.charCodeAt(b._-1);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._--;return true};function o(a,d,c,e){var b;if(a._>=a.A){return false}b=a.E.charCodeAt(a._);if(b>e||b<c){a._++;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._++;return true}return false};function i(a,d,c,e){var b;if(a._<=a.B){return false}b=a.E.charCodeAt(a._-1);if(b>e||b<c){a._--;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._--;return true}return false};g.prototype.K=function(a,c){var b;if(this._-this.B<a){return false}if(this.E.slice((b=this._)-a,b)!==c){return false}this._-=a;return true};function c(a,b,d){var c;if(a._-a.B<b){return false}if(a.E.slice((c=a._)-b,c)!==d){return false}a._-=b;return true};g.prototype.Q=function(l,o){var b;var d;var e;var m;var f;var j;var k;var h;var g;var c;var a;var i;var n;b=0;d=o;e=this._;m=this.B;f=0;j=0;k=false;while(true){h=b+(d-b>>1);g=0;c=f<j?f:j;a=l[h];for(i=a.F-1-c;i>=0;i--){if(e-c===m){g=-1;break}g=this.E.charCodeAt(e-1-c)-a.M.charCodeAt(i);if(g!==0){break}c++}if(g<0){d=h;j=c}else{b=h;f=c}if(d-b<=1){if(b>0){break}if(d===b){break}if(k){break}k=true}}while(true){a=l[b];if(f>=a.F){this._=e-a.F|0;if(a.G==null){return a.H}n=a.G(this);this._=e-a.F|0;if(n){return a.H}}b=a.N;if(b<0){return 0}}return-1};function e(d,m,p){var b;var g;var e;var n;var f;var k;var l;var i;var h;var c;var a;var j;var o;b=0;g=p;e=d._;n=d.B;f=0;k=0;l=false;while(true){i=b+(g-b>>1);h=0;c=f<k?f:k;a=m[i];for(j=a.F-1-c;j>=0;j--){if(e-c===n){h=-1;break}h=d.E.charCodeAt(e-1-c)-a.M.charCodeAt(j);if(h!==0){break}c++}if(h<0){g=i;k=c}else{b=i;f=c}if(g-b<=1){if(b>0){break}if(g===b){break}if(l){break}l=true}}while(true){a=m[b];if(f>=a.F){d._=e-a.F|0;if(a.G==null){return a.H}o=a.G(d);d._=e-a.F|0;if(o){return a.H}}b=a.N;if(b<0){return 0}}return-1};function D(a,b,d,e){var c;c=e.length-(d-b);a.E=a.E.slice(0,b)+e+a.E.slice(d);a.A+=c|0;if(a._>=d){a._+=c|0}else if(a._>b){a._=b}return c|0};function d(a,f){var b;var c;var d;var e;b=false;if((c=a.C)<0||c>(d=a.D)||d>(e=a.A)||e>a.E.length?false:true){D(a,a.C,a.D,f);b=true}return b};function r(a,f){var b;var c;var d;var e;b='';if((c=a.C)<0||c>(d=a.D)||d>(e=a.A)||e>a.E.length?false:true){b=a.E.slice(a.C,a.D)}return b};g.prototype.J=function(){return false};g.prototype.e=function(b){var a;var c;var d;var e;a=this.I['.'+b];if(a==null){c=this.E=b;d=this._=0;e=this.A=c.length;this.B=0;this.C=d;this.D=e;this.J();a=this.E;this.I['.'+b]=a}return a};g.prototype.stemWord=g.prototype.e;g.prototype.f=function(e){var d;var b;var c;var a;var f;var g;var h;d=[];for(b=0;b<e.length;b++){c=e[b];a=this.I['.'+c];if(a==null){f=this.E=c;g=this._=0;h=this.A=f.length;this.B=0;this.C=g;this.D=h;this.J();a=this.E;this.I['.'+c]=a}d.push(a)}return d};g.prototype.stemWords=g.prototype.f;function a(){g.call(this);this.B_ending_removed=false;this.S_x='';this.I_p2=0;this.I_p1=0};l([a],g);a.prototype.O=function(a){this.B_ending_removed=a.B_ending_removed;this.S_x=a.S_x;this.I_p2=a.I_p2;this.I_p1=a.I_p1;w(this,a)};a.prototype.copy_from=a.prototype.O;a.prototype.Y=function(){var b;var c;var d;var e;var f;var g;var h;var i;var j;this.I_p1=i=this.A;this.I_p2=i;a:while(true){b=this._;d=true;b:while(d===true){d=false;if(!n(this,a.g_V1,97,246)){break b}this._=b;break a}h=this._=b;if(h>=this.A){return false}this._++}a:while(true){e=true;b:while(e===true){e=false;if(!o(this,a.g_V1,97,246)){break b}break a}if(this._>=this.A){return false}this._++}this.I_p1=this._;a:while(true){c=this._;f=true;b:while(f===true){f=false;if(!n(this,a.g_V1,97,246)){break b}this._=c;break a}j=this._=c;if(j>=this.A){return false}this._++}a:while(true){g=true;b:while(g===true){g=false;if(!o(this,a.g_V1,97,246)){break b}break a}if(this._>=this.A){return false}this._++}this.I_p2=this._;return true};a.prototype.r_mark_regions=a.prototype.Y;function H(b){var d;var e;var f;var c;var g;var h;var j;var k;var i;b.I_p1=k=b.A;b.I_p2=k;a:while(true){d=b._;f=true;b:while(f===true){f=false;if(!n(b,a.g_V1,97,246)){break b}b._=d;break a}j=b._=d;if(j>=b.A){return false}b._++}a:while(true){c=true;b:while(c===true){c=false;if(!o(b,a.g_V1,97,246)){break b}break a}if(b._>=b.A){return false}b._++}b.I_p1=b._;a:while(true){e=b._;g=true;b:while(g===true){g=false;if(!n(b,a.g_V1,97,246)){break b}b._=e;break a}i=b._=e;if(i>=b.A){return false}b._++}a:while(true){h=true;b:while(h===true){h=false;if(!o(b,a.g_V1,97,246)){break b}break a}if(b._>=b.A){return false}b._++}b.I_p2=b._;return true};a.prototype.U=function(){return!(this.I_p2<=this._)?false:true};a.prototype.r_R2=a.prototype.U;a.prototype.a=function(){var b;var f;var c;var g;var i;var j;f=this.A-(g=this._);if(g<this.I_p1){return false}i=this._=this.I_p1;c=this.B;this.B=i;j=this._=this.A-f;this.D=j;b=e(this,a.a_0,10);if(b===0){this.B=c;return false}this.C=this._;this.B=c;switch(b){case 0:return false;case 1:if(!h(this,a.g_particle_end,97,246)){return false}break;case 2:if(!(!(this.I_p2<=this._)?false:true)){return false}break}return!d(this,'')?false:true};a.prototype.r_particle_etc=a.prototype.a;function I(b){var c;var g;var f;var i;var j;var k;g=b.A-(i=b._);if(i<b.I_p1){return false}j=b._=b.I_p1;f=b.B;b.B=j;k=b._=b.A-g;b.D=k;c=e(b,a.a_0,10);if(c===0){b.B=f;return false}b.C=b._;b.B=f;switch(c){case 0:return false;case 1:if(!h(b,a.g_particle_end,97,246)){return false}break;case 2:if(!(!(b.I_p2<=b._)?false:true)){return false}break}return!d(b,'')?false:true};a.prototype.b=function(){var b;var h;var f;var i;var g;var j;var k;var l;h=this.A-(j=this._);if(j<this.I_p1){return false}k=this._=this.I_p1;f=this.B;this.B=k;l=this._=this.A-h;this.D=l;b=e(this,a.a_4,9);if(b===0){this.B=f;return false}this.C=this._;this.B=f;switch(b){case 0:return false;case 1:i=this.A-this._;g=true;a:while(g===true){g=false;if(!c(this,1,'k')){break a}return false}this._=this.A-i;if(!d(this,'')){return false}break;case 2:if(!d(this,'')){return false}this.D=this._;if(!c(this,3,'kse')){return false}this.C=this._;if(!d(this,'ksi')){return false}break;case 3:if(!d(this,'')){return false}break;case 4:if(e(this,a.a_1,6)===0){return false}if(!d(this,'')){return false}break;case 5:if(e(this,a.a_2,6)===0){return false}if(!d(this,'')){return false}break;case 6:if(e(this,a.a_3,2)===0){return false}if(!d(this,'')){return false}break}return true};a.prototype.r_possessive=a.prototype.b;function J(b){var f;var i;var g;var j;var h;var k;var l;var m;i=b.A-(k=b._);if(k<b.I_p1){return false}l=b._=b.I_p1;g=b.B;b.B=l;m=b._=b.A-i;b.D=m;f=e(b,a.a_4,9);if(f===0){b.B=g;return false}b.C=b._;b.B=g;switch(f){case 0:return false;case 1:j=b.A-b._;h=true;a:while(h===true){h=false;if(!c(b,1,'k')){break a}return false}b._=b.A-j;if(!d(b,'')){return false}break;case 2:if(!d(b,'')){return false}b.D=b._;if(!c(b,3,'kse')){return false}b.C=b._;if(!d(b,'ksi')){return false}break;case 3:if(!d(b,'')){return false}break;case 4:if(e(b,a.a_1,6)===0){return false}if(!d(b,'')){return false}break;case 5:if(e(b,a.a_2,6)===0){return false}if(!d(b,'')){return false}break;case 6:if(e(b,a.a_3,2)===0){return false}if(!d(b,'')){return false}break}return true};a.prototype.T=function(){return e(this,a.a_5,7)===0?false:true};a.prototype.r_LONG=a.prototype.T;a.prototype.V=function(){return!c(this,1,'i')?false:!h(this,a.g_V2,97,246)?false:true};a.prototype.r_VI=a.prototype.V;a.prototype.W=function(){var j;var o;var f;var g;var p;var m;var b;var k;var l;var q;var r;var s;var n;o=this.A-(q=this._);if(q<this.I_p1){return false}r=this._=this.I_p1;f=this.B;this.B=r;s=this._=this.A-o;this.D=s;j=e(this,a.a_6,30);if(j===0){this.B=f;return false}this.C=this._;this.B=f;switch(j){case 0:return false;case 1:if(!c(this,1,'a')){return false}break;case 2:if(!c(this,1,'e')){return false}break;case 3:if(!c(this,1,'i')){return false}break;case 4:if(!c(this,1,'o')){return false}break;case 5:if(!c(this,1,'ä')){return false}break;case 6:if(!c(this,1,'ö')){return false}break;case 7:g=this.A-this._;b=true;a:while(b===true){b=false;p=this.A-this._;k=true;b:while(k===true){k=false;m=this.A-this._;l=true;c:while(l===true){l=false;if(!(e(this,a.a_5,7)===0?false:true)){break c}break b}this._=this.A-m;if(!c(this,2,'ie')){this._=this.A-g;break a}}n=this._=this.A-p;if(n<=this.B){this._=this.A-g;break a}this._--;this.C=this._}break;case 8:if(!h(this,a.g_V1,97,246)){return false}if(!i(this,a.g_V1,97,246)){return false}break;case 9:if(!c(this,1,'e')){return false}break}if(!d(this,'')){return false}this.B_ending_removed=true;return true};a.prototype.r_case_ending=a.prototype.W;function K(b){var f;var o;var g;var j;var p;var n;var k;var l;var m;var r;var s;var t;var q;o=b.A-(r=b._);if(r<b.I_p1){return false}s=b._=b.I_p1;g=b.B;b.B=s;t=b._=b.A-o;b.D=t;f=e(b,a.a_6,30);if(f===0){b.B=g;return false}b.C=b._;b.B=g;switch(f){case 0:return false;case 1:if(!c(b,1,'a')){return false}break;case 2:if(!c(b,1,'e')){return false}break;case 3:if(!c(b,1,'i')){return false}break;case 4:if(!c(b,1,'o')){return false}break;case 5:if(!c(b,1,'ä')){return false}break;case 6:if(!c(b,1,'ö')){return false}break;case 7:j=b.A-b._;k=true;a:while(k===true){k=false;p=b.A-b._;l=true;b:while(l===true){l=false;n=b.A-b._;m=true;c:while(m===true){m=false;if(!(e(b,a.a_5,7)===0?false:true)){break c}break b}b._=b.A-n;if(!c(b,2,'ie')){b._=b.A-j;break a}}q=b._=b.A-p;if(q<=b.B){b._=b.A-j;break a}b._--;b.C=b._}break;case 8:if(!h(b,a.g_V1,97,246)){return false}if(!i(b,a.g_V1,97,246)){return false}break;case 9:if(!c(b,1,'e')){return false}break}if(!d(b,'')){return false}b.B_ending_removed=true;return true};a.prototype.Z=function(){var b;var h;var f;var i;var g;var j;var k;var l;h=this.A-(j=this._);if(j<this.I_p2){return false}k=this._=this.I_p2;f=this.B;this.B=k;l=this._=this.A-h;this.D=l;b=e(this,a.a_7,14);if(b===0){this.B=f;return false}this.C=this._;this.B=f;switch(b){case 0:return false;case 1:i=this.A-this._;g=true;a:while(g===true){g=false;if(!c(this,2,'po')){break a}return false}this._=this.A-i;break}return!d(this,'')?false:true};a.prototype.r_other_endings=a.prototype.Z;function L(b){var f;var i;var g;var j;var h;var k;var l;var m;i=b.A-(k=b._);if(k<b.I_p2){return false}l=b._=b.I_p2;g=b.B;b.B=l;m=b._=b.A-i;b.D=m;f=e(b,a.a_7,14);if(f===0){b.B=g;return false}b.C=b._;b.B=g;switch(f){case 0:return false;case 1:j=b.A-b._;h=true;a:while(h===true){h=false;if(!c(b,2,'po')){break a}return false}b._=b.A-j;break}return!d(b,'')?false:true};a.prototype.X=function(){var c;var b;var f;var g;var h;c=this.A-(f=this._);if(f<this.I_p1){return false}g=this._=this.I_p1;b=this.B;this.B=g;h=this._=this.A-c;this.D=h;if(e(this,a.a_8,2)===0){this.B=b;return false}this.C=this._;this.B=b;return!d(this,'')?false:true};a.prototype.r_i_plural=a.prototype.X;function G(b){var f;var c;var g;var h;var i;f=b.A-(g=b._);if(g<b.I_p1){return false}h=b._=b.I_p1;c=b.B;b.B=h;i=b._=b.A-f;b.D=i;if(e(b,a.a_8,2)===0){b.B=c;return false}b.C=b._;b.B=c;return!d(b,'')?false:true};a.prototype.c=function(){var i;var l;var b;var j;var k;var g;var m;var f;var o;var p;var q;var r;var s;var t;var n;l=this.A-(o=this._);if(o<this.I_p1){return false}p=this._=this.I_p1;b=this.B;this.B=p;q=this._=this.A-l;this.D=q;if(!c(this,1,'t')){this.B=b;return false}this.C=r=this._;j=this.A-r;if(!h(this,a.g_V1,97,246)){this.B=b;return false}this._=this.A-j;if(!d(this,'')){return false}this.B=b;k=this.A-(s=this._);if(s<this.I_p2){return false}t=this._=this.I_p2;g=this.B;this.B=t;n=this._=this.A-k;this.D=n;i=e(this,a.a_9,2);if(i===0){this.B=g;return false}this.C=this._;this.B=g;switch(i){case 0:return false;case 1:m=this.A-this._;f=true;a:while(f===true){f=false;if(!c(this,2,'po')){break a}return false}this._=this.A-m;break}return!d(this,'')?false:true};a.prototype.r_t_plural=a.prototype.c;function F(b){var g;var m;var f;var o;var l;var i;var k;var j;var p;var q;var r;var s;var t;var u;var n;m=b.A-(p=b._);if(p<b.I_p1){return false}q=b._=b.I_p1;f=b.B;b.B=q;r=b._=b.A-m;b.D=r;if(!c(b,1,'t')){b.B=f;return false}b.C=s=b._;o=b.A-s;if(!h(b,a.g_V1,97,246)){b.B=f;return false}b._=b.A-o;if(!d(b,'')){return false}b.B=f;l=b.A-(t=b._);if(t<b.I_p2){return false}u=b._=b.I_p2;i=b.B;b.B=u;n=b._=b.A-l;b.D=n;g=e(b,a.a_9,2);if(g===0){b.B=i;return false}b.C=b._;b.B=i;switch(g){case 0:return false;case 1:k=b.A-b._;j=true;a:while(j===true){j=false;if(!c(b,2,'po')){break a}return false}b._=b.A-k;break}return!d(b,'')?false:true};a.prototype.d=function(){var x;var q;var s;var t;var u;var v;var w;var y;var f;var g;var j;var k;var l;var m;var n;var b;var o;var z;var p;var B;var C;var D;var E;var F;var G;var H;var I;var J;var K;var L;var A;x=this.A-(z=this._);if(z<this.I_p1){return false}B=this._=this.I_p1;q=this.B;this.B=B;D=this._=(C=this.A)-x;s=C-D;g=true;a:while(g===true){g=false;t=this.A-this._;if(!(e(this,a.a_5,7)===0?false:true)){break a}p=this._=this.A-t;this.D=p;if(p<=this.B){break a}this._--;this.C=this._;if(!d(this,'')){return false}}F=this._=(E=this.A)-s;u=E-F;j=true;a:while(j===true){j=false;this.D=this._;if(!h(this,a.g_AEI,97,228)){break a}this.C=this._;if(!i(this,a.g_V1,97,246)){break a}if(!d(this,'')){return false}}H=this._=(G=this.A)-u;v=G-H;k=true;a:while(k===true){k=false;this.D=this._;if(!c(this,1,'j')){break a}this.C=this._;l=true;b:while(l===true){l=false;w=this.A-this._;m=true;c:while(m===true){m=false;if(!c(this,1,'o')){break c}break b}this._=this.A-w;if(!c(this,1,'u')){break a}}if(!d(this,'')){return false}}J=this._=(I=this.A)-v;y=I-J;n=true;a:while(n===true){n=false;this.D=this._;if(!c(this,1,'o')){break a}this.C=this._;if(!c(this,1,'j')){break a}if(!d(this,'')){return false}}this._=this.A-y;this.B=q;a:while(true){f=this.A-this._;b=true;b:while(b===true){b=false;if(!i(this,a.g_V1,97,246)){break b}this._=this.A-f;break a}K=this._=this.A-f;if(K<=this.B){return false}this._--}this.D=L=this._;if(L<=this.B){return false}this._--;this.C=this._;A=this.S_x=r(this,this.S_x);return A===''?false:!(o=this.S_x,c(this,o.length,o))?false:!d(this,'')?false:true};a.prototype.r_tidy=a.prototype.d;function B(b){var s;var t;var u;var v;var w;var x;var y;var z;var l;var g;var j;var k;var f;var m;var n;var o;var p;var A;var q;var C;var D;var E;var F;var G;var H;var I;var J;var K;var L;var M;var B;s=b.A-(A=b._);if(A<b.I_p1){return false}C=b._=b.I_p1;t=b.B;b.B=C;E=b._=(D=b.A)-s;u=D-E;g=true;a:while(g===true){g=false;v=b.A-b._;if(!(e(b,a.a_5,7)===0?false:true)){break a}q=b._=b.A-v;b.D=q;if(q<=b.B){break a}b._--;b.C=b._;if(!d(b,'')){return false}}G=b._=(F=b.A)-u;w=F-G;j=true;a:while(j===true){j=false;b.D=b._;if(!h(b,a.g_AEI,97,228)){break a}b.C=b._;if(!i(b,a.g_V1,97,246)){break a}if(!d(b,'')){return false}}I=b._=(H=b.A)-w;x=H-I;k=true;a:while(k===true){k=false;b.D=b._;if(!c(b,1,'j')){break a}b.C=b._;f=true;b:while(f===true){f=false;y=b.A-b._;m=true;c:while(m===true){m=false;if(!c(b,1,'o')){break c}break b}b._=b.A-y;if(!c(b,1,'u')){break a}}if(!d(b,'')){return false}}K=b._=(J=b.A)-x;z=J-K;n=true;a:while(n===true){n=false;b.D=b._;if(!c(b,1,'o')){break a}b.C=b._;if(!c(b,1,'j')){break a}if(!d(b,'')){return false}}b._=b.A-z;b.B=t;a:while(true){l=b.A-b._;o=true;b:while(o===true){o=false;if(!i(b,a.g_V1,97,246)){break b}b._=b.A-l;break a}L=b._=b.A-l;if(L<=b.B){return false}b._--}b.D=M=b._;if(M<=b.B){return false}b._--;b.C=b._;B=b.S_x=r(b,b.S_x);return B===''?false:!(p=b.S_x,c(b,p.length,p))?false:!d(b,'')?false:true};a.prototype.J=function(){var p;var k;var l;var m;var n;var o;var q;var r;var b;var c;var d;var e;var f;var g;var a;var h;var i;var j;var t;var u;var v;var w;var x;var y;var z;var A;var C;var D;var s;p=this._;b=true;a:while(b===true){b=false;if(!H(this)){break a}}t=this._=p;this.B_ending_removed=false;this.B=t;v=this._=u=this.A;k=u-v;c=true;a:while(c===true){c=false;if(!I(this)){break a}}x=this._=(w=this.A)-k;l=w-x;d=true;a:while(d===true){d=false;if(!J(this)){break a}}z=this._=(y=this.A)-l;m=y-z;e=true;a:while(e===true){e=false;if(!K(this)){break a}}C=this._=(A=this.A)-m;n=A-C;f=true;a:while(f===true){f=false;if(!L(this)){break a}}this._=this.A-n;g=true;a:while(g===true){g=false;o=this.A-this._;a=true;b:while(a===true){a=false;if(!this.B_ending_removed){break b}q=this.A-this._;h=true;c:while(h===true){h=false;if(!G(this)){break c}}this._=this.A-q;break a}s=this._=(D=this.A)-o;r=D-s;i=true;b:while(i===true){i=false;if(!F(this)){break b}}this._=this.A-r}j=true;a:while(j===true){j=false;if(!B(this)){break a}}this._=this.B;return true};a.prototype.stem=a.prototype.J;a.prototype.P=function(b){return b instanceof a};a.prototype.equals=a.prototype.P;a.prototype.R=function(){var c;var a;var b;var d;c='FinnishStemmer';a=0;for(b=0;b<c.length;b++){d=c.charCodeAt(b);a=(a<<5)-a+d;a=a&a}return a|0};a.prototype.hashCode=a.prototype.R;a.serialVersionUID=1;f(a,'methodObject',function(){return new a});f(a,'a_0',function(){return[new b('pa',-1,1),new b('sti',-1,2),new b('kaan',-1,1),new b('han',-1,1),new b('kin',-1,1),new b('hän',-1,1),new b('kään',-1,1),new b('ko',-1,1),new b('pä',-1,1),new b('kö',-1,1)]});f(a,'a_1',function(){return[new b('lla',-1,-1),new b('na',-1,-1),new b('ssa',-1,-1),new b('ta',-1,-1),new b('lta',3,-1),new b('sta',3,-1)]});f(a,'a_2',function(){return[new b('llä',-1,-1),new b('nä',-1,-1),new b('ssä',-1,-1),new b('tä',-1,-1),new b('ltä',3,-1),new b('stä',3,-1)]});f(a,'a_3',function(){return[new b('lle',-1,-1),new b('ine',-1,-1)]});f(a,'a_4',function(){return[new b('nsa',-1,3),new b('mme',-1,3),new b('nne',-1,3),new b('ni',-1,2),new b('si',-1,1),new b('an',-1,4),new b('en',-1,6),new b('än',-1,5),new b('nsä',-1,3)]});f(a,'a_5',function(){return[new b('aa',-1,-1),new b('ee',-1,-1),new b('ii',-1,-1),new b('oo',-1,-1),new b('uu',-1,-1),new b('ää',-1,-1),new b('öö',-1,-1)]});f(a,'a_6',function(){return[new b('a',-1,8),new b('lla',0,-1),new b('na',0,-1),new b('ssa',0,-1),new b('ta',0,-1),new b('lta',4,-1),new b('sta',4,-1),new b('tta',4,9),new b('lle',-1,-1),new b('ine',-1,-1),new b('ksi',-1,-1),new b('n',-1,7),new b('han',11,1),new m('den',11,-1,function(c){var b;b=c;return!b.K(1,'i')?false:!b.L(a.g_V2,97,246)?false:true},a.methodObject),new m('seen',11,-1,function(c){var b;b=c;return b.Q(a.a_5,7)===0?false:true},a.methodObject),new b('hen',11,2),new m('tten',11,-1,function(c){var b;b=c;return!b.K(1,'i')?false:!b.L(a.g_V2,97,246)?false:true},a.methodObject),new b('hin',11,3),new m('siin',11,-1,function(c){var b;b=c;return!b.K(1,'i')?false:!b.L(a.g_V2,97,246)?false:true},a.methodObject),new b('hon',11,4),new b('hän',11,5),new b('hön',11,6),new b('ä',-1,8),new b('llä',22,-1),new b('nä',22,-1),new b('ssä',22,-1),new b('tä',22,-1),new b('ltä',26,-1),new b('stä',26,-1),new b('ttä',26,9)]});f(a,'a_7',function(){return[new b('eja',-1,-1),new b('mma',-1,1),new b('imma',1,-1),new b('mpa',-1,1),new b('impa',3,-1),new b('mmi',-1,1),new b('immi',5,-1),new b('mpi',-1,1),new b('impi',7,-1),new b('ejä',-1,-1),new b('mmä',-1,1),new b('immä',10,-1),new b('mpä',-1,1),new b('impä',12,-1)]});f(a,'a_8',function(){return[new b('i',-1,-1),new b('j',-1,-1)]});f(a,'a_9',function(){return[new b('mma',-1,1),new b('imma',0,-1)]});f(a,'g_AEI',function(){return[17,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8]});f(a,'g_V1',function(){return[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32]});f(a,'g_V2',function(){return[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32]});f(a,'g_particle_end',function(){return[17,97,24,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32]});var q={'src/stemmer.jsx':{Stemmer:p},'src/finnish-stemmer.jsx':{FinnishStemmer:a}}}(JSX))
+var Stemmer = JSX.require("src/finnish-stemmer.jsx").FinnishStemmer;
+"""
+
+
+class SearchFinnish(SearchLanguage):
+    lang = 'fi'
+    language_name = 'Finnish'
+    js_stemmer_code = js_stemmer
+    stopwords = finnish_stopwords
+
+    def init(self, options):
+        self.stemmer = snowballstemmer.stemmer('finnish')
+
+    def stem(self, word):
+        return self.stemmer.stemWord(word)
diff --git a/sphinx/search/fr.py b/sphinx/search/fr.py
new file mode 100644
index 0000000..9ae6133
--- /dev/null
+++ b/sphinx/search/fr.py
@@ -0,0 +1,209 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.search.fr
+    ~~~~~~~~~~~~~~~~
+
+    French search language: includes the JS French stemmer.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from sphinx.search import SearchLanguage, parse_stop_word
+
+import snowballstemmer
+
+french_stopwords = parse_stop_word(u'''
+| source: http://snowball.tartarus.org/algorithms/french/stop.txt
+au             |  a + le
+aux            |  a + les
+avec           |  with
+ce             |  this
+ces            |  these
+dans           |  with
+de             |  of
+des            |  de + les
+du             |  de + le
+elle           |  she
+en             |  `of them' etc
+et             |  and
+eux            |  them
+il             |  he
+je             |  I
+la             |  the
+le             |  the
+leur           |  their
+lui            |  him
+ma             |  my (fem)
+mais           |  but
+me             |  me
+même           |  same; as in moi-même (myself) etc
+mes            |  me (pl)
+moi            |  me
+mon            |  my (masc)
+ne             |  not
+nos            |  our (pl)
+notre          |  our
+nous           |  we
+on             |  one
+ou             |  where
+par            |  by
+pas            |  not
+pour           |  for
+qu             |  que before vowel
+que            |  that
+qui            |  who
+sa             |  his, her (fem)
+se             |  oneself
+ses            |  his (pl)
+son            |  his, her (masc)
+sur            |  on
+ta             |  thy (fem)
+te             |  thee
+tes            |  thy (pl)
+toi            |  thee
+ton            |  thy (masc)
+tu             |  thou
+un             |  a
+une            |  a
+vos            |  your (pl)
+votre          |  your
+vous           |  you
+
+               |  single letter forms
+
+c              |  c'
+d              |  d'
+j              |  j'
+l              |  l'
+à              |  to, at
+m              |  m'
+n              |  n'
+s              |  s'
+t              |  t'
+y              |  there
+
+               | forms of être (not including the infinitive):
+été
+étée
+étées
+étés
+étant
+suis
+es
+est
+sommes
+êtes
+sont
+serai
+seras
+sera
+serons
+serez
+seront
+serais
+serait
+serions
+seriez
+seraient
+étais
+était
+étions
+étiez
+étaient
+fus
+fut
+fûmes
+fûtes
+furent
+sois
+soit
+soyons
+soyez
+soient
+fusse
+fusses
+fût
+fussions
+fussiez
+fussent
+
+               | forms of avoir (not including the infinitive):
+ayant
+eu
+eue
+eues
+eus
+ai
+as
+avons
+avez
+ont
+aurai
+auras
+aura
+aurons
+aurez
+auront
+aurais
+aurait
+aurions
+auriez
+auraient
+avais
+avait
+avions
+aviez
+avaient
+eut
+eûmes
+eûtes
+eurent
+aie
+aies
+ait
+ayons
+ayez
+aient
+eusse
+eusses
+eût
+eussions
+eussiez
+eussent
+
+               | Later additions (from Jean-Christophe Deschamps)
+ceci           |  this
+cela           |  that (added 11 Apr 2012. Omission reported by Adrien Grand)
+celà           |  that (incorrect, though common)
+cet            |  this
+cette          |  this
+ici            |  here
+ils            |  they
+les            |  the (pl)
+leurs          |  their (pl)
+quel           |  which
+quels          |  which
+quelle         |  which
+quelles        |  which
+sans           |  without
+soi            |  oneself
+''')
+
+js_stemmer = u"""
+var JSX={};(function(l){function m(b,e){var a=function(){};a.prototype=e.prototype;var c=new a;for(var d in b){b[d].prototype=c}}function P(c,b){for(var a in b.prototype)if(b.prototype.hasOwnProperty(a))c.prototype[a]=b.prototype[a]}function g(a,b,d){function c(a,b,c){delete a[b];a[b]=c;return c}Object.defineProperty(a,b,{get:function(){return c(a,b,d())},set:function(d){c(a,b,d)},enumerable:true,configurable:true})}function O(a,b,c){return a[b]=a[b]/c|0}var u=parseInt;var v=parseFloat;function N(a){return a!==a}var x=isFinite;var y=encodeURIComponent;var z=decodeURIComponent;var A=encodeURI;var B=decodeURI;var C=Object.prototype.toString;var D=Object.prototype.hasOwnProperty;function k(){}l.require=function(b){var a=q[b];return a!==undefined?a:null};l.profilerIsRunning=function(){return k.getResults!=null};l.getProfileResults=function(){return(k.getResults||function(){return{}})()};l.postProfileResults=function(a,b){if(k.postResults==null)throw new Error('profiler has not been turned on');return k.postResults(a,b)};l.resetProfileResults=function(){if(k.resetResults==null)throw new Error('profiler has not been turned on');return k.resetResults()};l.DEBUG=false;function G(){};m([G],Error);function a(a,b,c){this.F=a.length;this.K=a;this.L=b;this.I=c;this.H=null;this.P=null};m([a],Object);function p(){};m([p],Object);function i(){var a;var b;var c;this.G={};a=this.E='';b=this._=0;c=this.A=a.length;this.B=0;this.D=b;this.C=c};m([i],p);function s(a,b){a.E=b.E;a._=b._;a.A=b.A;a.B=b.B;a.D=b.D;a.C=b.C};function e(b,d,c,e){var a;if(b._>=b.A){return false}a=b.E.charCodeAt(b._);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._++;return true};function r(b,d,c,e){var a;if(b._<=b.B){return false}a=b.E.charCodeAt(b._-1);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._--;return true};function o(a,d,c,e){var b;if(a._>=a.A){return false}b=a.E.charCodeAt(a._);if(b>e||b<c){a._++;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._++;return true}return false};function j(a,d,c,e){var b;if(a._<=a.B){return false}b=a.E.charCodeAt(a._-1);if(b>e||b<c){a._--;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._--;return true}return false};function h(a,b,d){var c;if(a.A-a._<b){return false}if(a.E.slice(c=a._,c+b)!==d){return false}a._+=b;return true};function d(a,b,d){var c;if(a._-a.B<b){return false}if(a.E.slice((c=a._)-b,c)!==d){return false}a._-=b;return true};function n(f,m,p){var b;var d;var e;var n;var g;var k;var l;var i;var h;var c;var a;var j;var o;b=0;d=p;e=f._;n=f.A;g=0;k=0;l=false;while(true){i=b+(d-b>>>1);h=0;c=g<k?g:k;a=m[i];for(j=c;j<a.F;j++){if(e+c===n){h=-1;break}h=f.E.charCodeAt(e+c)-a.K.charCodeAt(j);if(h!==0){break}c++}if(h<0){d=i;k=c}else{b=i;g=c}if(d-b<=1){if(b>0){break}if(d===b){break}if(l){break}l=true}}while(true){a=m[b];if(g>=a.F){f._=e+a.F|0;if(a.H==null){return a.I}o=a.H(a.P);f._=e+a.F|0;if(o){return a.I}}b=a.L;if(b<0){return 0}}return-1};function f(d,m,p){var b;var g;var e;var n;var f;var k;var l;var i;var h;var c;var a;var j;var o;b=0;g=p;e=d._;n=d.B;f=0;k=0;l=false;while(true){i=b+(g-b>>1);h=0;c=f<k?f:k;a=m[i];for(j=a.F-1-c;j>=0;j--){if(e-c===n){h=-1;break}h=d.E.charCodeAt(e-1-c)-a.K.charCodeAt(j);if(h!==0){break}c++}if(h<0){g=i;k=c}else{b=i;f=c}if(g-b<=1){if(b>0){break}if(g===b){break}if(l){break}l=true}}while(true){a=m[b];if(f>=a.F){d._=e-a.F|0;if(a.H==null){return a.I}o=a.H(d);d._=e-a.F|0;if(o){return a.I}}b=a.L;if(b<0){return 0}}return-1};function E(a,b,d,e){var c;c=e.length-(d-b);a.E=a.E.slice(0,b)+e+a.E.slice(d);a.A+=c|0;if(a._>=d){a._+=c|0}else if(a._>b){a._=b}return c|0};function c(a,f){var b;var c;var d;var e;b=false;if((c=a.D)<0||c>(d=a.C)||d>(e=a.A)||e>a.E.length?false:true){E(a,a.D,a.C,f);b=true}return b};i.prototype.J=function(){return false};i.prototype.c=function(b){var a;var c;var d;var e;a=this.G['.'+b];if(a==null){c=this.E=b;d=this._=0;e=this.A=c.length;this.B=0;this.D=d;this.C=e;this.J();a=this.E;this.G['.'+b]=a}return a};i.prototype.stemWord=i.prototype.c;i.prototype.d=function(e){var d;var b;var c;var a;var f;var g;var h;d=[];for(b=0;b<e.length;b++){c=e[b];a=this.G['.'+c];if(a==null){f=this.E=c;g=this._=0;h=this.A=f.length;this.B=0;this.D=g;this.C=h;this.J();a=this.E;this.G['.'+c]=a}d.push(a)}return d};i.prototype.stemWords=i.prototype.d;function b(){i.call(this);this.I_p2=0;this.I_p1=0;this.I_pV=0};m([b],i);b.prototype.M=function(a){this.I_p2=a.I_p2;this.I_p1=a.I_p1;this.I_pV=a.I_pV;s(this,a)};b.prototype.copy_from=b.prototype.M;b.prototype.W=function(){var p;var j;var f;var g;var i;var a;var d;var k;var l;var m;var n;var o;var q;a:while(true){p=this._;i=true;g:while(i===true){i=false;h:while(true){j=this._;a=true;b:while(a===true){a=false;d=true;c:while(d===true){d=false;f=this._;k=true;d:while(k===true){k=false;if(!e(this,b.g_v,97,251)){break d}this.D=this._;l=true;e:while(l===true){l=false;g=this._;m=true;f:while(m===true){m=false;if(!h(this,1,'u')){break f}this.C=this._;if(!e(this,b.g_v,97,251)){break f}if(!c(this,'U')){return false}break e}this._=g;n=true;f:while(n===true){n=false;if(!h(this,1,'i')){break f}this.C=this._;if(!e(this,b.g_v,97,251)){break f}if(!c(this,'I')){return false}break e}this._=g;if(!h(this,1,'y')){break d}this.C=this._;if(!c(this,'Y')){return false}}break c}this._=f;o=true;d:while(o===true){o=false;this.D=this._;if(!h(this,1,'y')){break d}this.C=this._;if(!e(this,b.g_v,97,251)){break d}if(!c(this,'Y')){return false}break c}this._=f;if(!h(this,1,'q')){break b}this.D=this._;if(!h(this,1,'u')){break b}this.C=this._;if(!c(this,'U')){return false}}this._=j;break h}q=this._=j;if(q>=this.A){break g}this._++}continue a}this._=p;break a}return true};b.prototype.r_prelude=b.prototype.W;function H(a){var q;var k;var f;var g;var i;var j;var d;var l;var m;var n;var o;var p;var r;a:while(true){q=a._;i=true;g:while(i===true){i=false;h:while(true){k=a._;j=true;b:while(j===true){j=false;d=true;c:while(d===true){d=false;f=a._;l=true;d:while(l===true){l=false;if(!e(a,b.g_v,97,251)){break d}a.D=a._;m=true;e:while(m===true){m=false;g=a._;n=true;f:while(n===true){n=false;if(!h(a,1,'u')){break f}a.C=a._;if(!e(a,b.g_v,97,251)){break f}if(!c(a,'U')){return false}break e}a._=g;o=true;f:while(o===true){o=false;if(!h(a,1,'i')){break f}a.C=a._;if(!e(a,b.g_v,97,251)){break f}if(!c(a,'I')){return false}break e}a._=g;if(!h(a,1,'y')){break d}a.C=a._;if(!c(a,'Y')){return false}}break c}a._=f;p=true;d:while(p===true){p=false;a.D=a._;if(!h(a,1,'y')){break d}a.C=a._;if(!e(a,b.g_v,97,251)){break d}if(!c(a,'Y')){return false}break c}a._=f;if(!h(a,1,'q')){break b}a.D=a._;if(!h(a,1,'u')){break b}a.C=a._;if(!c(a,'U')){return false}}a._=k;break h}r=a._=k;if(r>=a.A){break g}a._++}continue a}a._=q;break a}return true};b.prototype.U=function(){var t;var i;var r;var d;var f;var g;var h;var c;var a;var j;var k;var l;var m;var s;var p;var q;this.I_pV=p=this.A;this.I_p1=p;this.I_p2=p;t=this._;d=true;b:while(d===true){d=false;f=true;c:while(f===true){f=false;i=this._;g=true;a:while(g===true){g=false;if(!e(this,b.g_v,97,251)){break a}if(!e(this,b.g_v,97,251)){break a}if(this._>=this.A){break a}this._++;break c}this._=i;h=true;a:while(h===true){h=false;if(n(this,b.a_0,3)===0){break a}break c}s=this._=i;if(s>=this.A){break b}this._++;a:while(true){c=true;d:while(c===true){c=false;if(!e(this,b.g_v,97,251)){break d}break a}if(this._>=this.A){break b}this._++}}this.I_pV=this._}q=this._=t;r=q;a=true;a:while(a===true){a=false;c:while(true){j=true;b:while(j===true){j=false;if(!e(this,b.g_v,97,251)){break b}break c}if(this._>=this.A){break a}this._++}b:while(true){k=true;c:while(k===true){k=false;if(!o(this,b.g_v,97,251)){break c}break b}if(this._>=this.A){break a}this._++}this.I_p1=this._;b:while(true){l=true;c:while(l===true){l=false;if(!e(this,b.g_v,97,251)){break c}break b}if(this._>=this.A){break a}this._++}c:while(true){m=true;b:while(m===true){m=false;if(!o(this,b.g_v,97,251)){break b}break c}if(this._>=this.A){break a}this._++}this.I_p2=this._}this._=r;return true};b.prototype.r_mark_regions=b.prototype.U;function I(a){var s;var i;var r;var d;var f;var g;var h;var c;var j;var k;var l;var m;var p;var t;var q;var u;a.I_pV=q=a.A;a.I_p1=q;a.I_p2=q;s=a._;d=true;b:while(d===true){d=false;f=true;c:while(f===true){f=false;i=a._;g=true;a:while(g===true){g=false;if(!e(a,b.g_v,97,251)){break a}if(!e(a,b.g_v,97,251)){break a}if(a._>=a.A){break a}a._++;break c}a._=i;h=true;a:while(h===true){h=false;if(n(a,b.a_0,3)===0){break a}break c}t=a._=i;if(t>=a.A){break b}a._++;a:while(true){c=true;d:while(c===true){c=false;if(!e(a,b.g_v,97,251)){break d}break a}if(a._>=a.A){break b}a._++}}a.I_pV=a._}u=a._=s;r=u;j=true;a:while(j===true){j=false;c:while(true){k=true;b:while(k===true){k=false;if(!e(a,b.g_v,97,251)){break b}break c}if(a._>=a.A){break a}a._++}b:while(true){l=true;c:while(l===true){l=false;if(!o(a,b.g_v,97,251)){break c}break b}if(a._>=a.A){break a}a._++}a.I_p1=a._;b:while(true){m=true;c:while(m===true){m=false;if(!e(a,b.g_v,97,251)){break c}break b}if(a._>=a.A){break a}a._++}c:while(true){p=true;b:while(p===true){p=false;if(!o(a,b.g_v,97,251)){break b}break c}if(a._>=a.A){break a}a._++}a.I_p2=a._}a._=r;return true};b.prototype.V=function(){var a;var e;var d;b:while(true){e=this._;d=true;a:while(d===true){d=false;this.D=this._;a=n(this,b.a_1,4);if(a===0){break a}this.C=this._;switch(a){case 0:break a;case 1:if(!c(this,'i')){return false}break;case 2:if(!c(this,'u')){return false}break;case 3:if(!c(this,'y')){return false}break;case 4:if(this._>=this.A){break a}this._++;break}continue b}this._=e;break b}return true};b.prototype.r_postlude=b.prototype.V;function J(a){var d;var f;var e;b:while(true){f=a._;e=true;a:while(e===true){e=false;a.D=a._;d=n(a,b.a_1,4);if(d===0){break a}a.C=a._;switch(d){case 0:break a;case 1:if(!c(a,'i')){return false}break;case 2:if(!c(a,'u')){return false}break;case 3:if(!c(a,'y')){return false}break;case 4:if(a._>=a.A){break a}a._++;break}continue b}a._=f;break b}return true};b.prototype.S=function(){return!(this.I_pV<=this._)?false:true};b.prototype.r_RV=b.prototype.S;b.prototype.Q=function(){return!(this.I_p1<=this._)?false:true};b.prototype.r_R1=b.prototype.Q;b.prototype.R=function(){return!(this.I_p2<=this._)?false:true};b.prototype.r_R2=b.prototype.R;b.prototype.Y=function(){var a;var E;var H;var e;var D;var g;var F;var G;var h;var I;var A;var B;var p;var k;var l;var m;var n;var o;var i;var q;var s;var t;var u;var v;var w;var x;var y;var z;var J;var K;var L;var C;this.C=this._;a=f(this,b.a_4,43);if(a===0){return false}this.D=this._;switch(a){case 0:return false;case 1:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'')){return false}break;case 2:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'')){return false}E=this.A-this._;p=true;c:while(p===true){p=false;this.C=this._;if(!d(this,2,'ic')){this._=this.A-E;break c}this.D=this._;k=true;b:while(k===true){k=false;H=this.A-this._;l=true;a:while(l===true){l=false;if(!(!(this.I_p2<=this._)?false:true)){break a}if(!c(this,'')){return false}break b}this._=this.A-H;if(!c(this,'iqU')){return false}}}break;case 3:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'log')){return false}break;case 4:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'u')){return false}break;case 5:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'ent')){return false}break;case 6:if(!(!(this.I_pV<=this._)?false:true)){return false}if(!c(this,'')){return false}e=this.A-this._;m=true;a:while(m===true){m=false;this.C=this._;a=f(this,b.a_2,6);if(a===0){this._=this.A-e;break a}this.D=this._;switch(a){case 0:this._=this.A-e;break a;case 1:if(!(!(this.I_p2<=this._)?false:true)){this._=this.A-e;break a}if(!c(this,'')){return false}this.C=this._;if(!d(this,2,'at')){this._=this.A-e;break a}this.D=J=this._;if(!(!(this.I_p2<=J)?false:true)){this._=this.A-e;break a}if(!c(this,'')){return false}break;case 2:n=true;b:while(n===true){n=false;D=this.A-this._;o=true;c:while(o===true){o=false;if(!(!(this.I_p2<=this._)?false:true)){break c}if(!c(this,'')){return false}break b}K=this._=this.A-D;if(!(!(this.I_p1<=K)?false:true)){this._=this.A-e;break a}if(!c(this,'eux')){return false}}break;case 3:if(!(!(this.I_p2<=this._)?false:true)){this._=this.A-e;break a}if(!c(this,'')){return false}break;case 4:if(!(!(this.I_pV<=this._)?false:true)){this._=this.A-e;break a}if(!c(this,'i')){return false}break}}break;case 7:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'')){return false}g=this.A-this._;i=true;a:while(i===true){i=false;this.C=this._;a=f(this,b.a_3,3);if(a===0){this._=this.A-g;break a}this.D=this._;switch(a){case 0:this._=this.A-g;break a;case 1:q=true;c:while(q===true){q=false;F=this.A-this._;s=true;b:while(s===true){s=false;if(!(!(this.I_p2<=this._)?false:true)){break b}if(!c(this,'')){return false}break c}this._=this.A-F;if(!c(this,'abl')){return false}}break;case 2:t=true;b:while(t===true){t=false;G=this.A-this._;u=true;c:while(u===true){u=false;if(!(!(this.I_p2<=this._)?false:true)){break c}if(!c(this,'')){return false}break b}this._=this.A-G;if(!c(this,'iqU')){return false}}break;case 3:if(!(!(this.I_p2<=this._)?false:true)){this._=this.A-g;break a}if(!c(this,'')){return false}break}}break;case 8:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'')){return false}h=this.A-this._;v=true;a:while(v===true){v=false;this.C=this._;if(!d(this,2,'at')){this._=this.A-h;break a}this.D=L=this._;if(!(!(this.I_p2<=L)?false:true)){this._=this.A-h;break a}if(!c(this,'')){return false}this.C=this._;if(!d(this,2,'ic')){this._=this.A-h;break a}this.D=this._;w=true;b:while(w===true){w=false;I=this.A-this._;x=true;c:while(x===true){x=false;if(!(!(this.I_p2<=this._)?false:true)){break c}if(!c(this,'')){return false}break b}this._=this.A-I;if(!c(this,'iqU')){return false}}}break;case 9:if(!c(this,'eau')){return false}break;case 10:if(!(!(this.I_p1<=this._)?false:true)){return false}if(!c(this,'al')){return false}break;case 11:y=true;a:while(y===true){y=false;A=this.A-this._;z=true;b:while(z===true){z=false;if(!(!(this.I_p2<=this._)?false:true)){break b}if(!c(this,'')){return false}break a}C=this._=this.A-A;if(!(!(this.I_p1<=C)?false:true)){return false}if(!c(this,'eux')){return false}}break;case 12:if(!(!(this.I_p1<=this._)?false:true)){return false}if(!j(this,b.g_v,97,251)){return false}if(!c(this,'')){return false}break;case 13:if(!(!(this.I_pV<=this._)?false:true)){return false}if(!c(this,'ant')){return false}return false;case 14:if(!(!(this.I_pV<=this._)?false:true)){return false}if(!c(this,'ent')){return false}return false;case 15:B=this.A-this._;if(!r(this,b.g_v,97,251)){return false}if(!(!(this.I_pV<=this._)?false:true)){return false}this._=this.A-B;if(!c(this,'')){return false}return false}return true};b.prototype.r_standard_suffix=b.prototype.Y;function K(a){var g;var F;var I;var e;var E;var h;var G;var H;var i;var J;var B;var C;var p;var l;var m;var n;var o;var k;var q;var s;var t;var u;var v;var w;var x;var y;var z;var A;var K;var L;var M;var D;a.C=a._;g=f(a,b.a_4,43);if(g===0){return false}a.D=a._;switch(g){case 0:return false;case 1:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'')){return false}break;case 2:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'')){return false}F=a.A-a._;p=true;c:while(p===true){p=false;a.C=a._;if(!d(a,2,'ic')){a._=a.A-F;break c}a.D=a._;l=true;b:while(l===true){l=false;I=a.A-a._;m=true;a:while(m===true){m=false;if(!(!(a.I_p2<=a._)?false:true)){break a}if(!c(a,'')){return false}break b}a._=a.A-I;if(!c(a,'iqU')){return false}}}break;case 3:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'log')){return false}break;case 4:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'u')){return false}break;case 5:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'ent')){return false}break;case 6:if(!(!(a.I_pV<=a._)?false:true)){return false}if(!c(a,'')){return false}e=a.A-a._;n=true;a:while(n===true){n=false;a.C=a._;g=f(a,b.a_2,6);if(g===0){a._=a.A-e;break a}a.D=a._;switch(g){case 0:a._=a.A-e;break a;case 1:if(!(!(a.I_p2<=a._)?false:true)){a._=a.A-e;break a}if(!c(a,'')){return false}a.C=a._;if(!d(a,2,'at')){a._=a.A-e;break a}a.D=K=a._;if(!(!(a.I_p2<=K)?false:true)){a._=a.A-e;break a}if(!c(a,'')){return false}break;case 2:o=true;b:while(o===true){o=false;E=a.A-a._;k=true;c:while(k===true){k=false;if(!(!(a.I_p2<=a._)?false:true)){break c}if(!c(a,'')){return false}break b}L=a._=a.A-E;if(!(!(a.I_p1<=L)?false:true)){a._=a.A-e;break a}if(!c(a,'eux')){return false}}break;case 3:if(!(!(a.I_p2<=a._)?false:true)){a._=a.A-e;break a}if(!c(a,'')){return false}break;case 4:if(!(!(a.I_pV<=a._)?false:true)){a._=a.A-e;break a}if(!c(a,'i')){return false}break}}break;case 7:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'')){return false}h=a.A-a._;q=true;a:while(q===true){q=false;a.C=a._;g=f(a,b.a_3,3);if(g===0){a._=a.A-h;break a}a.D=a._;switch(g){case 0:a._=a.A-h;break a;case 1:s=true;c:while(s===true){s=false;G=a.A-a._;t=true;b:while(t===true){t=false;if(!(!(a.I_p2<=a._)?false:true)){break b}if(!c(a,'')){return false}break c}a._=a.A-G;if(!c(a,'abl')){return false}}break;case 2:u=true;b:while(u===true){u=false;H=a.A-a._;v=true;c:while(v===true){v=false;if(!(!(a.I_p2<=a._)?false:true)){break c}if(!c(a,'')){return false}break b}a._=a.A-H;if(!c(a,'iqU')){return false}}break;case 3:if(!(!(a.I_p2<=a._)?false:true)){a._=a.A-h;break a}if(!c(a,'')){return false}break}}break;case 8:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'')){return false}i=a.A-a._;w=true;a:while(w===true){w=false;a.C=a._;if(!d(a,2,'at')){a._=a.A-i;break a}a.D=M=a._;if(!(!(a.I_p2<=M)?false:true)){a._=a.A-i;break a}if(!c(a,'')){return false}a.C=a._;if(!d(a,2,'ic')){a._=a.A-i;break a}a.D=a._;x=true;b:while(x===true){x=false;J=a.A-a._;y=true;c:while(y===true){y=false;if(!(!(a.I_p2<=a._)?false:true)){break c}if(!c(a,'')){return false}break b}a._=a.A-J;if(!c(a,'iqU')){return false}}}break;case 9:if(!c(a,'eau')){return false}break;case 10:if(!(!(a.I_p1<=a._)?false:true)){return false}if(!c(a,'al')){return false}break;case 11:z=true;a:while(z===true){z=false;B=a.A-a._;A=true;b:while(A===true){A=false;if(!(!(a.I_p2<=a._)?false:true)){break b}if(!c(a,'')){return false}break a}D=a._=a.A-B;if(!(!(a.I_p1<=D)?false:true)){return false}if(!c(a,'eux')){return false}}break;case 12:if(!(!(a.I_p1<=a._)?false:true)){return false}if(!j(a,b.g_v,97,251)){return false}if(!c(a,'')){return false}break;case 13:if(!(!(a.I_pV<=a._)?false:true)){return false}if(!c(a,'ant')){return false}return false;case 14:if(!(!(a.I_pV<=a._)?false:true)){return false}if(!c(a,'ent')){return false}return false;case 15:C=a.A-a._;if(!r(a,b.g_v,97,251)){return false}if(!(!(a.I_pV<=a._)?false:true)){return false}a._=a.A-C;if(!c(a,'')){return false}return false}return true};b.prototype.T=function(){var d;var e;var a;var g;var h;var i;e=this.A-(g=this._);if(g<this.I_pV){return false}h=this._=this.I_pV;a=this.B;this.B=h;i=this._=this.A-e;this.C=i;d=f(this,b.a_5,35);if(d===0){this.B=a;return false}this.D=this._;switch(d){case 0:this.B=a;return false;case 1:if(!j(this,b.g_v,97,251)){this.B=a;return false}if(!c(this,'')){return false}break}this.B=a;return true};b.prototype.r_i_verb_suffix=b.prototype.T;function L(a){var e;var g;var d;var h;var i;var k;g=a.A-(h=a._);if(h<a.I_pV){return false}i=a._=a.I_pV;d=a.B;a.B=i;k=a._=a.A-g;a.C=k;e=f(a,b.a_5,35);if(e===0){a.B=d;return false}a.D=a._;switch(e){case 0:a.B=d;return false;case 1:if(!j(a,b.g_v,97,251)){a.B=d;return false}if(!c(a,'')){return false}break}a.B=d;return true};b.prototype.b=function(){var e;var h;var a;var i;var g;var j;var k;var l;h=this.A-(j=this._);if(j<this.I_pV){return false}k=this._=this.I_pV;a=this.B;this.B=k;l=this._=this.A-h;this.C=l;e=f(this,b.a_6,38);if(e===0){this.B=a;return false}this.D=this._;switch(e){case 0:this.B=a;return false;case 1:if(!(!(this.I_p2<=this._)?false:true)){this.B=a;return false}if(!c(this,'')){return false}break;case 2:if(!c(this,'')){return false}break;case 3:if(!c(this,'')){return false}i=this.A-this._;g=true;a:while(g===true){g=false;this.C=this._;if(!d(this,1,'e')){this._=this.A-i;break a}this.D=this._;if(!c(this,'')){return false}}break}this.B=a;return true};b.prototype.r_verb_suffix=b.prototype.b;function M(a){var g;var i;var e;var j;var h;var k;var l;var m;i=a.A-(k=a._);if(k<a.I_pV){return false}l=a._=a.I_pV;e=a.B;a.B=l;m=a._=a.A-i;a.C=m;g=f(a,b.a_6,38);if(g===0){a.B=e;return false}a.D=a._;switch(g){case 0:a.B=e;return false;case 1:if(!(!(a.I_p2<=a._)?false:true)){a.B=e;return false}if(!c(a,'')){return false}break;case 2:if(!c(a,'')){return false}break;case 3:if(!c(a,'')){return false}j=a.A-a._;h=true;a:while(h===true){h=false;a.C=a._;if(!d(a,1,'e')){a._=a.A-j;break a}a.D=a._;if(!c(a,'')){return false}}break}a.B=e;return true};b.prototype.X=function(){var h;var g;var m;var n;var a;var l;var e;var i;var k;var p;var q;var r;var o;g=this.A-this._;e=true;a:while(e===true){e=false;this.C=this._;if(!d(this,1,'s')){this._=this.A-g;break a}this.D=p=this._;m=this.A-p;if(!j(this,b.g_keep_with_s,97,232)){this._=this.A-g;break a}this._=this.A-m;if(!c(this,'')){return false}}n=this.A-(q=this._);if(q<this.I_pV){return false}r=this._=this.I_pV;a=this.B;this.B=r;o=this._=this.A-n;this.C=o;h=f(this,b.a_7,7);if(h===0){this.B=a;return false}this.D=this._;switch(h){case 0:this.B=a;return false;case 1:if(!(!(this.I_p2<=this._)?false:true)){this.B=a;return false}i=true;a:while(i===true){i=false;l=this.A-this._;k=true;b:while(k===true){k=false;if(!d(this,1,'s')){break b}break a}this._=this.A-l;if(!d(this,1,'t')){this.B=a;return false}}if(!c(this,'')){return false}break;case 2:if(!c(this,'i')){return false}break;case 3:if(!c(this,'')){return false}break;case 4:if(!d(this,2,'gu')){this.B=a;return false}if(!c(this,'')){return false}break}this.B=a;return true};b.prototype.r_residual_suffix=b.prototype.X;function w(a){var g;var h;var p;var n;var e;var m;var i;var k;var l;var q;var r;var s;var o;h=a.A-a._;i=true;a:while(i===true){i=false;a.C=a._;if(!d(a,1,'s')){a._=a.A-h;break a}a.D=q=a._;p=a.A-q;if(!j(a,b.g_keep_with_s,97,232)){a._=a.A-h;break a}a._=a.A-p;if(!c(a,'')){return false}}n=a.A-(r=a._);if(r<a.I_pV){return false}s=a._=a.I_pV;e=a.B;a.B=s;o=a._=a.A-n;a.C=o;g=f(a,b.a_7,7);if(g===0){a.B=e;return false}a.D=a._;switch(g){case 0:a.B=e;return false;case 1:if(!(!(a.I_p2<=a._)?false:true)){a.B=e;return false}k=true;a:while(k===true){k=false;m=a.A-a._;l=true;b:while(l===true){l=false;if(!d(a,1,'s')){break b}break a}a._=a.A-m;if(!d(a,1,'t')){a.B=e;return false}}if(!c(a,'')){return false}break;case 2:if(!c(a,'i')){return false}break;case 3:if(!c(a,'')){return false}break;case 4:if(!d(a,2,'gu')){a.B=e;return false}if(!c(a,'')){return false}break}a.B=e;return true};b.prototype.a=function(){var d;var a;d=this.A-this._;if(f(this,b.a_8,5)===0){return false}a=this._=this.A-d;this.C=a;if(a<=this.B){return false}this._--;this.D=this._;return!c(this,'')?false:true};b.prototype.r_un_double=b.prototype.a;function t(a){var e;var d;e=a.A-a._;if(f(a,b.a_8,5)===0){return false}d=a._=a.A-e;a.C=d;if(d<=a.B){return false}a._--;a.D=a._;return!c(a,'')?false:true};b.prototype.Z=function(){var h;var a;var e;var f;var g;a=1;a:while(true){e=true;b:while(e===true){e=false;if(!j(this,b.g_v,97,251)){break b}a--;continue a}break a}if(a>0){return false}this.C=this._;f=true;a:while(f===true){f=false;h=this.A-this._;g=true;b:while(g===true){g=false;if(!d(this,1,'é')){break b}break a}this._=this.A-h;if(!d(this,1,'è')){return false}}this.D=this._;return!c(this,'e')?false:true};b.prototype.r_un_accent=b.prototype.Z;function F(a){var i;var e;var f;var g;var h;e=1;a:while(true){f=true;b:while(f===true){f=false;if(!j(a,b.g_v,97,251)){break b}e--;continue a}break a}if(e>0){return false}a.C=a._;g=true;a:while(g===true){g=false;i=a.A-a._;h=true;b:while(h===true){h=false;if(!d(a,1,'é')){break b}break a}a._=a.A-i;if(!d(a,1,'è')){return false}}a.D=a._;return!c(a,'e')?false:true};b.prototype.J=function(){var u;var z;var A;var B;var C;var j;var s;var v;var x;var y;var e;var f;var g;var h;var i;var a;var b;var k;var l;var m;var n;var o;var p;var q;var D;var E;var G;var N;var O;var P;var Q;var R;var r;u=this._;e=true;a:while(e===true){e=false;if(!H(this)){break a}}D=this._=u;z=D;f=true;a:while(f===true){f=false;if(!I(this)){break a}}N=this._=z;this.B=N;P=this._=O=this.A;A=O-P;g=true;c:while(g===true){g=false;h=true;d:while(h===true){h=false;B=this.A-this._;i=true;e:while(i===true){i=false;C=this.A-this._;a=true;a:while(a===true){a=false;j=this.A-this._;b=true;b:while(b===true){b=false;if(!K(this)){break b}break a}this._=this.A-j;k=true;b:while(k===true){k=false;if(!L(this)){break b}break a}this._=this.A-j;if(!M(this)){break e}}G=this._=(E=this.A)-C;s=E-G;l=true;a:while(l===true){l=false;this.C=this._;m=true;b:while(m===true){m=false;v=this.A-this._;n=true;f:while(n===true){n=false;if(!d(this,1,'Y')){break f}this.D=this._;if(!c(this,'i')){return false}break b}this._=this.A-v;if(!d(this,1,'ç')){this._=this.A-s;break a}this.D=this._;if(!c(this,'c')){return false}}}break d}this._=this.A-B;if(!w(this)){break c}}}R=this._=(Q=this.A)-A;x=Q-R;o=true;a:while(o===true){o=false;if(!t(this)){break a}}this._=this.A-x;p=true;a:while(p===true){p=false;if(!F(this)){break a}}r=this._=this.B;y=r;q=true;a:while(q===true){q=false;if(!J(this)){break a}}this._=y;return true};b.prototype.stem=b.prototype.J;b.prototype.N=function(a){return a instanceof b};b.prototype.equals=b.prototype.N;b.prototype.O=function(){var c;var a;var b;var d;c='FrenchStemmer';a=0;for(b=0;b<c.length;b++){d=c.charCodeAt(b);a=(a<<5)-a+d;a=a&a}return a|0};b.prototype.hashCode=b.prototype.O;b.serialVersionUID=1;g(b,'methodObject',function(){return new b});g(b,'a_0',function(){return[new a('col',-1,-1),new a('par',-1,-1),new a('tap',-1,-1)]});g(b,'a_1',function(){return[new a('',-1,4),new a('I',0,1),new a('U',0,2),new a('Y',0,3)]});g(b,'a_2',function(){return[new a('iqU',-1,3),new a('abl',-1,3),new a('Ièr',-1,4),new a('ièr',-1,4),new a('eus',-1,2),new a('iv',-1,1)]});g(b,'a_3',function(){return[new a('ic',-1,2),new a('abil',-1,1),new a('iv',-1,3)]});g(b,'a_4',function(){return[new a('iqUe',-1,1),new a('atrice',-1,2),new a('ance',-1,1),new a('ence',-1,5),new a('logie',-1,3),new a('able',-1,1),new a('isme',-1,1),new a('euse',-1,11),new a('iste',-1,1),new a('ive',-1,8),new a('if',-1,8),new a('usion',-1,4),new a('ation',-1,2),new a('ution',-1,4),new a('ateur',-1,2),new a('iqUes',-1,1),new a('atrices',-1,2),new a('ances',-1,1),new a('ences',-1,5),new a('logies',-1,3),new a('ables',-1,1),new a('ismes',-1,1),new a('euses',-1,11),new a('istes',-1,1),new a('ives',-1,8),new a('ifs',-1,8),new a('usions',-1,4),new a('ations',-1,2),new a('utions',-1,4),new a('ateurs',-1,2),new a('ments',-1,15),new a('ements',30,6),new a('issements',31,12),new a('ités',-1,7),new a('ment',-1,15),new a('ement',34,6),new a('issement',35,12),new a('amment',34,13),new a('emment',34,14),new a('aux',-1,10),new a('eaux',39,9),new a('eux',-1,1),new a('ité',-1,7)]});g(b,'a_5',function(){return[new a('ira',-1,1),new a('ie',-1,1),new a('isse',-1,1),new a('issante',-1,1),new a('i',-1,1),new a('irai',4,1),new a('ir',-1,1),new a('iras',-1,1),new a('ies',-1,1),new a('îmes',-1,1),new a('isses',-1,1),new a('issantes',-1,1),new a('îtes',-1,1),new a('is',-1,1),new a('irais',13,1),new a('issais',13,1),new a('irions',-1,1),new a('issions',-1,1),new a('irons',-1,1),new a('issons',-1,1),new a('issants',-1,1),new a('it',-1,1),new a('irait',21,1),new a('issait',21,1),new a('issant',-1,1),new a('iraIent',-1,1),new a('issaIent',-1,1),new a('irent',-1,1),new a('issent',-1,1),new a('iront',-1,1),new a('ît',-1,1),new a('iriez',-1,1),new a('issiez',-1,1),new a('irez',-1,1),new a('issez',-1,1)]});g(b,'a_6',function(){return[new a('a',-1,3),new a('era',0,2),new a('asse',-1,3),new a('ante',-1,3),new a('ée',-1,2),new a('ai',-1,3),new a('erai',5,2),new a('er',-1,2),new a('as',-1,3),new a('eras',8,2),new a('âmes',-1,3),new a('asses',-1,3),new a('antes',-1,3),new a('âtes',-1,3),new a('ées',-1,2),new a('ais',-1,3),new a('erais',15,2),new a('ions',-1,1),new a('erions',17,2),new a('assions',17,3),new a('erons',-1,2),new a('ants',-1,3),new a('és',-1,2),new a('ait',-1,3),new a('erait',23,2),new a('ant',-1,3),new a('aIent',-1,3),new a('eraIent',26,2),new a('èrent',-1,2),new a('assent',-1,3),new a('eront',-1,2),new a('ât',-1,3),new a('ez',-1,2),new a('iez',32,2),new a('eriez',33,2),new a('assiez',33,3),new a('erez',32,2),new a('é',-1,2)]});g(b,'a_7',function(){return[new a('e',-1,3),new a('Ière',0,2),new a('ière',0,2),new a('ion',-1,1),new a('Ier',-1,2),new a('ier',-1,2),new a('ë',-1,4)]});g(b,'a_8',function(){return[new a('ell',-1,-1),new a('eill',-1,-1),new a('enn',-1,-1),new a('onn',-1,-1),new a('ett',-1,-1)]});g(b,'g_v',function(){return[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,128,130,103,8,5]});g(b,'g_keep_with_s',function(){return[1,65,20,0,0,0,0,0,0,0,0,0,0,0,0,0,128]});var q={'src/stemmer.jsx':{Stemmer:p},'src/french-stemmer.jsx':{FrenchStemmer:b}}}(JSX))
+var Stemmer = JSX.require("src/french-stemmer.jsx").FrenchStemmer;
+"""
+
+
+class SearchFrench(SearchLanguage):
+    lang = 'fr'
+    language_name = 'French'
+    js_stemmer_code = js_stemmer
+    stopwords = french_stopwords
+
+    def init(self, options):
+        self.stemmer = snowballstemmer.stemmer('french')
+
+    def stem(self, word):
+        return self.stemmer.stemWord(word)
diff --git a/sphinx/search/hu.py b/sphinx/search/hu.py
new file mode 100644
index 0000000..003a98a
--- /dev/null
+++ b/sphinx/search/hu.py
@@ -0,0 +1,237 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.search.hu
+    ~~~~~~~~~~~~~~~~
+
+    Hungarian search language: includes the JS Hungarian stemmer.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from sphinx.search import SearchLanguage, parse_stop_word
+
+import snowballstemmer
+
+hungarian_stopwords = parse_stop_word(u'''
+| source: http://snowball.tartarus.org/algorithms/hungarian/stop.txt
+| prepared by Anna Tordai
+a
+ahogy
+ahol
+aki
+akik
+akkor
+alatt
+által
+általában
+amely
+amelyek
+amelyekben
+amelyeket
+amelyet
+amelynek
+ami
+amit
+amolyan
+amíg
+amikor
+át
+abban
+ahhoz
+annak
+arra
+arról
+az
+azok
+azon
+azt
+azzal
+azért
+aztán
+azután
+azonban
+bár
+be
+belül
+benne
+cikk
+cikkek
+cikkeket
+csak
+de
+e
+eddig
+egész
+egy
+egyes
+egyetlen
+egyéb
+egyik
+egyre
+ekkor
+el
+elég
+ellen
+elő
+először
+előtt
+első
+én
+éppen
+ebben
+ehhez
+emilyen
+ennek
+erre
+ez
+ezt
+ezek
+ezen
+ezzel
+ezért
+és
+fel
+felé
+hanem
+hiszen
+hogy
+hogyan
+igen
+így
+illetve
+ill.
+ill
+ilyen
+ilyenkor
+ison
+ismét
+itt
+jó
+jól
+jobban
+kell
+kellett
+keresztül
+keressünk
+ki
+kívül
+között
+közül
+legalább
+lehet
+lehetett
+legyen
+lenne
+lenni
+lesz
+lett
+maga
+magát
+majd
+majd
+már
+más
+másik
+meg
+még
+mellett
+mert
+mely
+melyek
+mi
+mit
+míg
+miért
+milyen
+mikor
+minden
+mindent
+mindenki
+mindig
+mint
+mintha
+mivel
+most
+nagy
+nagyobb
+nagyon
+ne
+néha
+nekem
+neki
+nem
+néhány
+nélkül
+nincs
+olyan
+ott
+össze

+ők
+őket
+pedig
+persze
+rá
+s
+saját
+sem
+semmi
+sok
+sokat
+sokkal
+számára
+szemben
+szerint
+szinte
+talán
+tehát
+teljes
+tovább
+továbbá
+több
+úgy
+ugyanis
+új
+újabb
+újra
+után
+utána
+utolsó
+vagy
+vagyis
+valaki
+valami
+valamint
+való
+vagyok
+van
+vannak
+volt
+voltam
+voltak
+voltunk
+vissza
+vele
+viszont
+volna
+''')
+
+js_stemmer = u"""
+
+var JSX={};(function(h){function j(b,e){var a=function(){};a.prototype=e.prototype;var c=new a;for(var d in b){b[d].prototype=c}}function P(c,b){for(var a in b.prototype)if(b.prototype.hasOwnProperty(a))c.prototype[a]=b.prototype[a]}function e(a,b,d){function c(a,b,c){delete a[b];a[b]=c;return c}Object.defineProperty(a,b,{get:function(){return c(a,b,d())},set:function(d){c(a,b,d)},enumerable:true,configurable:true})}function O(a,b,c){return a[b]=a[b]/c|0}var u=parseInt;var v=parseFloat;function N(a){return a!==a}var x=isFinite;var y=encodeURIComponent;var z=decodeURIComponent;var B=encodeURI;var C=decodeURI;var E=Object.prototype.toString;var F=Object.prototype.hasOwnProperty;function i(){}h.require=function(b){var a=q[b];return a!==undefined?a:null};h.profilerIsRunning=function(){return i.getResults!=null};h.getProfileResults=function(){return(i.getResults||function(){return{}})()};h.postProfileResults=function(a,b){if(i.postResults==null)throw new Error('profiler has not been turned on');return i.postResults(a,b)};h.resetProfileResults=function(){if(i.resetResults==null)throw new Error('profiler has not been turned on');return i.resetResults()};h.DEBUG=false;function r(){};j([r],Error);function a(a,b,c){this.F=a.length;this.K=a;this.L=b;this.I=c;this.H=null;this.P=null};j([a],Object);function n(){};j([n],Object);function f(){var a;var b;var c;this.G={};a=this.D='';b=this._=0;c=this.A=a.length;this.E=0;this.B=b;this.C=c};j([f],n);function s(a,b){a.D=b.D;a._=b._;a.A=b.A;a.E=b.E;a.B=b.B;a.C=b.C};function k(b,d,c,e){var a;if(b._>=b.A){return false}a=b.D.charCodeAt(b._);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._++;return true};function l(a,d,c,e){var b;if(a._>=a.A){return false}b=a.D.charCodeAt(a._);if(b>e||b<c){a._++;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._++;return true}return false};function o(f,m,p){var b;var d;var e;var n;var g;var k;var l;var i;var h;var c;var a;var j;var o;b=0;d=p;e=f._;n=f.A;g=0;k=0;l=false;while(true){i=b+(d-b>>>1);h=0;c=g<k?g:k;a=m[i];for(j=c;j<a.F;j++){if(e+c===n){h=-1;break}h=f.D.charCodeAt(e+c)-a.K.charCodeAt(j);if(h!==0){break}c++}if(h<0){d=i;k=c}else{b=i;g=c}if(d-b<=1){if(b>0){break}if(d===b){break}if(l){break}l=true}}while(true){a=m[b];if(g>=a.F){f._=e+a.F|0;if(a.H==null){return a.I}o=a.H(a.P);f._=e+a.F|0;if(o){return a.I}}b=a.L;if(b<0){return 0}}return-1};function d(d,m,p){var b;var g;var e;var n;var f;var k;var l;var i;var h;var c;var a;var j;var o;b=0;g=p;e=d._;n=d.E;f=0;k=0;l=false;while(true){i=b+(g-b>>1);h=0;c=f<k?f:k;a=m[i];for(j=a.F-1-c;j>=0;j--){if(e-c===n){h=-1;break}h=d.D.charCodeAt(e-1-c)-a.K.charCodeAt(j);if(h!==0){break}c++}if(h<0){g=i;k=c}else{b=i;f=c}if(g-b<=1){if(b>0){break}if(g===b){break}if(l){break}l=true}}while(true){a=m[b];if(f>=a.F){d._=e-a.F|0;if(a.H==null){return a.I}o=a.H(d);d._=e-a.F|0;if(o){return a.I}}b=a.L;if(b<0){return 0}}return-1};function A(a,b,d,e){var c;c=e.length-(d-b);a.D=a.D.slice(0,b)+e+a.D.slice(d);a.A+=c|0;if(a._>=d){a._+=c|0}else if(a._>b){a._=b}return c|0};function b(a,f){var b;var c;var d;var e;b=false;if((c=a.B)<0||c>(d=a.C)||d>(e=a.A)||e>a.D.length?false:true){A(a,a.B,a.C,f);b=true}return b};f.prototype.J=function(){return false};f.prototype.e=function(b){var a;var c;var d;var e;a=this.G['.'+b];if(a==null){c=this.D=b;d=this._=0;e=this.A=c.length;this.E=0;this.B=d;this.C=e;this.J();a=this.D;this.G['.'+b]=a}return a};f.prototype.stemWord=f.prototype.e;f.prototype.f=function(e){var d;var b;var c;var a;var f;var g;var h;d=[];for(b=0;b<e.length;b++){c=e[b];a=this.G['.'+c];if(a==null){f=this.D=c;g=this._=0;h=this.A=f.length;this.E=0;this.B=g;this.C=h;this.J();a=this.D;this.G['.'+c]=a}d.push(a)}return d};f.prototype.stemWords=f.prototype.f;function c(){f.call(this);this.I_p1=0};j([c],f);c.prototype.M=function(a){this.I_p1=a.I_p1;s(this,a)};c.prototype.copy_from=c.prototype.M;c.prototype.X=function(){var m;var b;var j;var d;var e;var a;var f;var g;var h;var n;var i;this.I_p1=this.A;d=true;b:while(d===true){d=false;m=this._;e=true;a:while(e===true){e=false;if(!k(this,c.g_v,97,252)){break a}c:while(true){b=this._;a=true;d:while(a===true){a=false;if(!l(this,c.g_v,97,252)){break d}this._=b;break c}n=this._=b;if(n>=this.A){break a}this._++}f=true;c:while(f===true){f=false;j=this._;g=true;d:while(g===true){g=false;if(o(this,c.a_0,8)===0){break d}break c}i=this._=j;if(i>=this.A){break a}this._++}this.I_p1=this._;break b}this._=m;if(!l(this,c.g_v,97,252)){return false}a:while(true){h=true;c:while(h===true){h=false;if(!k(this,c.g_v,97,252)){break c}break a}if(this._>=this.A){return false}this._++}this.I_p1=this._}return true};c.prototype.r_mark_regions=c.prototype.X;function D(a){var j;var d;var n;var e;var b;var f;var g;var h;var i;var p;var m;a.I_p1=a.A;e=true;b:while(e===true){e=false;j=a._;b=true;a:while(b===true){b=false;if(!k(a,c.g_v,97,252)){break a}c:while(true){d=a._;f=true;d:while(f===true){f=false;if(!l(a,c.g_v,97,252)){break d}a._=d;break c}p=a._=d;if(p>=a.A){break a}a._++}g=true;c:while(g===true){g=false;n=a._;h=true;d:while(h===true){h=false;if(o(a,c.a_0,8)===0){break d}break c}m=a._=n;if(m>=a.A){break a}a._++}a.I_p1=a._;break b}a._=j;if(!l(a,c.g_v,97,252)){return false}a:while(true){i=true;c:while(i===true){i=false;if(!k(a,c.g_v,97,252)){break c}break a}if(a._>=a.A){return false}a._++}a.I_p1=a._}return true};c.prototype.Q=function(){return!(this.I_p1<=this._)?false:true};c.prototype.r_R1=c.prototype.Q;c.prototype.d=function(){var a;var e;this.C=this._;a=d(this,c.a_1,2);if(a===0){return false}this.B=e=this._;if(!(!(this.I_p1<=e)?false:true)){return false}switch(a){case 0:return false;case 1:if(!b(this,'a')){return false}break;case 2:if(!b(this,'e')){return false}break}return true};c.prototype.r_v_ending=c.prototype.d;function p(a){var e;var f;a.C=a._;e=d(a,c.a_1,2);if(e===0){return false}a.B=f=a._;if(!(!(a.I_p1<=f)?false:true)){return false}switch(e){case 0:return false;case 1:if(!b(a,'a')){return false}break;case 2:if(!b(a,'e')){return false}break}return true};c.prototype.U=function(){var a;a=this.A-this._;if(d(this,c.a_2,23)===0){return false}this._=this.A-a;return true};c.prototype.r_double=c.prototype.U;function g(a){var b;b=a.A-a._;if(d(a,c.a_2,23)===0){return false}a._=a.A-b;return true};c.prototype.c=function(){var a;var c;var d;if(this._<=this.E){return false}this._--;this.C=c=this._;a=c-1|0;if(this.E>a||a>this.A){return false}d=this._=a;this.B=d;return!b(this,'')?false:true};c.prototype.r_undouble=c.prototype.c;function m(a){var c;var d;var e;if(a._<=a.E){return false}a._--;a.C=d=a._;c=d-1|0;if(a.E>c||c>a.A){return false}e=a._=c;a.B=e;return!b(a,'')?false:true};c.prototype.W=function(){var a;var e;this.C=this._;a=d(this,c.a_3,2);if(a===0){return false}this.B=e=this._;if(!(!(this.I_p1<=e)?false:true)){return false}switch(a){case 0:return false;case 1:if(!g(this)){return false}break;case 2:if(!g(this)){return false}break}return!b(this,'')?false:!m(this)?false:true};c.prototype.r_instrum=c.prototype.W;function H(a){var e;var f;a.C=a._;e=d(a,c.a_3,2);if(e===0){return false}a.B=f=a._;if(!(!(a.I_p1<=f)?false:true)){return false}switch(e){case 0:return false;case 1:if(!g(a)){return false}break;case 2:if(!g(a)){return false}break}return!b(a,'')?false:!m(a)?false:true};c.prototype.R=function(){var a;this.C=this._;if(d(this,c.a_4,44)===0){return false}this.B=a=this._;return!(!(this.I_p1<=a)?false:true)?false:!b(this,'')?false:!p(this)?false:true};c.prototype.r_case=c.prototype.R;function I(a){var e;a.C=a._;if(d(a,c.a_4,44)===0){return false}a.B=e=a._;return!(!(a.I_p1<=e)?false:true)?false:!b(a,'')?false:!p(a)?false:true};c.prototype.T=function(){var a;var e;this.C=this._;a=d(this,c.a_5,3);if(a===0){return false}this.B=e=this._;if(!(!(this.I_p1<=e)?false:true)){return false}switch(a){case 0:return false;case 1:if(!b(this,'e')){return false}break;case 2:if(!b(this,'a')){return false}break;case 3:if(!b(this,'a')){return false}break}return true};c.prototype.r_case_special=c.prototype.T;function J(a){var e;var f;a.C=a._;e=d(a,c.a_5,3);if(e===0){return false}a.B=f=a._;if(!(!(a.I_p1<=f)?false:true)){return false}switch(e){case 0:return false;case 1:if(!b(a,'e')){return false}break;case 2:if(!b(a,'a')){return false}break;case 3:if(!b(a,'a')){return false}break}return true};c.prototype.S=function(){var a;var e;this.C=this._;a=d(this,c.a_6,6);if(a===0){return false}this.B=e=this._;if(!(!(this.I_p1<=e)?false:true)){return false}switch(a){case 0:return false;case 1:if(!b(this,'')){return false}break;case 2:if(!b(this,'')){return false}break;case 3:if(!b(this,'a')){return false}break;case 4:if(!b(this,'e')){return false}break}return true};c.prototype.r_case_other=c.prototype.S;function K(a){var e;var f;a.C=a._;e=d(a,c.a_6,6);if(e===0){return false}a.B=f=a._;if(!(!(a.I_p1<=f)?false:true)){return false}switch(e){case 0:return false;case 1:if(!b(a,'')){return false}break;case 2:if(!b(a,'')){return false}break;case 3:if(!b(a,'a')){return false}break;case 4:if(!b(a,'e')){return false}break}return true};c.prototype.V=function(){var a;var e;this.C=this._;a=d(this,c.a_7,2);if(a===0){return false}this.B=e=this._;if(!(!(this.I_p1<=e)?false:true)){return false}switch(a){case 0:return false;case 1:if(!g(this)){return false}break;case 2:if(!g(this)){return false}break}return!b(this,'')?false:!m(this)?false:true};c.prototype.r_factive=c.prototype.V;function L(a){var e;var f;a.C=a._;e=d(a,c.a_7,2);if(e===0){return false}a.B=f=a._;if(!(!(a.I_p1<=f)?false:true)){return false}switch(e){case 0:return false;case 1:if(!g(a)){return false}break;case 2:if(!g(a)){return false}break}return!b(a,'')?false:!m(a)?false:true};c.prototype.a=function(){var a;var e;this.C=this._;a=d(this,c.a_8,7);if(a===0){return false}this.B=e=this._;if(!(!(this.I_p1<=e)?false:true)){return false}switch(a){case 0:return false;case 1:if(!b(this,'a')){return false}break;case 2:if(!b(this,'e')){return false}break;case 3:if(!b(this,'')){return false}break;case 4:if(!b(this,'')){return false}break;case 5:if(!b(this,'')){return false}break;case 6:if(!b(this,'')){return false}break;case 7:if(!b(this,'')){return false}break}return true};c.prototype.r_plural=c.prototype.a;function M(a){var e;var f;a.C=a._;e=d(a,c.a_8,7);if(e===0){return false}a.B=f=a._;if(!(!(a.I_p1<=f)?false:true)){return false}switch(e){case 0:return false;case 1:if(!b(a,'a')){return false}break;case 2:if(!b(a,'e')){return false}break;case 3:if(!b(a,'')){return false}break;case 4:if(!b(a,'')){return false}break;case 5:if(!b(a,'')){return false}break;case 6:if(!b(a,'')){return false}break;case 7:if(!b(a,'')){return false}break}return true};c.prototype.Y=function(){var a;var e;this.C=this._;a=d(this,c.a_9,12);if(a===0){return false}this.B=e=this._;if(!(!(this.I_p1<=e)?false:true)){return false}switch(a){case 0:return false;case 1:if(!b(this,'')){return false}break;case 2:if(!b(this,'e')){return false}break;case 3:if(!b(this,'a')){return false}break;case 4:if(!b(this,'')){return false}break;case 5:if(!b(this,'e')){return false}break;case 6:if(!b(this,'a')){return false}break;case 7:if(!b(this,'')){return false}break;case 8:if(!b(this,'e')){return false}break;case 9:if(!b(this,'')){return false}break}return true};c.prototype.r_owned=c.prototype.Y;function w(a){var e;var f;a.C=a._;e=d(a,c.a_9,12);if(e===0){return false}a.B=f=a._;if(!(!(a.I_p1<=f)?false:true)){return false}switch(e){case 0:return false;case 1:if(!b(a,'')){return false}break;case 2:if(!b(a,'e')){return false}break;case 3:if(!b(a,'a')){return false}break;case 4:if(!b(a,'')){return false}break;case 5:if(!b(a,'e')){return false}break;case 6:if(!b(a,'a')){return false}break;case 7:if(!b(a,'')){return false}break;case 8:if(!b(a,'e')){return false}break;case 9:if(!b(a,'')){return false}break}return true};c.prototype.b=function(){var a;var e;this.C=this._;a=d(this,c.a_10,31);if(a===0){return false}this.B=e=this._;if(!(!(this.I_p1<=e)?false:true)){return false}switch(a){case 0:return false;case 1:if(!b(this,'')){return false}break;case 2:if(!b(this,'a')){return false}break;case 3:if(!b(this,'e')){return false}break;case 4:if(!b(this,'')){return false}break;case 5:if(!b(this,'a')){return false}break;case 6:if(!b(this,'e')){return false}break;case 7:if(!b(this,'')){return false}break;case 8:if(!b(this,'')){return false}break;case 9:if(!b(this,'')){return false}break;case 10:if(!b(this,'a')){return false}break;case 11:if(!b(this,'e')){return false}break;case 12:if(!b(this,'')){return false}break;case 13:if(!b(this,'')){return false}break;case 14:if(!b(this,'a')){return false}break;case 15:if(!b(this,'e')){return false}break;case 16:if(!b(this,'')){return false}break;case 17:if(!b(this,'')){return false}break;case 18:if(!b(this,'')){return false}break;case 19:if(!b(this,'a')){return false}break;case 20:if(!b(this,'e')){return false}break}return true};c.prototype.r_sing_owner=c.prototype.b;function t(a){var e;var f;a.C=a._;e=d(a,c.a_10,31);if(e===0){return false}a.B=f=a._;if(!(!(a.I_p1<=f)?false:true)){return false}switch(e){case 0:return false;case 1:if(!b(a,'')){return false}break;case 2:if(!b(a,'a')){return false}break;case 3:if(!b(a,'e')){return false}break;case 4:if(!b(a,'')){return false}break;case 5:if(!b(a,'a')){return false}break;case 6:if(!b(a,'e')){return false}break;case 7:if(!b(a,'')){return false}break;case 8:if(!b(a,'')){return false}break;case 9:if(!b(a,'')){return false}break;case 10:if(!b(a,'a')){return false}break;case 11:if(!b(a,'e')){return false}break;case 12:if(!b(a,'')){return false}break;case 13:if(!b(a,'')){return false}break;case 14:if(!b(a,'a')){return false}break;case 15:if(!b(a,'e')){return false}break;case 16:if(!b(a,'')){return false}break;case 17:if(!b(a,'')){return false}break;case 18:if(!b(a,'')){return false}break;case 19:if(!b(a,'a')){return false}break;case 20:if(!b(a,'e')){return false}break}return true};c.prototype.Z=function(){var a;var e;this.C=this._;a=d(this,c.a_11,42);if(a===0){return false}this.B=e=this._;if(!(!(this.I_p1<=e)?false:true)){return false}switch(a){case 0:return false;case 1:if(!b(this,'')){return false}break;case 2:if(!b(this,'a')){return false}break;case 3:if(!b(this,'e')){return false}break;case 4:if(!b(this,'')){return false}break;case 5:if(!b(this,'')){return false}break;case 6:if(!b(this,'')){return false}break;case 7:if(!b(this,'a')){return false}break;case 8:if(!b(this,'e')){return false}break;case 9:if(!b(this,'')){return false}break;case 10:if(!b(this,'')){return false}break;case 11:if(!b(this,'')){return false}break;case 12:if(!b(this,'a')){return false}break;case 13:if(!b(this,'e')){return false}break;case 14:if(!b(this,'')){return false}break;case 15:if(!b(this,'')){return false}break;case 16:if(!b(this,'')){return false}break;case 17:if(!b(this,'')){return false}break;case 18:if(!b(this,'a')){return false}break;case 19:if(!b(this,'e')){return false}break;case 20:if(!b(this,'')){return false}break;case 21:if(!b(this,'')){return false}break;case 22:if(!b(this,'a')){return false}break;case 23:if(!b(this,'e')){return false}break;case 24:if(!b(this,'')){return false}break;case 25:if(!b(this,'')){return false}break;case 26:if(!b(this,'')){return false}break;case 27:if(!b(this,'a')){return false}break;case 28:if(!b(this,'e')){return false}break;case 29:if(!b(this,'')){return false}break}return true};c.prototype.r_plur_owner=c.prototype.Z;function G(a){var e;var f;a.C=a._;e=d(a,c.a_11,42);if(e===0){return false}a.B=f=a._;if(!(!(a.I_p1<=f)?false:true)){return false}switch(e){case 0:return false;case 1:if(!b(a,'')){return false}break;case 2:if(!b(a,'a')){return false}break;case 3:if(!b(a,'e')){return false}break;case 4:if(!b(a,'')){return false}break;case 5:if(!b(a,'')){return false}break;case 6:if(!b(a,'')){return false}break;case 7:if(!b(a,'a')){return false}break;case 8:if(!b(a,'e')){return false}break;case 9:if(!b(a,'')){return false}break;case 10:if(!b(a,'')){return false}break;case 11:if(!b(a,'')){return false}break;case 12:if(!b(a,'a')){return false}break;case 13:if(!b(a,'e')){return false}break;case 14:if(!b(a,'')){return false}break;case 15:if(!b(a,'')){return false}break;case 16:if(!b(a,'')){return false}break;case 17:if(!b(a,'')){return false}break;case 18:if(!b(a,'a')){return false}break;case 19:if(!b(a,'e')){return false}break;case 20:if(!b(a,'')){return false}break;case 21:if(!b(a,'')){return false}break;case 22:if(!b(a,'a')){return false}break;case 23:if(!b(a,'e')){return false}break;case 24:if(!b(a,'')){return false}break;case 25:if(!b(a,'')){return false}break;case 26:if(!b(a,'')){return false}break;case 27:if(!b(a,'a')){return false}break;case 28:if(!b(a,'e')){return false}break;case 29:if(!b(a,'')){return false}break}return true};c.prototype.J=function(){var s;var l;var m;var n;var o;var p;var q;var r;var u;var b;var c;var d;var e;var f;var g;var h;var i;var a;var j;var v;var x;var y;var z;var A;var B;var C;var E;var F;var N;var O;var P;var Q;var R;var S;var T;var k;s=this._;b=true;a:while(b===true){b=false;if(!D(this)){break a}}v=this._=s;this.E=v;y=this._=x=this.A;l=x-y;c=true;a:while(c===true){c=false;if(!H(this)){break a}}A=this._=(z=this.A)-l;m=z-A;d=true;a:while(d===true){d=false;if(!I(this)){break a}}C=this._=(B=this.A)-m;n=B-C;e=true;a:while(e===true){e=false;if(!J(this)){break a}}F=this._=(E=this.A)-n;o=E-F;f=true;a:while(f===true){f=false;if(!K(this)){break a}}O=this._=(N=this.A)-o;p=N-O;g=true;a:while(g===true){g=false;if(!L(this)){break a}}Q=this._=(P=this.A)-p;q=P-Q;h=true;a:while(h===true){h=false;if(!w(this)){break a}}S=this._=(R=this.A)-q;r=R-S;i=true;a:while(i===true){i=false;if(!t(this)){break a}}k=this._=(T=this.A)-r;u=T-k;a=true;a:while(a===true){a=false;if(!G(this)){break a}}this._=this.A-u;j=true;a:while(j===true){j=false;if(!M(this)){break a}}this._=this.E;return true};c.prototype.stem=c.prototype.J;c.prototype.N=function(a){return a instanceof c};c.prototype.equals=c.prototype.N;c.prototype.O=function(){var c;var a;var b;var d;c='HungarianStemmer';a=0;for(b=0;b<c.length;b++){d=c.charCodeAt(b);a=(a<<5)-a+d;a=a&a}return a|0};c.prototype.hashCode=c.prototype.O;c.serialVersionUID=1;e(c,'methodObject',function(){return new c});e(c,'a_0',function(){return[new a('cs',-1,-1),new a('dzs',-1,-1),new a('gy',-1,-1),new a('ly',-1,-1),new a('ny',-1,-1),new a('sz',-1,-1),new a('ty',-1,-1),new a('zs',-1,-1)]});e(c,'a_1',function(){return[new a('á',-1,1),new a('é',-1,2)]});e(c,'a_2',function(){return[new a('bb',-1,-1),new a('cc',-1,-1),new a('dd',-1,-1),new a('ff',-1,-1),new a('gg',-1,-1),new a('jj',-1,-1),new a('kk',-1,-1),new a('ll',-1,-1),new a('mm',-1,-1),new a('nn',-1,-1),new a('pp',-1,-1),new a('rr',-1,-1),new a('ccs',-1,-1),new a('ss',-1,-1),new a('zzs',-1,-1),new a('tt',-1,-1),new a('vv',-1,-1),new a('ggy',-1,-1),new a('lly',-1,-1),new a('nny',-1,-1),new a('tty',-1,-1),new a('ssz',-1,-1),new a('zz',-1,-1)]});e(c,'a_3',function(){return[new a('al',-1,1),new a('el',-1,2)]});e(c,'a_4',function(){return[new a('ba',-1,-1),new a('ra',-1,-1),new a('be',-1,-1),new a('re',-1,-1),new a('ig',-1,-1),new a('nak',-1,-1),new a('nek',-1,-1),new a('val',-1,-1),new a('vel',-1,-1),new a('ul',-1,-1),new a('nál',-1,-1),new a('nél',-1,-1),new a('ból',-1,-1),new a('ról',-1,-1),new a('tól',-1,-1),new a('bõl',-1,-1),new a('rõl',-1,-1),new a('tõl',-1,-1),new a('ül',-1,-1),new a('n',-1,-1),new a('an',19,-1),new a('ban',20,-1),new a('en',19,-1),new a('ben',22,-1),new a('képpen',22,-1),new a('on',19,-1),new a('ön',19,-1),new a('képp',-1,-1),new a('kor',-1,-1),new a('t',-1,-1),new a('at',29,-1),new a('et',29,-1),new a('ként',29,-1),new a('anként',32,-1),new a('enként',32,-1),new a('onként',32,-1),new a('ot',29,-1),new a('ért',29,-1),new a('öt',29,-1),new a('hez',-1,-1),new a('hoz',-1,-1),new a('höz',-1,-1),new a('vá',-1,-1),new a('vé',-1,-1)]});e(c,'a_5',function(){return[new a('án',-1,2),new a('én',-1,1),new a('ánként',-1,3)]});e(c,'a_6',function(){return[new a('stul',-1,2),new a('astul',0,1),new a('ástul',0,3),new a('stül',-1,2),new a('estül',3,1),new a('éstül',3,4)]});e(c,'a_7',function(){return[new a('á',-1,1),new a('é',-1,2)]});e(c,'a_8',function(){return[new a('k',-1,7),new a('ak',0,4),new a('ek',0,6),new a('ok',0,5),new a('ák',0,1),new a('ék',0,2),new a('ök',0,3)]});e(c,'a_9',function(){return[new a('éi',-1,7),new a('áéi',0,6),new a('ééi',0,5),new a('é',-1,9),new a('ké',3,4),new a('aké',4,1),new a('eké',4,1),new a('oké',4,1),new a('áké',4,3),new a('éké',4,2),new a('öké',4,1),new a('éé',3,8)]});e(c,'a_10',function(){return[new a('a',-1,18),new a('ja',0,17),new a('d',-1,16),new a('ad',2,13),new a('ed',2,13),new a('od',2,13),new a('ád',2,14),new a('éd',2,15),new a('öd',2,13),new a('e',-1,18),new a('je',9,17),new a('nk',-1,4),new a('unk',11,1),new a('ánk',11,2),new a('énk',11,3),new a('ünk',11,1),new a('uk',-1,8),new a('juk',16,7),new a('ájuk',17,5),new a('ük',-1,8),new a('jük',19,7),new a('éjük',20,6),new a('m',-1,12),new a('am',22,9),new a('em',22,9),new a('om',22,9),new a('ám',22,10),new a('ém',22,11),new a('o',-1,18),new a('á',-1,19),new a('é',-1,20)]});e(c,'a_11',function(){return[new a('id',-1,10),new a('aid',0,9),new a('jaid',1,6),new a('eid',0,9),new a('jeid',3,6),new a('áid',0,7),new a('éid',0,8),new a('i',-1,15),new a('ai',7,14),new a('jai',8,11),new a('ei',7,14),new a('jei',10,11),new a('ái',7,12),new a('éi',7,13),new a('itek',-1,24),new a('eitek',14,21),new a('jeitek',15,20),new a('éitek',14,23),new a('ik',-1,29),new a('aik',18,26),new a('jaik',19,25),new a('eik',18,26),new a('jeik',21,25),new a('áik',18,27),new a('éik',18,28),new a('ink',-1,20),new a('aink',25,17),new a('jaink',26,16),new a('eink',25,17),new a('jeink',28,16),new a('áink',25,18),new a('éink',25,19),new a('aitok',-1,21),new a('jaitok',32,20),new a('áitok',-1,22),new a('im',-1,5),new a('aim',35,4),new a('jaim',36,1),new a('eim',35,4),new a('jeim',38,1),new a('áim',35,2),new a('éim',35,3)]});e(c,'g_v',function(){return[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,52,14]});var q={'src/stemmer.jsx':{Stemmer:n},'src/hungarian-stemmer.jsx':{HungarianStemmer:c}}}(JSX))
+var Stemmer = JSX.require("src/hungarian-stemmer.jsx").HungarianStemmer;
+"""
+
+
+class SearchHungarian(SearchLanguage):
+    lang = 'hu'
+    language_name = 'Hungarian'
+    js_stemmer_code = js_stemmer
+    stopwords = hungarian_stopwords
+
+    def init(self, options):
+        self.stemmer = snowballstemmer.stemmer('hungarian')
+
+    def stem(self, word):
+        return self.stemmer.stemWord(word)
diff --git a/sphinx/search/it.py b/sphinx/search/it.py
new file mode 100644
index 0000000..1b8d51e
--- /dev/null
+++ b/sphinx/search/it.py
@@ -0,0 +1,326 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.search.it
+    ~~~~~~~~~~~~~~~~
+
+    Italian search language: includes the JS Italian stemmer.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from sphinx.search import SearchLanguage, parse_stop_word
+
+import snowballstemmer
+
+italian_stopwords = parse_stop_word(u'''
+| source: http://snowball.tartarus.org/algorithms/italian/stop.txt
+ad             |  a (to) before vowel
+al             |  a + il
+allo           |  a + lo
+ai             |  a + i
+agli           |  a + gli
+all            |  a + l'
+agl            |  a + gl'
+alla           |  a + la
+alle           |  a + le
+con            |  with
+col            |  con + il
+coi            |  con + i (forms collo, cogli etc are now very rare)
+da             |  from
+dal            |  da + il
+dallo          |  da + lo
+dai            |  da + i
+dagli          |  da + gli
+dall           |  da + l'
+dagl           |  da + gll'
+dalla          |  da + la
+dalle          |  da + le
+di             |  of
+del            |  di + il
+dello          |  di + lo
+dei            |  di + i
+degli          |  di + gli
+dell           |  di + l'
+degl           |  di + gl'
+della          |  di + la
+delle          |  di + le
+in             |  in
+nel            |  in + el
+nello          |  in + lo
+nei            |  in + i
+negli          |  in + gli
+nell           |  in + l'
+negl           |  in + gl'
+nella          |  in + la
+nelle          |  in + le
+su             |  on
+sul            |  su + il
+sullo          |  su + lo
+sui            |  su + i
+sugli          |  su + gli
+sull           |  su + l'
+sugl           |  su + gl'
+sulla          |  su + la
+sulle          |  su + le
+per            |  through, by
+tra            |  among
+contro         |  against
+io             |  I
+tu             |  thou
+lui            |  he
+lei            |  she
+noi            |  we
+voi            |  you
+loro           |  they
+mio            |  my
+mia            |
+miei           |
+mie            |
+tuo            |
+tua            |
+tuoi           |  thy
+tue            |
+suo            |
+sua            |
+suoi           |  his, her
+sue            |
+nostro         |  our
+nostra         |
+nostri         |
+nostre         |
+vostro         |  your
+vostra         |
+vostri         |
+vostre         |
+mi             |  me
+ti             |  thee
+ci             |  us, there
+vi             |  you, there
+lo             |  him, the
+la             |  her, the
+li             |  them
+le             |  them, the
+gli            |  to him, the
+ne             |  from there etc
+il             |  the
+un             |  a
+uno            |  a
+una            |  a
+ma             |  but
+ed             |  and
+se             |  if
+perché         |  why, because
+anche          |  also
+come           |  how
+dov            |  where (as dov')
+dove           |  where
+che            |  who, that
+chi            |  who
+cui            |  whom
+non            |  not
+più            |  more
+quale          |  who, that
+quanto         |  how much
+quanti         |
+quanta         |
+quante         |
+quello         |  that
+quelli         |
+quella         |
+quelle         |
+questo         |  this
+questi         |
+questa         |
+queste         |
+si             |  yes
+tutto          |  all
+tutti          |  all
+
+               |  single letter forms:
+
+a              |  at
+c              |  as c' for ce or ci
+e              |  and
+i              |  the
+l              |  as l'
+o              |  or
+
+               | forms of avere, to have (not including the infinitive):
+
+ho
+hai
+ha
+abbiamo
+avete
+hanno
+abbia
+abbiate
+abbiano
+avrò
+avrai
+avrà
+avremo
+avrete
+avranno
+avrei
+avresti
+avrebbe
+avremmo
+avreste
+avrebbero
+avevo
+avevi
+aveva
+avevamo
+avevate
+avevano
+ebbi
+avesti
+ebbe
+avemmo
+aveste
+ebbero
+avessi
+avesse
+avessimo
+avessero
+avendo
+avuto
+avuta
+avuti
+avute
+
+               | forms of essere, to be (not including the infinitive):
+sono
+sei

+siamo
+siete
+sia
+siate
+siano
+sarò
+sarai
+sarà
+saremo
+sarete
+saranno
+sarei
+saresti
+sarebbe
+saremmo
+sareste
+sarebbero
+ero
+eri
+era
+eravamo
+eravate
+erano
+fui
+fosti
+fu
+fummo
+foste
+furono
+fossi
+fosse
+fossimo
+fossero
+essendo
+
+               | forms of fare, to do (not including the infinitive, fa, fat-):
+faccio
+fai
+facciamo
+fanno
+faccia
+facciate
+facciano
+farò
+farai
+farà
+faremo
+farete
+faranno
+farei
+faresti
+farebbe
+faremmo
+fareste
+farebbero
+facevo
+facevi
+faceva
+facevamo
+facevate
+facevano
+feci
+facesti
+fece
+facemmo
+faceste
+fecero
+facessi
+facesse
+facessimo
+facessero
+facendo
+
+               | forms of stare, to be (not including the infinitive):
+sto
+stai
+sta
+stiamo
+stanno
+stia
+stiate
+stiano
+starò
+starai
+starà
+staremo
+starete
+staranno
+starei
+staresti
+starebbe
+staremmo
+stareste
+starebbero
+stavo
+stavi
+stava
+stavamo
+stavate
+stavano
+stetti
+stesti
+stette
+stemmo
+steste
+stettero
+stessi
+stesse
+stessimo
+stessero
+''')
+
+js_stemmer = u"""
+var JSX={};(function(k){function l(b,e){var a=function(){};a.prototype=e.prototype;var c=new a;for(var d in b){b[d].prototype=c}}function K(c,b){for(var a in b.prototype)if(b.prototype.hasOwnProperty(a))c.prototype[a]=b.prototype[a]}function e(a,b,d){function c(a,b,c){delete a[b];a[b]=c;return c}Object.defineProperty(a,b,{get:function(){return c(a,b,d())},set:function(d){c(a,b,d)},enumerable:true,configurable:true})}function L(a,b,c){return a[b]=a[b]/c|0}var r=parseInt;var B=parseFloat;function M(a){return a!==a}var z=isFinite;var y=encodeURIComponent;var x=decodeURIComponent;var w=encodeURI;var u=decodeURI;var t=Object.prototype.toString;var C=Object.prototype.hasOwnProperty;function j(){}k.require=function(b){var a=q[b];return a!==undefined?a:null};k.profilerIsRunning=function(){return j.getResults!=null};k.getProfileResults=function(){return(j.getResults||function(){return{}})()};k.postProfileResults=function(a,b){if(j.postResults==null)throw new Error('profiler has not been turned on');return j.postResults(a,b)};k.resetProfileResults=function(){if(j.resetResults==null)throw new Error('profiler has not been turned on');return j.resetResults()};k.DEBUG=false;function s(){};l([s],Error);function a(a,b,c){this.F=a.length;this.K=a;this.L=b;this.I=c;this.H=null;this.P=null};l([a],Object);function p(){};l([p],Object);function i(){var a;var b;var c;this.G={};a=this.E='';b=this._=0;c=this.A=a.length;this.D=0;this.C=b;this.B=c};l([i],p);function v(a,b){a.E=b.E;a._=b._;a.A=b.A;a.D=b.D;a.C=b.C;a.B=b.B};function d(b,d,c,e){var a;if(b._>=b.A){return false}a=b.E.charCodeAt(b._);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._++;return true};function m(b,d,c,e){var a;if(b._<=b.D){return false}a=b.E.charCodeAt(b._-1);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._--;return true};function h(a,d,c,e){var b;if(a._>=a.A){return false}b=a.E.charCodeAt(a._);if(b>e||b<c){a._++;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._++;return true}return false};function o(a,b,d){var c;if(a.A-a._<b){return false}if(a.E.slice(c=a._,c+b)!==d){return false}a._+=b;return true};function g(a,b,d){var c;if(a._-a.D<b){return false}if(a.E.slice((c=a._)-b,c)!==d){return false}a._-=b;return true};function n(f,m,p){var b;var d;var e;var n;var g;var k;var l;var i;var h;var c;var a;var j;var o;b=0;d=p;e=f._;n=f.A;g=0;k=0;l=false;while(true){i=b+(d-b>>>1);h=0;c=g<k?g:k;a=m[i];for(j=c;j<a.F;j++){if(e+c===n){h=-1;break}h=f.E.charCodeAt(e+c)-a.K.charCodeAt(j);if(h!==0){break}c++}if(h<0){d=i;k=c}else{b=i;g=c}if(d-b<=1){if(b>0){break}if(d===b){break}if(l){break}l=true}}while(true){a=m[b];if(g>=a.F){f._=e+a.F|0;if(a.H==null){return a.I}o=a.H(a.P);f._=e+a.F|0;if(o){return a.I}}b=a.L;if(b<0){return 0}}return-1};function f(d,m,p){var b;var g;var e;var n;var f;var k;var l;var i;var h;var c;var a;var j;var o;b=0;g=p;e=d._;n=d.D;f=0;k=0;l=false;while(true){i=b+(g-b>>1);h=0;c=f<k?f:k;a=m[i];for(j=a.F-1-c;j>=0;j--){if(e-c===n){h=-1;break}h=d.E.charCodeAt(e-1-c)-a.K.charCodeAt(j);if(h!==0){break}c++}if(h<0){g=i;k=c}else{b=i;f=c}if(g-b<=1){if(b>0){break}if(g===b){break}if(l){break}l=true}}while(true){a=m[b];if(f>=a.F){d._=e-a.F|0;if(a.H==null){return a.I}o=a.H(d);d._=e-a.F|0;if(o){return a.I}}b=a.L;if(b<0){return 0}}return-1};function D(a,b,d,e){var c;c=e.length-(d-b);a.E=a.E.slice(0,b)+e+a.E.slice(d);a.A+=c|0;if(a._>=d){a._+=c|0}else if(a._>b){a._=b}return c|0};function c(a,f){var b;var c;var d;var e;b=false;if((c=a.C)<0||c>(d=a.B)||d>(e=a.A)||e>a.E.length?false:true){D(a,a.C,a.B,f);b=true}return b};i.prototype.J=function(){return false};i.prototype.a=function(b){var a;var c;var d;var e;a=this.G['.'+b];if(a==null){c=this.E=b;d=this._=0;e=this.A=c.length;this.D=0;this.C=d;this.B=e;this.J();a=this.E;this.G['.'+b]=a}return a};i.prototype.stemWord=i.prototype.a;i.prototype.b=function(e){var d;var b;var c;var a;var f;var g;var h;d=[];for(b=0;b<e.length;b++){c=e[b];a=this.G['.'+c];if(a==null){f=this.E=c;g=this._=0;h=this.A=f.length;this.D=0;this.C=g;this.B=h;this.J();a=this.E;this.G['.'+c]=a}d.push(a)}return d};i.prototype.stemWords=i.prototype.b;function b(){i.call(this);this.I_p2=0;this.I_p1=0;this.I_pV=0};l([b],i);b.prototype.M=function(a){this.I_p2=a.I_p2;this.I_p1=a.I_p1;this.I_pV=a.I_pV;v(this,a)};b.prototype.copy_from=b.prototype.M;b.prototype.W=function(){var e;var p;var q;var l;var a;var k;var f;var g;var h;var i;var j;var m;p=this._;b:while(true){q=this._;f=true;a:while(f===true){f=false;this.C=this._;e=n(this,b.a_0,7);if(e===0){break a}this.B=this._;switch(e){case 0:break a;case 1:if(!c(this,'à')){return false}break;case 2:if(!c(this,'è')){return false}break;case 3:if(!c(this,'ì')){return false}break;case 4:if(!c(this,'ò')){return false}break;case 5:if(!c(this,'ù')){return false}break;case 6:if(!c(this,'qU')){return false}break;case 7:if(this._>=this.A){break a}this._++;break}continue b}this._=q;break b}this._=p;b:while(true){l=this._;g=true;d:while(g===true){g=false;e:while(true){a=this._;h=true;a:while(h===true){h=false;if(!d(this,b.g_v,97,249)){break a}this.C=this._;i=true;f:while(i===true){i=false;k=this._;j=true;c:while(j===true){j=false;if(!o(this,1,'u')){break c}this.B=this._;if(!d(this,b.g_v,97,249)){break c}if(!c(this,'U')){return false}break f}this._=k;if(!o(this,1,'i')){break a}this.B=this._;if(!d(this,b.g_v,97,249)){break a}if(!c(this,'I')){return false}}this._=a;break e}m=this._=a;if(m>=this.A){break d}this._++}continue b}this._=l;break b}return true};b.prototype.r_prelude=b.prototype.W;function G(a){var e;var q;var r;var m;var f;var l;var g;var h;var i;var j;var k;var p;q=a._;b:while(true){r=a._;g=true;a:while(g===true){g=false;a.C=a._;e=n(a,b.a_0,7);if(e===0){break a}a.B=a._;switch(e){case 0:break a;case 1:if(!c(a,'à')){return false}break;case 2:if(!c(a,'è')){return false}break;case 3:if(!c(a,'ì')){return false}break;case 4:if(!c(a,'ò')){return false}break;case 5:if(!c(a,'ù')){return false}break;case 6:if(!c(a,'qU')){return false}break;case 7:if(a._>=a.A){break a}a._++;break}continue b}a._=r;break b}a._=q;b:while(true){m=a._;h=true;d:while(h===true){h=false;e:while(true){f=a._;i=true;a:while(i===true){i=false;if(!d(a,b.g_v,97,249)){break a}a.C=a._;j=true;f:while(j===true){j=false;l=a._;k=true;c:while(k===true){k=false;if(!o(a,1,'u')){break c}a.B=a._;if(!d(a,b.g_v,97,249)){break c}if(!c(a,'U')){return false}break f}a._=l;if(!o(a,1,'i')){break a}a.B=a._;if(!d(a,b.g_v,97,249)){break a}if(!c(a,'I')){return false}}a._=f;break e}p=a._=f;if(p>=a.A){break d}a._++}continue b}a._=m;break b}return true};b.prototype.U=function(){var u;var w;var x;var y;var t;var l;var e;var f;var g;var i;var c;var j;var k;var a;var m;var n;var o;var p;var q;var r;var s;var v;this.I_pV=s=this.A;this.I_p1=s;this.I_p2=s;u=this._;l=true;a:while(l===true){l=false;e=true;g:while(e===true){e=false;w=this._;f=true;b:while(f===true){f=false;if(!d(this,b.g_v,97,249)){break b}g=true;f:while(g===true){g=false;x=this._;i=true;c:while(i===true){i=false;if(!h(this,b.g_v,97,249)){break c}d:while(true){c=true;e:while(c===true){c=false;if(!d(this,b.g_v,97,249)){break e}break d}if(this._>=this.A){break c}this._++}break f}this._=x;if(!d(this,b.g_v,97,249)){break b}c:while(true){j=true;d:while(j===true){j=false;if(!h(this,b.g_v,97,249)){break d}break c}if(this._>=this.A){break b}this._++}}break g}this._=w;if(!h(this,b.g_v,97,249)){break a}k=true;c:while(k===true){k=false;y=this._;a=true;b:while(a===true){a=false;if(!h(this,b.g_v,97,249)){break b}e:while(true){m=true;d:while(m===true){m=false;if(!d(this,b.g_v,97,249)){break d}break e}if(this._>=this.A){break b}this._++}break c}this._=y;if(!d(this,b.g_v,97,249)){break a}if(this._>=this.A){break a}this._++}}this.I_pV=this._}v=this._=u;t=v;n=true;a:while(n===true){n=false;b:while(true){o=true;c:while(o===true){o=false;if(!d(this,b.g_v,97,249)){break c}break b}if(this._>=this.A){break a}this._++}b:while(true){p=true;c:while(p===true){p=false;if(!h(this,b.g_v,97,249)){break c}break b}if(this._>=this.A){break a}this._++}this.I_p1=this._;b:while(true){q=true;c:while(q===true){q=false;if(!d(this,b.g_v,97,249)){break c}break b}if(this._>=this.A){break a}this._++}c:while(true){r=true;b:while(r===true){r=false;if(!h(this,b.g_v,97,249)){break b}break c}if(this._>=this.A){break a}this._++}this.I_p2=this._}this._=t;return true};b.prototype.r_mark_regions=b.prototype.U;function H(a){var x;var y;var z;var u;var v;var l;var e;var f;var g;var i;var j;var k;var c;var m;var n;var o;var p;var q;var r;var s;var t;var w;a.I_pV=t=a.A;a.I_p1=t;a.I_p2=t;x=a._;l=true;a:while(l===true){l=false;e=true;g:while(e===true){e=false;y=a._;f=true;b:while(f===true){f=false;if(!d(a,b.g_v,97,249)){break b}g=true;f:while(g===true){g=false;z=a._;i=true;c:while(i===true){i=false;if(!h(a,b.g_v,97,249)){break c}d:while(true){j=true;e:while(j===true){j=false;if(!d(a,b.g_v,97,249)){break e}break d}if(a._>=a.A){break c}a._++}break f}a._=z;if(!d(a,b.g_v,97,249)){break b}c:while(true){k=true;d:while(k===true){k=false;if(!h(a,b.g_v,97,249)){break d}break c}if(a._>=a.A){break b}a._++}}break g}a._=y;if(!h(a,b.g_v,97,249)){break a}c=true;c:while(c===true){c=false;u=a._;m=true;b:while(m===true){m=false;if(!h(a,b.g_v,97,249)){break b}e:while(true){n=true;d:while(n===true){n=false;if(!d(a,b.g_v,97,249)){break d}break e}if(a._>=a.A){break b}a._++}break c}a._=u;if(!d(a,b.g_v,97,249)){break a}if(a._>=a.A){break a}a._++}}a.I_pV=a._}w=a._=x;v=w;o=true;a:while(o===true){o=false;b:while(true){p=true;c:while(p===true){p=false;if(!d(a,b.g_v,97,249)){break c}break b}if(a._>=a.A){break a}a._++}b:while(true){q=true;c:while(q===true){q=false;if(!h(a,b.g_v,97,249)){break c}break b}if(a._>=a.A){break a}a._++}a.I_p1=a._;b:while(true){r=true;c:while(r===true){r=false;if(!d(a,b.g_v,97,249)){break c}break b}if(a._>=a.A){break a}a._++}c:while(true){s=true;b:while(s===true){s=false;if(!h(a,b.g_v,97,249)){break b}break c}if(a._>=a.A){break a}a._++}a.I_p2=a._}a._=v;return true};b.prototype.V=function(){var a;var e;var d;b:while(true){e=this._;d=true;a:while(d===true){d=false;this.C=this._;a=n(this,b.a_1,3);if(a===0){break a}this.B=this._;switch(a){case 0:break a;case 1:if(!c(this,'i')){return false}break;case 2:if(!c(this,'u')){return false}break;case 3:if(this._>=this.A){break a}this._++;break}continue b}this._=e;break b}return true};b.prototype.r_postlude=b.prototype.V;function I(a){var d;var f;var e;b:while(true){f=a._;e=true;a:while(e===true){e=false;a.C=a._;d=n(a,b.a_1,3);if(d===0){break a}a.B=a._;switch(d){case 0:break a;case 1:if(!c(a,'i')){return false}break;case 2:if(!c(a,'u')){return false}break;case 3:if(a._>=a.A){break a}a._++;break}continue b}a._=f;break b}return true};b.prototype.S=function(){return!(this.I_pV<=this._)?false:true};b.prototype.r_RV=b.prototype.S;b.prototype.Q=function(){return!(this.I_p1<=this._)?false:true};b.prototype.r_R1=b.prototype.Q;b.prototype.R=function(){return!(this.I_p2<=this._)?false:true};b.prototype.r_R2=b.prototype.R;b.prototype.T=function(){var a;this.B=this._;if(f(this,b.a_2,37)===0){return false}this.C=this._;a=f(this,b.a_3,5);if(a===0){return false}if(!(!(this.I_pV<=this._)?false:true)){return false}switch(a){case 0:return false;case 1:if(!c(this,'')){return false}break;case 2:if(!c(this,'e')){return false}break}return true};b.prototype.r_attached_pronoun=b.prototype.T;function J(a){var d;a.B=a._;if(f(a,b.a_2,37)===0){return false}a.C=a._;d=f(a,b.a_3,5);if(d===0){return false}if(!(!(a.I_pV<=a._)?false:true)){return false}switch(d){case 0:return false;case 1:if(!c(a,'')){return false}break;case 2:if(!c(a,'e')){return false}break}return true};b.prototype.X=function(){var a;var j;var d;var h;var e;var k;var i;var l;var m;var o;var p;var q;var r;var n;this.B=this._;a=f(this,b.a_6,51);if(a===0){return false}this.C=this._;switch(a){case 0:return false;case 1:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'')){return false}break;case 2:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'')){return false}j=this.A-this._;k=true;a:while(k===true){k=false;this.B=this._;if(!g(this,2,'ic')){this._=this.A-j;break a}this.C=o=this._;if(!(!(this.I_p2<=o)?false:true)){this._=this.A-j;break a}if(!c(this,'')){return false}}break;case 3:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'log')){return false}break;case 4:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'u')){return false}break;case 5:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'ente')){return false}break;case 6:if(!(!(this.I_pV<=this._)?false:true)){return false}if(!c(this,'')){return false}break;case 7:if(!(!(this.I_p1<=this._)?false:true)){return false}if(!c(this,'')){return false}d=this.A-this._;i=true;a:while(i===true){i=false;this.B=this._;a=f(this,b.a_4,4);if(a===0){this._=this.A-d;break a}this.C=p=this._;if(!(!(this.I_p2<=p)?false:true)){this._=this.A-d;break a}if(!c(this,'')){return false}switch(a){case 0:this._=this.A-d;break a;case 1:this.B=this._;if(!g(this,2,'at')){this._=this.A-d;break a}this.C=q=this._;if(!(!(this.I_p2<=q)?false:true)){this._=this.A-d;break a}if(!c(this,'')){return false}break}}break;case 8:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'')){return false}h=this.A-this._;l=true;a:while(l===true){l=false;this.B=this._;a=f(this,b.a_5,3);if(a===0){this._=this.A-h;break a}this.C=this._;switch(a){case 0:this._=this.A-h;break a;case 1:if(!(!(this.I_p2<=this._)?false:true)){this._=this.A-h;break a}if(!c(this,'')){return false}break}}break;case 9:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'')){return false}e=this.A-this._;m=true;a:while(m===true){m=false;this.B=this._;if(!g(this,2,'at')){this._=this.A-e;break a}this.C=r=this._;if(!(!(this.I_p2<=r)?false:true)){this._=this.A-e;break a}if(!c(this,'')){return false}this.B=this._;if(!g(this,2,'ic')){this._=this.A-e;break a}this.C=n=this._;if(!(!(this.I_p2<=n)?false:true)){this._=this.A-e;break a}if(!c(this,'')){return false}}break}return true};b.prototype.r_standard_suffix=b.prototype.X;function F(a){var d;var k;var e;var i;var h;var l;var j;var m;var n;var p;var q;var r;var s;var o;a.B=a._;d=f(a,b.a_6,51);if(d===0){return false}a.C=a._;switch(d){case 0:return false;case 1:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'')){return false}break;case 2:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'')){return false}k=a.A-a._;l=true;a:while(l===true){l=false;a.B=a._;if(!g(a,2,'ic')){a._=a.A-k;break a}a.C=p=a._;if(!(!(a.I_p2<=p)?false:true)){a._=a.A-k;break a}if(!c(a,'')){return false}}break;case 3:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'log')){return false}break;case 4:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'u')){return false}break;case 5:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'ente')){return false}break;case 6:if(!(!(a.I_pV<=a._)?false:true)){return false}if(!c(a,'')){return false}break;case 7:if(!(!(a.I_p1<=a._)?false:true)){return false}if(!c(a,'')){return false}e=a.A-a._;j=true;a:while(j===true){j=false;a.B=a._;d=f(a,b.a_4,4);if(d===0){a._=a.A-e;break a}a.C=q=a._;if(!(!(a.I_p2<=q)?false:true)){a._=a.A-e;break a}if(!c(a,'')){return false}switch(d){case 0:a._=a.A-e;break a;case 1:a.B=a._;if(!g(a,2,'at')){a._=a.A-e;break a}a.C=r=a._;if(!(!(a.I_p2<=r)?false:true)){a._=a.A-e;break a}if(!c(a,'')){return false}break}}break;case 8:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'')){return false}i=a.A-a._;m=true;a:while(m===true){m=false;a.B=a._;d=f(a,b.a_5,3);if(d===0){a._=a.A-i;break a}a.C=a._;switch(d){case 0:a._=a.A-i;break a;case 1:if(!(!(a.I_p2<=a._)?false:true)){a._=a.A-i;break a}if(!c(a,'')){return false}break}}break;case 9:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'')){return false}h=a.A-a._;n=true;a:while(n===true){n=false;a.B=a._;if(!g(a,2,'at')){a._=a.A-h;break a}a.C=s=a._;if(!(!(a.I_p2<=s)?false:true)){a._=a.A-h;break a}if(!c(a,'')){return false}a.B=a._;if(!g(a,2,'ic')){a._=a.A-h;break a}a.C=o=a._;if(!(!(a.I_p2<=o)?false:true)){a._=a.A-h;break a}if(!c(a,'')){return false}}break}return true};b.prototype.Y=function(){var d;var e;var a;var g;var h;var i;e=this.A-(g=this._);if(g<this.I_pV){return false}h=this._=this.I_pV;a=this.D;this.D=h;i=this._=this.A-e;this.B=i;d=f(this,b.a_7,87);if(d===0){this.D=a;return false}this.C=this._;switch(d){case 0:this.D=a;return false;case 1:if(!c(this,'')){return false}break}this.D=a;return true};b.prototype.r_verb_suffix=b.prototype.Y;function E(a){var e;var g;var d;var h;var i;var j;g=a.A-(h=a._);if(h<a.I_pV){return false}i=a._=a.I_pV;d=a.D;a.D=i;j=a._=a.A-g;a.B=j;e=f(a,b.a_7,87);if(e===0){a.D=d;return false}a.C=a._;switch(e){case 0:a.D=d;return false;case 1:if(!c(a,'')){return false}break}a.D=d;return true};b.prototype.Z=function(){var a;var d;var e;var f;var h;var i;a=this.A-this._;e=true;a:while(e===true){e=false;this.B=this._;if(!m(this,b.g_AEIO,97,242)){this._=this.A-a;break a}this.C=h=this._;if(!(!(this.I_pV<=h)?false:true)){this._=this.A-a;break a}if(!c(this,'')){return false}this.B=this._;if(!g(this,1,'i')){this._=this.A-a;break a}this.C=i=this._;if(!(!(this.I_pV<=i)?false:true)){this._=this.A-a;break a}if(!c(this,'')){return false}}d=this.A-this._;f=true;a:while(f===true){f=false;this.B=this._;if(!g(this,1,'h')){this._=this.A-d;break a}this.C=this._;if(!m(this,b.g_CG,99,103)){this._=this.A-d;break a}if(!(!(this.I_pV<=this._)?false:true)){this._=this.A-d;break a}if(!c(this,'')){return false}}return true};b.prototype.r_vowel_suffix=b.prototype.Z;function A(a){var d;var e;var f;var h;var i;var j;d=a.A-a._;f=true;a:while(f===true){f=false;a.B=a._;if(!m(a,b.g_AEIO,97,242)){a._=a.A-d;break a}a.C=i=a._;if(!(!(a.I_pV<=i)?false:true)){a._=a.A-d;break a}if(!c(a,'')){return false}a.B=a._;if(!g(a,1,'i')){a._=a.A-d;break a}a.C=j=a._;if(!(!(a.I_pV<=j)?false:true)){a._=a.A-d;break a}if(!c(a,'')){return false}}e=a.A-a._;h=true;a:while(h===true){h=false;a.B=a._;if(!g(a,1,'h')){a._=a.A-e;break a}a.C=a._;if(!m(a,b.g_CG,99,103)){a._=a.A-e;break a}if(!(!(a.I_pV<=a._)?false:true)){a._=a.A-e;break a}if(!c(a,'')){return false}}return true};b.prototype.J=function(){var l;var i;var j;var k;var m;var n;var b;var c;var d;var e;var a;var f;var g;var h;var p;var q;var r;var s;var t;var u;var o;l=this._;b=true;a:while(b===true){b=false;if(!G(this)){break a}}p=this._=l;i=p;c=true;a:while(c===true){c=false;if(!H(this)){break a}}q=this._=i;this.D=q;s=this._=r=this.A;j=r-s;d=true;a:while(d===true){d=false;if(!J(this)){break a}}u=this._=(t=this.A)-j;k=t-u;e=true;a:while(e===true){e=false;a=true;b:while(a===true){a=false;m=this.A-this._;f=true;c:while(f===true){f=false;if(!F(this)){break c}break b}this._=this.A-m;if(!E(this)){break a}}}this._=this.A-k;g=true;a:while(g===true){g=false;if(!A(this)){break a}}o=this._=this.D;n=o;h=true;a:while(h===true){h=false;if(!I(this)){break a}}this._=n;return true};b.prototype.stem=b.prototype.J;b.prototype.N=function(a){return a instanceof b};b.prototype.equals=b.prototype.N;b.prototype.O=function(){var c;var a;var b;var d;c='ItalianStemmer';a=0;for(b=0;b<c.length;b++){d=c.charCodeAt(b);a=(a<<5)-a+d;a=a&a}return a|0};b.prototype.hashCode=b.prototype.O;b.serialVersionUID=1;e(b,'methodObject',function(){return new b});e(b,'a_0',function(){return[new a('',-1,7),new a('qu',0,6),new a('á',0,1),new a('é',0,2),new a('í',0,3),new a('ó',0,4),new a('ú',0,5)]});e(b,'a_1',function(){return[new a('',-1,3),new a('I',0,1),new a('U',0,2)]});e(b,'a_2',function(){return[new a('la',-1,-1),new a('cela',0,-1),new a('gliela',0,-1),new a('mela',0,-1),new a('tela',0,-1),new a('vela',0,-1),new a('le',-1,-1),new a('cele',6,-1),new a('gliele',6,-1),new a('mele',6,-1),new a('tele',6,-1),new a('vele',6,-1),new a('ne',-1,-1),new a('cene',12,-1),new a('gliene',12,-1),new a('mene',12,-1),new a('sene',12,-1),new a('tene',12,-1),new a('vene',12,-1),new a('ci',-1,-1),new a('li',-1,-1),new a('celi',20,-1),new a('glieli',20,-1),new a('meli',20,-1),new a('teli',20,-1),new a('veli',20,-1),new a('gli',20,-1),new a('mi',-1,-1),new a('si',-1,-1),new a('ti',-1,-1),new a('vi',-1,-1),new a('lo',-1,-1),new a('celo',31,-1),new a('glielo',31,-1),new a('melo',31,-1),new a('telo',31,-1),new a('velo',31,-1)]});e(b,'a_3',function(){return[new a('ando',-1,1),new a('endo',-1,1),new a('ar',-1,2),new a('er',-1,2),new a('ir',-1,2)]});e(b,'a_4',function(){return[new a('ic',-1,-1),new a('abil',-1,-1),new a('os',-1,-1),new a('iv',-1,1)]});e(b,'a_5',function(){return[new a('ic',-1,1),new a('abil',-1,1),new a('iv',-1,1)]});e(b,'a_6',function(){return[new a('ica',-1,1),new a('logia',-1,3),new a('osa',-1,1),new a('ista',-1,1),new a('iva',-1,9),new a('anza',-1,1),new a('enza',-1,5),new a('ice',-1,1),new a('atrice',7,1),new a('iche',-1,1),new a('logie',-1,3),new a('abile',-1,1),new a('ibile',-1,1),new a('usione',-1,4),new a('azione',-1,2),new a('uzione',-1,4),new a('atore',-1,2),new a('ose',-1,1),new a('ante',-1,1),new a('mente',-1,1),new a('amente',19,7),new a('iste',-1,1),new a('ive',-1,9),new a('anze',-1,1),new a('enze',-1,5),new a('ici',-1,1),new a('atrici',25,1),new a('ichi',-1,1),new a('abili',-1,1),new a('ibili',-1,1),new a('ismi',-1,1),new a('usioni',-1,4),new a('azioni',-1,2),new a('uzioni',-1,4),new a('atori',-1,2),new a('osi',-1,1),new a('anti',-1,1),new a('amenti',-1,6),new a('imenti',-1,6),new a('isti',-1,1),new a('ivi',-1,9),new a('ico',-1,1),new a('ismo',-1,1),new a('oso',-1,1),new a('amento',-1,6),new a('imento',-1,6),new a('ivo',-1,9),new a('ità',-1,8),new a('istà',-1,1),new a('istè',-1,1),new a('istì',-1,1)]});e(b,'a_7',function(){return[new a('isca',-1,1),new a('enda',-1,1),new a('ata',-1,1),new a('ita',-1,1),new a('uta',-1,1),new a('ava',-1,1),new a('eva',-1,1),new a('iva',-1,1),new a('erebbe',-1,1),new a('irebbe',-1,1),new a('isce',-1,1),new a('ende',-1,1),new a('are',-1,1),new a('ere',-1,1),new a('ire',-1,1),new a('asse',-1,1),new a('ate',-1,1),new a('avate',16,1),new a('evate',16,1),new a('ivate',16,1),new a('ete',-1,1),new a('erete',20,1),new a('irete',20,1),new a('ite',-1,1),new a('ereste',-1,1),new a('ireste',-1,1),new a('ute',-1,1),new a('erai',-1,1),new a('irai',-1,1),new a('isci',-1,1),new a('endi',-1,1),new a('erei',-1,1),new a('irei',-1,1),new a('assi',-1,1),new a('ati',-1,1),new a('iti',-1,1),new a('eresti',-1,1),new a('iresti',-1,1),new a('uti',-1,1),new a('avi',-1,1),new a('evi',-1,1),new a('ivi',-1,1),new a('isco',-1,1),new a('ando',-1,1),new a('endo',-1,1),new a('Yamo',-1,1),new a('iamo',-1,1),new a('avamo',-1,1),new a('evamo',-1,1),new a('ivamo',-1,1),new a('eremo',-1,1),new a('iremo',-1,1),new a('assimo',-1,1),new a('ammo',-1,1),new a('emmo',-1,1),new a('eremmo',54,1),new a('iremmo',54,1),new a('immo',-1,1),new a('ano',-1,1),new a('iscano',58,1),new a('avano',58,1),new a('evano',58,1),new a('ivano',58,1),new a('eranno',-1,1),new a('iranno',-1,1),new a('ono',-1,1),new a('iscono',65,1),new a('arono',65,1),new a('erono',65,1),new a('irono',65,1),new a('erebbero',-1,1),new a('irebbero',-1,1),new a('assero',-1,1),new a('essero',-1,1),new a('issero',-1,1),new a('ato',-1,1),new a('ito',-1,1),new a('uto',-1,1),new a('avo',-1,1),new a('evo',-1,1),new a('ivo',-1,1),new a('ar',-1,1),new a('ir',-1,1),new a('erà',-1,1),new a('irà',-1,1),new a('erò',-1,1),new a('irò',-1,1)]});e(b,'g_v',function(){return[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2,1]});e(b,'g_AEIO',function(){return[17,65,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2]});e(b,'g_CG',function(){return[17]});var q={'src/stemmer.jsx':{Stemmer:p},'src/italian-stemmer.jsx':{ItalianStemmer:b}}}(JSX))
+var Stemmer = JSX.require("src/italian-stemmer.jsx").ItalianStemmer;
+"""
+
+
+class SearchItalian(SearchLanguage):
+    lang = 'it'
+    language_name = 'Italian'
+    js_stemmer_code = js_stemmer
+    stopwords = italian_stopwords
+
+    def init(self, options):
+        self.stemmer = snowballstemmer.stemmer('italian')
+
+    def stem(self, word):
+        return self.stemmer.stemWord(word)
diff --git a/sphinx/search/ja.py b/sphinx/search/ja.py
index d5a7b4a..bc308b6 100644
--- a/sphinx/search/ja.py
+++ b/sphinx/search/ja.py
@@ -21,6 +21,8 @@
 import re
 import sys
 
+from six import iteritems
+
 try:
     import MeCab
     native_module = True
@@ -91,14 +93,14 @@
 
 
 class TinySegmenter(object):
-    patterns_ = dict([(re.compile(pattern), value) for pattern, value in {
+    patterns_ = dict([(re.compile(pattern), value) for pattern, value in iteritems({
         u'[一二三四五六七八九十百千万億兆]': u'M',
         u'[一-龠々〆ヵヶ]': u'H',
         u'[ぁ-ん]': u'I',
         u'[ァ-ヴーア-ン゙ー]': u'K',
         u'[a-zA-Za-zA-Z]': u'A',
         u'[0-90-9]': u'N',
-    }.iteritems()])
+    })])
     BIAS__ = -332
     BC1__ = {u'HH':6,u'II':2461,u'KH':406,u'OH':-1378}
     BC2__ = {u'AA':-3267,u'AI':2744,u'AN':-878,u'HH':-4070,u'HM':-1711,u'HN':4012,u'HO':3761,u'IA':1327,u'IH':-1184,u'II':-1332,u'IK':1721,u'IO':5492,u'KI':3831,u'KK':-8741,u'MH':-3132,u'MK':3334,u'OO':-2920}
@@ -145,7 +147,7 @@
 
     # ctype_
     def ctype_(self, char):
-        for pattern, value in self.patterns_.iteritems():
+        for pattern, value in iteritems(self.patterns_):
             if pattern.match(char):
                 return value
         return u'O'
@@ -254,6 +256,7 @@
     complicated.
     """
     lang = 'ja'
+    language_name = 'Japanese'
 
     def init(self, options):
         type = options.get('type', 'default')
diff --git a/sphinx/search/nl.py b/sphinx/search/nl.py
new file mode 100644
index 0000000..f0d612c
--- /dev/null
+++ b/sphinx/search/nl.py
@@ -0,0 +1,130 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.search.nl
+    ~~~~~~~~~~~~~~~~
+
+    Danish search language: includes the JS porter stemmer.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from sphinx.search import SearchLanguage, parse_stop_word
+
+import snowballstemmer
+
+danish_stopwords = parse_stop_word(u'''
+| source: http://snowball.tartarus.org/algorithms/danish/stop.txt
+og           | and
+i            | in
+jeg          | I
+det          | that (dem. pronoun)/it (pers. pronoun)
+at           | that (in front of a sentence)/to (with infinitive)
+en           | a/an
+den          | it (pers. pronoun)/that (dem. pronoun)
+til          | to/at/for/until/against/by/of/into, more
+er           | present tense of "to be"
+som          | who, as
+på           | on/upon/in/on/at/to/after/of/with/for, on
+de           | they
+med          | with/by/in, along
+han          | he
+af           | of/by/from/off/for/in/with/on, off
+for          | at/for/to/from/by/of/ago, in front/before, because
+ikke         | not
+der          | who/which, there/those
+var          | past tense of "to be"
+mig          | me/myself
+sig          | oneself/himself/herself/itself/themselves
+men          | but
+et           | a/an/one, one (number), someone/somebody/one
+har          | present tense of "to have"
+om           | round/about/for/in/a, about/around/down, if
+vi           | we
+min          | my
+havde        | past tense of "to have"
+ham          | him
+hun          | she
+nu           | now
+over         | over/above/across/by/beyond/past/on/about, over/past
+da           | then, when/as/since
+fra          | from/off/since, off, since
+du           | you
+ud           | out
+sin          | his/her/its/one's
+dem          | them
+os           | us/ourselves
+op           | up
+man          | you/one
+hans         | his
+hvor         | where
+eller        | or
+hvad         | what
+skal         | must/shall etc.
+selv         | myself/youself/herself/ourselves etc., even
+her          | here
+alle         | all/everyone/everybody etc.
+vil          | will (verb)
+blev         | past tense of "to stay/to remain/to get/to become"
+kunne        | could
+ind          | in
+når          | when
+være         | present tense of "to be"
+dog          | however/yet/after all
+noget        | something
+ville        | would
+jo           | you know/you see (adv), yes
+deres        | their/theirs
+efter        | after/behind/according to/for/by/from, later/afterwards
+ned          | down
+skulle       | should
+denne        | this
+end          | than
+dette        | this
+mit          | my/mine
+også         | also
+under        | under/beneath/below/during, below/underneath
+have         | have
+dig          | you
+anden        | other
+hende        | her
+mine         | my
+alt          | everything
+meget        | much/very, plenty of
+sit          | his, her, its, one's
+sine         | his, her, its, one's
+vor          | our
+mod          | against
+disse        | these
+hvis         | if
+din          | your/yours
+nogle        | some
+hos          | by/at
+blive        | be/become
+mange        | many
+ad           | by/through
+bliver       | present tense of "to be/to become"
+hendes       | her/hers
+været        | be
+thi          | for (conj)
+jer          | you
+sådan        | such, like this/like that
+''')
+
+js_stemmer = u"""
+var JSX={};(function(m){function n(b,e){var a=function(){};a.prototype=e.prototype;var c=new a;for(var d in b){b[d].prototype=c}}function L(c,b){for(var a in b.prototype)if(b.prototype.hasOwnProperty(a))c.prototype[a]=b.prototype[a]}function e(a,b,d){function c(a,b,c){delete a[b];a[b]=c;return c}Object.defineProperty(a,b,{get:function(){return c(a,b,d())},set:function(d){c(a,b,d)},enumerable:true,configurable:true})}function K(a,b,c){return a[b]=a[b]/c|0}var I=parseInt;var E=parseFloat;function M(a){return a!==a}var B=isFinite;var A=encodeURIComponent;var z=decodeURIComponent;var y=encodeURI;var x=decodeURI;var w=Object.prototype.toString;var C=Object.prototype.hasOwnProperty;function l(){}m.require=function(b){var a=t[b];return a!==undefined?a:null};m.profilerIsRunning=function(){return l.getResults!=null};m.getProfileResults=function(){return(l.getResults||function(){return{}})()};m.postProfileResults=function(a,b){if(l.postResults==null)throw new Error('profiler has not been turned on');return l.postResults(a,b)};m.resetProfileResults=function(){if(l.resetResults==null)throw new Error('profiler has not been turned on');return l.resetResults()};m.DEBUG=false;function v(){};n([v],Error);function c(a,b,c){this.F=a.length;this.K=a;this.L=b;this.I=c;this.H=null;this.P=null};n([c],Object);function s(){};n([s],Object);function g(){var a;var b;var c;this.G={};a=this.D='';b=this._=0;c=this.A=a.length;this.E=0;this.C=b;this.B=c};n([g],s);function D(a,b){a.D=b.D;a._=b._;a.A=b.A;a.E=b.E;a.C=b.C;a.B=b.B};function i(b,d,c,e){var a;if(b._>=b.A){return false}a=b.D.charCodeAt(b._);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._++;return true};function r(a,d,c,e){var b;if(a._>=a.A){return false}b=a.D.charCodeAt(a._);if(b>e||b<c){a._++;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._++;return true}return false};function f(a,d,c,e){var b;if(a._<=a.E){return false}b=a.D.charCodeAt(a._-1);if(b>e||b<c){a._--;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._--;return true}return false};function k(a,b,d){var c;if(a.A-a._<b){return false}if(a.D.slice(c=a._,c+b)!==d){return false}a._+=b;return true};function d(a,b,d){var c;if(a._-a.E<b){return false}if(a.D.slice((c=a._)-b,c)!==d){return false}a._-=b;return true};function q(f,m,p){var b;var d;var e;var n;var g;var k;var l;var i;var h;var c;var a;var j;var o;b=0;d=p;e=f._;n=f.A;g=0;k=0;l=false;while(true){i=b+(d-b>>>1);h=0;c=g<k?g:k;a=m[i];for(j=c;j<a.F;j++){if(e+c===n){h=-1;break}h=f.D.charCodeAt(e+c)-a.K.charCodeAt(j);if(h!==0){break}c++}if(h<0){d=i;k=c}else{b=i;g=c}if(d-b<=1){if(b>0){break}if(d===b){break}if(l){break}l=true}}while(true){a=m[b];if(g>=a.F){f._=e+a.F|0;if(a.H==null){return a.I}o=a.H(a.P);f._=e+a.F|0;if(o){return a.I}}b=a.L;if(b<0){return 0}}return-1};function h(d,m,p){var b;var g;var e;var n;var f;var k;var l;var i;var h;var c;var a;var j;var o;b=0;g=p;e=d._;n=d.E;f=0;k=0;l=false;while(true){i=b+(g-b>>1);h=0;c=f<k?f:k;a=m[i];for(j=a.F-1-c;j>=0;j--){if(e-c===n){h=-1;break}h=d.D.charCodeAt(e-1-c)-a.K.charCodeAt(j);if(h!==0){break}c++}if(h<0){g=i;k=c}else{b=i;f=c}if(g-b<=1){if(b>0){break}if(g===b){break}if(l){break}l=true}}while(true){a=m[b];if(f>=a.F){d._=e-a.F|0;if(a.H==null){return a.I}o=a.H(d);d._=e-a.F|0;if(o){return a.I}}b=a.L;if(b<0){return 0}}return-1};function u(a,b,d,e){var c;c=e.length-(d-b);a.D=a.D.slice(0,b)+e+a.D.slice(d);a.A+=c|0;if(a._>=d){a._+=c|0}else if(a._>b){a._=b}return c|0};function b(a,f){var b;var c;var d;var e;b=false;if((c=a.C)<0||c>(d=a.B)||d>(e=a.A)||e>a.D.length?false:true){u(a,a.C,a.B,f);b=true}return b};g.prototype.J=function(){return false};g.prototype.Z=function(b){var a;var c;var d;var e;a=this.G['.'+b];if(a==null){c=this.D=b;d=this._=0;e=this.A=c.length;this.E=0;this.C=d;this.B=e;this.J();a=this.D;this.G['.'+b]=a}return a};g.prototype.stemWord=g.prototype.Z;g.prototype.a=function(e){var d;var b;var c;var a;var f;var g;var h;d=[];for(b=0;b<e.length;b++){c=e[b];a=this.G['.'+c];if(a==null){f=this.D=c;g=this._=0;h=this.A=f.length;this.E=0;this.C=g;this.B=h;this.J();a=this.D;this.G['.'+c]=a}d.push(a)}return d};g.prototype.stemWords=g.prototype.a;function a(){g.call(this);this.I_p2=0;this.I_p1=0;this.B_e_found=false};n([a],g);a.prototype.M=function(a){this.I_p2=a.I_p2;this.I_p1=a.I_p1;this.B_e_found=a.B_e_found;D(this,a)};a.prototype.copy_from=a.prototype.M;a.prototype.W=function(){var e;var m;var n;var o;var p;var d;var s;var c;var f;var g;var h;var j;var l;var t;var r;m=this._;b:while(true){n=this._;c=true;a:while(c===true){c=false;this.C=this._;e=q(this,a.a_0,11);if(e===0){break a}this.B=this._;switch(e){case 0:break a;case 1:if(!b(this,'a')){return false}break;case 2:if(!b(this,'e')){return false}break;case 3:if(!b(this,'i')){return false}break;case 4:if(!b(this,'o')){return false}break;case 5:if(!b(this,'u')){return false}break;case 6:if(this._>=this.A){break a}this._++;break}continue b}this._=n;break b}t=this._=m;o=t;f=true;a:while(f===true){f=false;this.C=this._;if(!k(this,1,'y')){this._=o;break a}this.B=this._;if(!b(this,'Y')){return false}}a:while(true){p=this._;g=true;d:while(g===true){g=false;e:while(true){d=this._;h=true;b:while(h===true){h=false;if(!i(this,a.g_v,97,232)){break b}this.C=this._;j=true;f:while(j===true){j=false;s=this._;l=true;c:while(l===true){l=false;if(!k(this,1,'i')){break c}this.B=this._;if(!i(this,a.g_v,97,232)){break c}if(!b(this,'I')){return false}break f}this._=s;if(!k(this,1,'y')){break b}this.B=this._;if(!b(this,'Y')){return false}}this._=d;break e}r=this._=d;if(r>=this.A){break d}this._++}continue a}this._=p;break a}return true};a.prototype.r_prelude=a.prototype.W;function F(c){var d;var s;var t;var o;var p;var e;var n;var f;var g;var h;var j;var l;var m;var u;var r;s=c._;b:while(true){t=c._;f=true;a:while(f===true){f=false;c.C=c._;d=q(c,a.a_0,11);if(d===0){break a}c.B=c._;switch(d){case 0:break a;case 1:if(!b(c,'a')){return false}break;case 2:if(!b(c,'e')){return false}break;case 3:if(!b(c,'i')){return false}break;case 4:if(!b(c,'o')){return false}break;case 5:if(!b(c,'u')){return false}break;case 6:if(c._>=c.A){break a}c._++;break}continue b}c._=t;break b}u=c._=s;o=u;g=true;a:while(g===true){g=false;c.C=c._;if(!k(c,1,'y')){c._=o;break a}c.B=c._;if(!b(c,'Y')){return false}}a:while(true){p=c._;h=true;d:while(h===true){h=false;e:while(true){e=c._;j=true;b:while(j===true){j=false;if(!i(c,a.g_v,97,232)){break b}c.C=c._;l=true;f:while(l===true){l=false;n=c._;m=true;c:while(m===true){m=false;if(!k(c,1,'i')){break c}c.B=c._;if(!i(c,a.g_v,97,232)){break c}if(!b(c,'I')){return false}break f}c._=n;if(!k(c,1,'y')){break b}c.B=c._;if(!b(c,'Y')){return false}}c._=e;break e}r=c._=e;if(r>=c.A){break d}c._++}continue a}c._=p;break a}return true};a.prototype.U=function(){var b;var c;var d;var e;var f;var g;this.I_p1=g=this.A;this.I_p2=g;a:while(true){b=true;b:while(b===true){b=false;if(!i(this,a.g_v,97,232)){break b}break a}if(this._>=this.A){return false}this._++}a:while(true){c=true;b:while(c===true){c=false;if(!r(this,a.g_v,97,232)){break b}break a}if(this._>=this.A){return false}this._++}this.I_p1=this._;d=true;a:while(d===true){d=false;if(!(this.I_p1<3)){break a}this.I_p1=3}a:while(true){e=true;b:while(e===true){e=false;if(!i(this,a.g_v,97,232)){break b}break a}if(this._>=this.A){return false}this._++}a:while(true){f=true;b:while(f===true){f=false;if(!r(this,a.g_v,97,232)){break b}break a}if(this._>=this.A){return false}this._++}this.I_p2=this._;return true};a.prototype.r_mark_regions=a.prototype.U;function G(b){var c;var d;var e;var f;var g;var h;b.I_p1=h=b.A;b.I_p2=h;a:while(true){c=true;b:while(c===true){c=false;if(!i(b,a.g_v,97,232)){break b}break a}if(b._>=b.A){return false}b._++}a:while(true){d=true;b:while(d===true){d=false;if(!r(b,a.g_v,97,232)){break b}break a}if(b._>=b.A){return false}b._++}b.I_p1=b._;e=true;a:while(e===true){e=false;if(!(b.I_p1<3)){break a}b.I_p1=3}a:while(true){f=true;b:while(f===true){f=false;if(!i(b,a.g_v,97,232)){break b}break a}if(b._>=b.A){return false}b._++}a:while(true){g=true;b:while(g===true){g=false;if(!r(b,a.g_v,97,232)){break b}break a}if(b._>=b.A){return false}b._++}b.I_p2=b._;return true};a.prototype.V=function(){var c;var e;var d;b:while(true){e=this._;d=true;a:while(d===true){d=false;this.C=this._;c=q(this,a.a_1,3);if(c===0){break a}this.B=this._;switch(c){case 0:break a;case 1:if(!b(this,'y')){return false}break;case 2:if(!b(this,'i')){return false}break;case 3:if(this._>=this.A){break a}this._++;break}continue b}this._=e;break b}return true};a.prototype.r_postlude=a.prototype.V;function H(c){var d;var f;var e;b:while(true){f=c._;e=true;a:while(e===true){e=false;c.C=c._;d=q(c,a.a_1,3);if(d===0){break a}c.B=c._;switch(d){case 0:break a;case 1:if(!b(c,'y')){return false}break;case 2:if(!b(c,'i')){return false}break;case 3:if(c._>=c.A){break a}c._++;break}continue b}c._=f;break b}return true};a.prototype.Q=function(){return!(this.I_p1<=this._)?false:true};a.prototype.r_R1=a.prototype.Q;a.prototype.R=function(){return!(this.I_p2<=this._)?false:true};a.prototype.r_R2=a.prototype.R;a.prototype.Y=function(){var d;var c;d=this.A-this._;if(h(this,a.a_2,3)===0){return false}c=this._=this.A-d;this.B=c;if(c<=this.E){return false}this._--;this.C=this._;return!b(this,'')?false:true};a.prototype.r_undouble=a.prototype.Y;function j(c){var e;var d;e=c.A-c._;if(h(c,a.a_2,3)===0){return false}d=c._=c.A-e;c.B=d;if(d<=c.E){return false}c._--;c.C=c._;return!b(c,'')?false:true};a.prototype.S=function(){var c;var e;this.B_e_found=false;this.B=this._;if(!d(this,1,'e')){return false}this.C=e=this._;if(!(!(this.I_p1<=e)?false:true)){return false}c=this.A-this._;if(!f(this,a.g_v,97,232)){return false}this._=this.A-c;if(!b(this,'')){return false}this.B_e_found=true;return!j(this)?false:true};a.prototype.r_e_ending=a.prototype.S;function o(c){var e;var g;c.B_e_found=false;c.B=c._;if(!d(c,1,'e')){return false}c.C=g=c._;if(!(!(c.I_p1<=g)?false:true)){return false}e=c.A-c._;if(!f(c,a.g_v,97,232)){return false}c._=c.A-e;if(!b(c,'')){return false}c.B_e_found=true;return!j(c)?false:true};a.prototype.T=function(){var e;var g;var c;var h;var i;if(!(!(this.I_p1<=this._)?false:true)){return false}e=this.A-this._;if(!f(this,a.g_v,97,232)){return false}i=this._=(h=this.A)-e;g=h-i;c=true;a:while(c===true){c=false;if(!d(this,3,'gem')){break a}return false}this._=this.A-g;return!b(this,'')?false:!j(this)?false:true};a.prototype.r_en_ending=a.prototype.T;function p(c){var g;var h;var e;var i;var k;if(!(!(c.I_p1<=c._)?false:true)){return false}g=c.A-c._;if(!f(c,a.g_v,97,232)){return false}k=c._=(i=c.A)-g;h=i-k;e=true;a:while(e===true){e=false;if(!d(c,3,'gem')){break a}return false}c._=c.A-h;return!b(c,'')?false:!j(c)?false:true};a.prototype.X=function(){var c;var v;var w;var x;var y;var z;var A;var B;var C;var D;var M;var m;var g;var i;var k;var l;var e;var n;var q;var r;var s;var E;var F;var G;var H;var I;var J;var K;var L;var t;var N;var u;v=this.A-this._;m=true;a:while(m===true){m=false;this.B=this._;c=h(this,a.a_3,5);if(c===0){break a}this.C=this._;switch(c){case 0:break a;case 1:if(!(!(this.I_p1<=this._)?false:true)){break a}if(!b(this,'heid')){return false}break;case 2:if(!p(this)){break a}break;case 3:if(!(!(this.I_p1<=this._)?false:true)){break a}if(!f(this,a.g_v_j,97,232)){break a}if(!b(this,'')){return false}break}}F=this._=(E=this.A)-v;w=E-F;g=true;a:while(g===true){g=false;if(!o(this)){break a}}I=this._=(H=this.A)-w;x=H-I;i=true;a:while(i===true){i=false;this.B=this._;if(!d(this,4,'heid')){break a}this.C=G=this._;if(!(!(this.I_p2<=G)?false:true)){break a}y=this.A-this._;k=true;b:while(k===true){k=false;if(!d(this,1,'c')){break b}break a}this._=this.A-y;if(!b(this,'')){return false}this.B=this._;if(!d(this,2,'en')){break a}this.C=this._;if(!p(this)){break a}}L=this._=(K=this.A)-x;z=K-L;l=true;a:while(l===true){l=false;this.B=this._;c=h(this,a.a_4,6);if(c===0){break a}this.C=this._;switch(c){case 0:break a;case 1:if(!(!(this.I_p2<=this._)?false:true)){break a}if(!b(this,'')){return false}e=true;c:while(e===true){e=false;A=this.A-this._;n=true;b:while(n===true){n=false;this.B=this._;if(!d(this,2,'ig')){break b}this.C=J=this._;if(!(!(this.I_p2<=J)?false:true)){break b}B=this.A-this._;q=true;d:while(q===true){q=false;if(!d(this,1,'e')){break d}break b}this._=this.A-B;if(!b(this,'')){return false}break c}this._=this.A-A;if(!j(this)){break a}}break;case 2:if(!(!(this.I_p2<=this._)?false:true)){break a}C=this.A-this._;r=true;b:while(r===true){r=false;if(!d(this,1,'e')){break b}break a}this._=this.A-C;if(!b(this,'')){return false}break;case 3:if(!(!(this.I_p2<=this._)?false:true)){break a}if(!b(this,'')){return false}if(!o(this)){break a}break;case 4:if(!(!(this.I_p2<=this._)?false:true)){break a}if(!b(this,'')){return false}break;case 5:if(!(!(this.I_p2<=this._)?false:true)){break a}if(!this.B_e_found){break a}if(!b(this,'')){return false}break}}u=this._=(N=this.A)-z;D=N-u;s=true;a:while(s===true){s=false;if(!f(this,a.g_v_I,73,232)){break a}M=this.A-this._;if(h(this,a.a_5,4)===0){break a}if(!f(this,a.g_v,97,232)){break a}t=this._=this.A-M;this.B=t;if(t<=this.E){break a}this._--;this.C=this._;if(!b(this,'')){return false}}this._=this.A-D;return true};a.prototype.r_standard_suffix=a.prototype.X;function J(c){var e;var w;var x;var y;var z;var A;var B;var C;var D;var E;var N;var g;var i;var k;var l;var m;var n;var q;var r;var s;var t;var F;var G;var H;var I;var J;var K;var L;var M;var u;var O;var v;w=c.A-c._;g=true;a:while(g===true){g=false;c.B=c._;e=h(c,a.a_3,5);if(e===0){break a}c.C=c._;switch(e){case 0:break a;case 1:if(!(!(c.I_p1<=c._)?false:true)){break a}if(!b(c,'heid')){return false}break;case 2:if(!p(c)){break a}break;case 3:if(!(!(c.I_p1<=c._)?false:true)){break a}if(!f(c,a.g_v_j,97,232)){break a}if(!b(c,'')){return false}break}}G=c._=(F=c.A)-w;x=F-G;i=true;a:while(i===true){i=false;if(!o(c)){break a}}J=c._=(I=c.A)-x;y=I-J;k=true;a:while(k===true){k=false;c.B=c._;if(!d(c,4,'heid')){break a}c.C=H=c._;if(!(!(c.I_p2<=H)?false:true)){break a}z=c.A-c._;l=true;b:while(l===true){l=false;if(!d(c,1,'c')){break b}break a}c._=c.A-z;if(!b(c,'')){return false}c.B=c._;if(!d(c,2,'en')){break a}c.C=c._;if(!p(c)){break a}}M=c._=(L=c.A)-y;A=L-M;m=true;a:while(m===true){m=false;c.B=c._;e=h(c,a.a_4,6);if(e===0){break a}c.C=c._;switch(e){case 0:break a;case 1:if(!(!(c.I_p2<=c._)?false:true)){break a}if(!b(c,'')){return false}n=true;c:while(n===true){n=false;B=c.A-c._;q=true;b:while(q===true){q=false;c.B=c._;if(!d(c,2,'ig')){break b}c.C=K=c._;if(!(!(c.I_p2<=K)?false:true)){break b}C=c.A-c._;r=true;d:while(r===true){r=false;if(!d(c,1,'e')){break d}break b}c._=c.A-C;if(!b(c,'')){return false}break c}c._=c.A-B;if(!j(c)){break a}}break;case 2:if(!(!(c.I_p2<=c._)?false:true)){break a}D=c.A-c._;s=true;b:while(s===true){s=false;if(!d(c,1,'e')){break b}break a}c._=c.A-D;if(!b(c,'')){return false}break;case 3:if(!(!(c.I_p2<=c._)?false:true)){break a}if(!b(c,'')){return false}if(!o(c)){break a}break;case 4:if(!(!(c.I_p2<=c._)?false:true)){break a}if(!b(c,'')){return false}break;case 5:if(!(!(c.I_p2<=c._)?false:true)){break a}if(!c.B_e_found){break a}if(!b(c,'')){return false}break}}v=c._=(O=c.A)-A;E=O-v;t=true;a:while(t===true){t=false;if(!f(c,a.g_v_I,73,232)){break a}N=c.A-c._;if(h(c,a.a_5,4)===0){break a}if(!f(c,a.g_v,97,232)){break a}u=c._=c.A-N;c.B=u;if(u<=c.E){break a}c._--;c.C=c._;if(!b(c,'')){return false}}c._=c.A-E;return true};a.prototype.J=function(){var f;var g;var h;var b;var a;var c;var d;var i;var j;var e;f=this._;b=true;a:while(b===true){b=false;if(!F(this)){break a}}i=this._=f;g=i;a=true;a:while(a===true){a=false;if(!G(this)){break a}}j=this._=g;this.E=j;this._=this.A;c=true;a:while(c===true){c=false;if(!J(this)){break a}}e=this._=this.E;h=e;d=true;a:while(d===true){d=false;if(!H(this)){break a}}this._=h;return true};a.prototype.stem=a.prototype.J;a.prototype.N=function(b){return b instanceof a};a.prototype.equals=a.prototype.N;a.prototype.O=function(){var c;var a;var b;var d;c='DutchStemmer';a=0;for(b=0;b<c.length;b++){d=c.charCodeAt(b);a=(a<<5)-a+d;a=a&a}return a|0};a.prototype.hashCode=a.prototype.O;a.serialVersionUID=1;e(a,'methodObject',function(){return new a});e(a,'a_0',function(){return[new c('',-1,6),new c('á',0,1),new c('ä',0,1),new c('é',0,2),new c('ë',0,2),new c('í',0,3),new c('ï',0,3),new c('ó',0,4),new c('ö',0,4),new c('ú',0,5),new c('ü',0,5)]});e(a,'a_1',function(){return[new c('',-1,3),new c('I',0,2),new c('Y',0,1)]});e(a,'a_2',function(){return[new c('dd',-1,-1),new c('kk',-1,-1),new c('tt',-1,-1)]});e(a,'a_3',function(){return[new c('ene',-1,2),new c('se',-1,3),new c('en',-1,2),new c('heden',2,1),new c('s',-1,3)]});e(a,'a_4',function(){return[new c('end',-1,1),new c('ig',-1,2),new c('ing',-1,1),new c('lijk',-1,3),new c('baar',-1,4),new c('bar',-1,5)]});e(a,'a_5',function(){return[new c('aa',-1,-1),new c('ee',-1,-1),new c('oo',-1,-1),new c('uu',-1,-1)]});e(a,'g_v',function(){return[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128]});e(a,'g_v_I',function(){return[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128]});e(a,'g_v_j',function(){return[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128]});var t={'src/stemmer.jsx':{Stemmer:s},'src/dutch-stemmer.jsx':{DutchStemmer:a}}}(JSX))
+var Stemmer = JSX.require("src/dutch-stemmer.jsx").DutchStemmer;
+"""
+
+
+class SearchDutch(SearchLanguage):
+    lang = 'nl'
+    language_name = 'Dutch'
+    js_stemmer_code = js_stemmer
+    stopwords = danish_stopwords
+
+    def init(self, options):
+        self.stemmer = snowballstemmer.stemmer('dutch')
+
+    def stem(self, word):
+        return self.stemmer.stemWord(word)
diff --git a/sphinx/search/no.py b/sphinx/search/no.py
new file mode 100644
index 0000000..b72b4ea
--- /dev/null
+++ b/sphinx/search/no.py
@@ -0,0 +1,212 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.search.no
+    ~~~~~~~~~~~~~~~~
+
+    Norwegian search language: includes the JS Norwegian stemmer.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from sphinx.search import SearchLanguage, parse_stop_word
+
+import snowballstemmer
+
+norwegian_stopwords = parse_stop_word(u'''
+| source: http://snowball.tartarus.org/algorithms/norwegian/stop.txt
+og             | and
+i              | in
+jeg            | I
+det            | it/this/that
+at             | to (w. inf.)
+en             | a/an
+et             | a/an
+den            | it/this/that
+til            | to
+er             | is/am/are
+som            | who/that
+på             | on
+de             | they / you(formal)
+med            | with
+han            | he
+av             | of
+ikke           | not
+ikkje          | not *
+der            | there
+så             | so
+var            | was/were
+meg            | me
+seg            | you
+men            | but
+ett            | one
+har            | have
+om             | about
+vi             | we
+min            | my
+mitt           | my
+ha             | have
+hadde          | had
+hun            | she
+nå             | now
+over           | over
+da             | when/as
+ved            | by/know
+fra            | from
+du             | you
+ut             | out
+sin            | your
+dem            | them
+oss            | us
+opp            | up
+man            | you/one
+kan            | can
+hans           | his
+hvor           | where
+eller          | or
+hva            | what
+skal           | shall/must
+selv           | self (reflective)
+sjøl           | self (reflective)
+her            | here
+alle           | all
+vil            | will
+bli            | become
+ble            | became
+blei           | became *
+blitt          | have become
+kunne          | could
+inn            | in
+når            | when
+være           | be
+kom            | come
+noen           | some
+noe            | some
+ville          | would
+dere           | you
+som            | who/which/that
+deres          | their/theirs
+kun            | only/just
+ja             | yes
+etter          | after
+ned            | down
+skulle         | should
+denne          | this
+for            | for/because
+deg            | you
+si             | hers/his
+sine           | hers/his
+sitt           | hers/his
+mot            | against
+å              | to
+meget          | much
+hvorfor        | why
+dette          | this
+disse          | these/those
+uten           | without
+hvordan        | how
+ingen          | none
+din            | your
+ditt           | your
+blir           | become
+samme          | same
+hvilken        | which
+hvilke         | which (plural)
+sånn           | such a
+inni           | inside/within
+mellom         | between
+vår            | our
+hver           | each
+hvem           | who
+vors           | us/ours
+hvis           | whose
+både           | both
+bare           | only/just
+enn            | than
+fordi          | as/because
+før            | before
+mange          | many
+også           | also
+slik           | just
+vært           | been
+være           | to be
+båe            | both *
+begge          | both
+siden          | since
+dykk           | your *
+dykkar         | yours *
+dei            | they *
+deira          | them *
+deires         | theirs *
+deim           | them *
+di             | your (fem.) *
+då             | as/when *
+eg             | I *
+ein            | a/an *
+eit            | a/an *
+eitt           | a/an *
+elles          | or *
+honom          | he *
+hjå            | at *
+ho             | she *
+hoe            | she *
+henne          | her
+hennar         | her/hers
+hennes         | hers
+hoss           | how *
+hossen         | how *
+ikkje          | not *
+ingi           | noone *
+inkje          | noone *
+korleis        | how *
+korso          | how *
+kva            | what/which *
+kvar           | where *
+kvarhelst      | where *
+kven           | who/whom *
+kvi            | why *
+kvifor         | why *
+me             | we *
+medan          | while *
+mi             | my *
+mine           | my *
+mykje          | much *
+no             | now *
+nokon          | some (masc./neut.) *
+noka           | some (fem.) *
+nokor          | some *
+noko           | some *
+nokre          | some *
+si             | his/hers *
+sia            | since *
+sidan          | since *
+so             | so *
+somt           | some *
+somme          | some *
+um             | about*
+upp            | up *
+vere           | be *
+vore           | was *
+verte          | become *
+vort           | become *
+varte          | became *
+vart           | became *
+''')
+
+js_stemmer = u"""
+var JSX={};(function(g){function i(b,e){var a=function(){};a.prototype=e.prototype;var c=new a;for(var d in b){b[d].prototype=c}}function G(c,b){for(var a in b.prototype)if(b.prototype.hasOwnProperty(a))c.prototype[a]=b.prototype[a]}function e(a,b,d){function c(a,b,c){delete a[b];a[b]=c;return c}Object.defineProperty(a,b,{get:function(){return c(a,b,d())},set:function(d){c(a,b,d)},enumerable:true,configurable:true})}function H(a,b,c){return a[b]=a[b]/c|0}var B=parseInt;var q=parseFloat;function I(a){return a!==a}var y=isFinite;var x=encodeURIComponent;var w=decodeURIComponent;var u=encodeURI;var t=decodeURI;var s=Object.prototype.toString;var r=Object.prototype.hasOwnProperty;function h(){}g.require=function(b){var a=m[b];return a!==undefined?a:null};g.profilerIsRunning=function(){return h.getResults!=null};g.getProfileResults=function(){return(h.getResults||function(){return{}})()};g.postProfileResults=function(a,b){if(h.postResults==null)throw new Error('profiler has not been turned on');return h.postResults(a,b)};g.resetProfileResults=function(){if(h.resetResults==null)throw new Error('profiler has not been turned on');return h.resetResults()};g.DEBUG=false;function A(){};i([A],Error);function b(a,b,c){this.G=a.length;this.R=a;this.U=b;this.J=c;this.I=null;this.V=null};i([b],Object);function j(){};i([j],Object);function d(){var a;var b;var c;this.F={};a=this.C='';b=this._=0;c=this.A=a.length;this.B=0;this.D=b;this.E=c};i([d],j);function v(a,b){a.C=b.C;a._=b._;a.A=b.A;a.B=b.B;a.D=b.D;a.E=b.E};function l(b,d,c,e){var a;if(b._>=b.A){return false}a=b.C.charCodeAt(b._);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._++;return true};function k(b,d,c,e){var a;if(b._<=b.B){return false}a=b.C.charCodeAt(b._-1);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._--;return true};function p(a,d,c,e){var b;if(a._>=a.A){return false}b=a.C.charCodeAt(a._);if(b>e||b<c){a._++;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._++;return true}return false};function o(a,d,c,e){var b;if(a._<=a.B){return false}b=a.C.charCodeAt(a._-1);if(b>e||b<c){a._--;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._--;return true}return false};function n(a,b,d){var c;if(a._-a.B<b){return false}if(a.C.slice((c=a._)-b,c)!==d){return false}a._-=b;return true};function f(d,m,p){var b;var g;var e;var n;var f;var k;var l;var i;var h;var c;var a;var j;var o;b=0;g=p;e=d._;n=d.B;f=0;k=0;l=false;while(true){i=b+(g-b>>1);h=0;c=f<k?f:k;a=m[i];for(j=a.G-1-c;j>=0;j--){if(e-c===n){h=-1;break}h=d.C.charCodeAt(e-1-c)-a.R.charCodeAt(j);if(h!==0){break}c++}if(h<0){g=i;k=c}else{b=i;f=c}if(g-b<=1){if(b>0){break}if(g===b){break}if(l){break}l=true}}while(true){a=m[b];if(f>=a.G){d._=e-a.G|0;if(a.I==null){return a.J}o=a.I(d);d._=e-a.G|0;if(o){return a.J}}b=a.U;if(b<0){return 0}}return-1};function C(a,b,d,e){var c;c=e.length-(d-b);a.C=a.C.slice(0,b)+e+a.C.slice(d);a.A+=c|0;if(a._>=d){a._+=c|0}else if(a._>b){a._=b}return c|0};function c(a,f){var b;var c;var d;var e;b=false;if((c=a.D)<0||c>(d=a.E)||d>(e=a.A)||e>a.C.length?false:true){C(a,a.D,a.E,f);b=true}return b};d.prototype.H=function(){return false};d.prototype.S=function(b){var a;var c;var d;var e;a=this.F['.'+b];if(a==null){c=this.C=b;d=this._=0;e=this.A=c.length;this.B=0;this.D=d;this.E=e;this.H();a=this.C;this.F['.'+b]=a}return a};d.prototype.stemWord=d.prototype.S;d.prototype.T=function(e){var d;var b;var c;var a;var f;var g;var h;d=[];for(b=0;b<e.length;b++){c=e[b];a=this.F['.'+c];if(a==null){f=this.C=c;g=this._=0;h=this.A=f.length;this.B=0;this.D=g;this.E=h;this.H();a=this.C;this.F['.'+c]=a}d.push(a)}return d};d.prototype.stemWords=d.prototype.T;function a(){d.call(this);this.I_x=0;this.I_p1=0};i([a],d);a.prototype.K=function(a){this.I_x=a.I_x;this.I_p1=a.I_p1;v(this,a)};a.prototype.copy_from=a.prototype.K;a.prototype.P=function(){var g;var d;var b;var e;var c;var f;var i;var j;var k;var h;this.I_p1=j=this.A;g=i=this._;b=i+3|0;if(0>b||b>j){return false}h=this._=b;this.I_x=h;this._=g;a:while(true){d=this._;e=true;b:while(e===true){e=false;if(!l(this,a.g_v,97,248)){break b}this._=d;break a}k=this._=d;if(k>=this.A){return false}this._++}a:while(true){c=true;b:while(c===true){c=false;if(!p(this,a.g_v,97,248)){break b}break a}if(this._>=this.A){return false}this._++}this.I_p1=this._;f=true;a:while(f===true){f=false;if(!(this.I_p1<this.I_x)){break a}this.I_p1=this.I_x}return true};a.prototype.r_mark_regions=a.prototype.P;function F(b){var h;var e;var c;var f;var d;var g;var j;var k;var m;var i;b.I_p1=k=b.A;h=j=b._;c=j+3|0;if(0>c||c>k){return false}i=b._=c;b.I_x=i;b._=h;a:while(true){e=b._;f=true;b:while(f===true){f=false;if(!l(b,a.g_v,97,248)){break b}b._=e;break a}m=b._=e;if(m>=b.A){return false}b._++}a:while(true){d=true;b:while(d===true){d=false;if(!p(b,a.g_v,97,248)){break b}break a}if(b._>=b.A){return false}b._++}b.I_p1=b._;g=true;a:while(g===true){g=false;if(!(b.I_p1<b.I_x)){break a}b.I_p1=b.I_x}return true};a.prototype.O=function(){var b;var h;var d;var i;var e;var g;var j;var l;var m;h=this.A-(j=this._);if(j<this.I_p1){return false}l=this._=this.I_p1;d=this.B;this.B=l;m=this._=this.A-h;this.E=m;b=f(this,a.a_0,29);if(b===0){this.B=d;return false}this.D=this._;this.B=d;switch(b){case 0:return false;case 1:if(!c(this,'')){return false}break;case 2:e=true;a:while(e===true){e=false;i=this.A-this._;g=true;b:while(g===true){g=false;if(!k(this,a.g_s_ending,98,122)){break b}break a}this._=this.A-i;if(!n(this,1,'k')){return false}if(!o(this,a.g_v,97,248)){return false}}if(!c(this,'')){return false}break;case 3:if(!c(this,'er')){return false}break}return true};a.prototype.r_main_suffix=a.prototype.O;function E(b){var d;var l;var e;var i;var g;var h;var m;var p;var j;l=b.A-(m=b._);if(m<b.I_p1){return false}p=b._=b.I_p1;e=b.B;b.B=p;j=b._=b.A-l;b.E=j;d=f(b,a.a_0,29);if(d===0){b.B=e;return false}b.D=b._;b.B=e;switch(d){case 0:return false;case 1:if(!c(b,'')){return false}break;case 2:g=true;a:while(g===true){g=false;i=b.A-b._;h=true;b:while(h===true){h=false;if(!k(b,a.g_s_ending,98,122)){break b}break a}b._=b.A-i;if(!n(b,1,'k')){return false}if(!o(b,a.g_v,97,248)){return false}}if(!c(b,'')){return false}break;case 3:if(!c(b,'er')){return false}break}return true};a.prototype.N=function(){var e;var g;var b;var h;var d;var i;var j;var k;var l;e=(h=this.A)-(d=this._);g=h-d;if(d<this.I_p1){return false}i=this._=this.I_p1;b=this.B;this.B=i;j=this._=this.A-g;this.E=j;if(f(this,a.a_1,2)===0){this.B=b;return false}this.D=this._;l=this.B=b;k=this._=this.A-e;if(k<=l){return false}this._--;this.D=this._;return!c(this,'')?false:true};a.prototype.r_consonant_pair=a.prototype.N;function D(b){var i;var j;var d;var g;var e;var k;var l;var m;var h;i=(g=b.A)-(e=b._);j=g-e;if(e<b.I_p1){return false}k=b._=b.I_p1;d=b.B;b.B=k;l=b._=b.A-j;b.E=l;if(f(b,a.a_1,2)===0){b.B=d;return false}b.D=b._;h=b.B=d;m=b._=b.A-i;if(m<=h){return false}b._--;b.D=b._;return!c(b,'')?false:true};a.prototype.Q=function(){var b;var e;var d;var g;var h;var i;e=this.A-(g=this._);if(g<this.I_p1){return false}h=this._=this.I_p1;d=this.B;this.B=h;i=this._=this.A-e;this.E=i;b=f(this,a.a_2,11);if(b===0){this.B=d;return false}this.D=this._;this.B=d;switch(b){case 0:return false;case 1:if(!c(this,'')){return false}break}return true};a.prototype.r_other_suffix=a.prototype.Q;function z(b){var d;var g;var e;var h;var i;var j;g=b.A-(h=b._);if(h<b.I_p1){return false}i=b._=b.I_p1;e=b.B;b.B=i;j=b._=b.A-g;b.E=j;d=f(b,a.a_2,11);if(d===0){b.B=e;return false}b.D=b._;b.B=e;switch(d){case 0:return false;case 1:if(!c(b,'')){return false}break}return true};a.prototype.H=function(){var g;var f;var h;var b;var c;var a;var d;var i;var j;var k;var l;var e;g=this._;b=true;a:while(b===true){b=false;if(!F(this)){break a}}i=this._=g;this.B=i;k=this._=j=this.A;f=j-k;c=true;a:while(c===true){c=false;if(!E(this)){break a}}e=this._=(l=this.A)-f;h=l-e;a=true;a:while(a===true){a=false;if(!D(this)){break a}}this._=this.A-h;d=true;a:while(d===true){d=false;if(!z(this)){break a}}this._=this.B;return true};a.prototype.stem=a.prototype.H;a.prototype.L=function(b){return b instanceof a};a.prototype.equals=a.prototype.L;a.prototype.M=function(){var c;var a;var b;var d;c='NorwegianStemmer';a=0;for(b=0;b<c.length;b++){d=c.charCodeAt(b);a=(a<<5)-a+d;a=a&a}return a|0};a.prototype.hashCode=a.prototype.M;a.serialVersionUID=1;e(a,'methodObject',function(){return new a});e(a,'a_0',function(){return[new b('a',-1,1),new b('e',-1,1),new b('ede',1,1),new b('ande',1,1),new b('ende',1,1),new b('ane',1,1),new b('ene',1,1),new b('hetene',6,1),new b('erte',1,3),new b('en',-1,1),new b('heten',9,1),new b('ar',-1,1),new b('er',-1,1),new b('heter',12,1),new b('s',-1,2),new b('as',14,1),new b('es',14,1),new b('edes',16,1),new b('endes',16,1),new b('enes',16,1),new b('hetenes',19,1),new b('ens',14,1),new b('hetens',21,1),new b('ers',14,1),new b('ets',14,1),new b('et',-1,1),new b('het',25,1),new b('ert',-1,3),new b('ast',-1,1)]});e(a,'a_1',function(){return[new b('dt',-1,-1),new b('vt',-1,-1)]});e(a,'a_2',function(){return[new b('leg',-1,1),new b('eleg',0,1),new b('ig',-1,1),new b('eig',2,1),new b('lig',2,1),new b('elig',4,1),new b('els',-1,1),new b('lov',-1,1),new b('elov',7,1),new b('slov',7,1),new b('hetslov',9,1)]});e(a,'g_v',function(){return[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128]});e(a,'g_s_ending',function(){return[119,125,149,1]});var m={'src/stemmer.jsx':{Stemmer:j},'src/norwegian-stemmer.jsx':{NorwegianStemmer:a}}}(JSX))
+var Stemmer = JSX.require("src/norwegian-stemmer.jsx").NorwegianStemmer;
+"""
+
+
+class SearchNorwegian(SearchLanguage):
+    lang = 'no'
+    language_name = 'Norwegian'
+    js_stemmer_code = js_stemmer
+    stopwords = norwegian_stopwords
+
+    def init(self, options):
+        self.stemmer = snowballstemmer.stemmer('norwegian')
+
+    def stem(self, word):
+        return self.stemmer.stemWord(word)
diff --git a/sphinx/search/pt.py b/sphinx/search/pt.py
new file mode 100644
index 0000000..cb93f26
--- /dev/null
+++ b/sphinx/search/pt.py
@@ -0,0 +1,272 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.search.pt
+    ~~~~~~~~~~~~~~~~
+
+    Portuguese search language: includes the JS Portuguese stemmer.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from sphinx.search import SearchLanguage, parse_stop_word
+
+import snowballstemmer
+
+portuguese_stopwords = parse_stop_word(u'''
+| source: http://snowball.tartarus.org/algorithms/portuguese/stop.txt
+de             |  of, from
+a              |  the; to, at; her
+o              |  the; him
+que            |  who, that
+e              |  and
+do             |  de + o
+da             |  de + a
+em             |  in
+um             |  a
+para           |  for
+  | é          from SER
+com            |  with
+não            |  not, no
+uma            |  a
+os             |  the; them
+no             |  em + o
+se             |  himself etc
+na             |  em + a
+por            |  for
+mais           |  more
+as             |  the; them
+dos            |  de + os
+como           |  as, like
+mas            |  but
+  | foi        from SER
+ao             |  a + o
+ele            |  he
+das            |  de + as
+  | tem        from TER
+à              |  a + a
+seu            |  his
+sua            |  her
+ou             |  or
+  | ser        from SER
+quando         |  when
+muito          |  much
+  | há         from HAV
+nos            |  em + os; us
+já             |  already, now
+  | está       from EST
+eu             |  I
+também         |  also
+só             |  only, just
+pelo           |  per + o
+pela           |  per + a
+até            |  up to
+isso           |  that
+ela            |  he
+entre          |  between
+  | era        from SER
+depois         |  after
+sem            |  without
+mesmo          |  same
+aos            |  a + os
+  | ter        from TER
+seus           |  his
+quem           |  whom
+nas            |  em + as
+me             |  me
+esse           |  that
+eles           |  they
+  | estão      from EST
+você           |  you
+  | tinha      from TER
+  | foram      from SER
+essa           |  that
+num            |  em + um
+nem            |  nor
+suas           |  her
+meu            |  my
+às             |  a + as
+minha          |  my
+  | têm        from TER
+numa           |  em + uma
+pelos          |  per + os
+elas           |  they
+  | havia      from HAV
+  | seja       from SER
+qual           |  which
+  | será       from SER
+nós            |  we
+  | tenho      from TER
+lhe            |  to him, her
+deles          |  of them
+essas          |  those
+esses          |  those
+pelas          |  per + as
+este           |  this
+  | fosse      from SER
+dele           |  of him
+
+ | other words. There are many contractions such as naquele = em+aquele,
+ | mo = me+o, but they are rare.
+ | Indefinite article plural forms are also rare.
+
+tu             |  thou
+te             |  thee
+vocês          |  you (plural)
+vos            |  you
+lhes           |  to them
+meus           |  my
+minhas
+teu            |  thy
+tua
+teus
+tuas
+nosso          | our
+nossa
+nossos
+nossas
+
+dela           |  of her
+delas          |  of them
+
+esta           |  this
+estes          |  these
+estas          |  these
+aquele         |  that
+aquela         |  that
+aqueles        |  those
+aquelas        |  those
+isto           |  this
+aquilo         |  that
+
+               | forms of estar, to be (not including the infinitive):
+estou
+está
+estamos
+estão
+estive
+esteve
+estivemos
+estiveram
+estava
+estávamos
+estavam
+estivera
+estivéramos
+esteja
+estejamos
+estejam
+estivesse
+estivéssemos
+estivessem
+estiver
+estivermos
+estiverem
+
+               | forms of haver, to have (not including the infinitive):
+hei
+há
+havemos
+hão
+houve
+houvemos
+houveram
+houvera
+houvéramos
+haja
+hajamos
+hajam
+houvesse
+houvéssemos
+houvessem
+houver
+houvermos
+houverem
+houverei
+houverá
+houveremos
+houverão
+houveria
+houveríamos
+houveriam
+
+               | forms of ser, to be (not including the infinitive):
+sou
+somos
+são
+era
+éramos
+eram
+fui
+foi
+fomos
+foram
+fora
+fôramos
+seja
+sejamos
+sejam
+fosse
+fôssemos
+fossem
+for
+formos
+forem
+serei
+será
+seremos
+serão
+seria
+seríamos
+seriam
+
+               | forms of ter, to have (not including the infinitive):
+tenho
+tem
+temos
+tém
+tinha
+tínhamos
+tinham
+tive
+teve
+tivemos
+tiveram
+tivera
+tivéramos
+tenha
+tenhamos
+tenham
+tivesse
+tivéssemos
+tivessem
+tiver
+tivermos
+tiverem
+terei
+terá
+teremos
+terão
+teria
+teríamos
+teriam
+''')
+
+js_stemmer = u"""
+
+var JSX={};(function(j){function l(b,e){var a=function(){};a.prototype=e.prototype;var c=new a;for(var d in b){b[d].prototype=c}}function I(c,b){for(var a in b.prototype)if(b.prototype.hasOwnProperty(a))c.prototype[a]=b.prototype[a]}function h(a,b,d){function c(a,b,c){delete a[b];a[b]=c;return c}Object.defineProperty(a,b,{get:function(){return c(a,b,d())},set:function(d){c(a,b,d)},enumerable:true,configurable:true})}function J(a,b,c){return a[b]=a[b]/c|0}var p=parseInt;var z=parseFloat;function K(a){return a!==a}var x=isFinite;var w=encodeURIComponent;var u=decodeURIComponent;var t=encodeURI;var s=decodeURI;var A=Object.prototype.toString;var q=Object.prototype.hasOwnProperty;function k(){}j.require=function(b){var a=o[b];return a!==undefined?a:null};j.profilerIsRunning=function(){return k.getResults!=null};j.getProfileResults=function(){return(k.getResults||function(){return{}})()};j.postProfileResults=function(a,b){if(k.postResults==null)throw new Error('profiler has not been turned on');return k.postResults(a,b)};j.resetProfileResults=function(){if(k.resetResults==null)throw new Error('profiler has not been turned on');return k.resetResults()};j.DEBUG=false;function r(){};l([r],Error);function a(a,b,c){this.F=a.length;this.K=a;this.L=b;this.I=c;this.H=null;this.P=null};l([a],Object);function n(){};l([n],Object);function i(){var a;var b;var c;this.G={};a=this.E='';b=this._=0;c=this.A=a.length;this.D=0;this.B=b;this.C=c};l([i],n);function v(a,b){a.E=b.E;a._=b._;a.A=b.A;a.D=b.D;a.B=b.B;a.C=b.C};function f(b,d,c,e){var a;if(b._>=b.A){return false}a=b.E.charCodeAt(b._);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._++;return true};function g(a,d,c,e){var b;if(a._>=a.A){return false}b=a.E.charCodeAt(a._);if(b>e||b<c){a._++;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._++;return true}return false};function d(a,b,d){var c;if(a._-a.D<b){return false}if(a.E.slice((c=a._)-b,c)!==d){return false}a._-=b;return true};function m(f,m,p){var b;var d;var e;var n;var g;var k;var l;var i;var h;var c;var a;var j;var o;b=0;d=p;e=f._;n=f.A;g=0;k=0;l=false;while(true){i=b+(d-b>>>1);h=0;c=g<k?g:k;a=m[i];for(j=c;j<a.F;j++){if(e+c===n){h=-1;break}h=f.E.charCodeAt(e+c)-a.K.charCodeAt(j);if(h!==0){break}c++}if(h<0){d=i;k=c}else{b=i;g=c}if(d-b<=1){if(b>0){break}if(d===b){break}if(l){break}l=true}}while(true){a=m[b];if(g>=a.F){f._=e+a.F|0;if(a.H==null){return a.I}o=a.H(a.P);f._=e+a.F|0;if(o){return a.I}}b=a.L;if(b<0){return 0}}return-1};function e(d,m,p){var b;var g;var e;var n;var f;var k;var l;var i;var h;var c;var a;var j;var o;b=0;g=p;e=d._;n=d.D;f=0;k=0;l=false;while(true){i=b+(g-b>>1);h=0;c=f<k?f:k;a=m[i];for(j=a.F-1-c;j>=0;j--){if(e-c===n){h=-1;break}h=d.E.charCodeAt(e-1-c)-a.K.charCodeAt(j);if(h!==0){break}c++}if(h<0){g=i;k=c}else{b=i;f=c}if(g-b<=1){if(b>0){break}if(g===b){break}if(l){break}l=true}}while(true){a=m[b];if(f>=a.F){d._=e-a.F|0;if(a.H==null){return a.I}o=a.H(d);d._=e-a.F|0;if(o){return a.I}}b=a.L;if(b<0){return 0}}return-1};function B(a,b,d,e){var c;c=e.length-(d-b);a.E=a.E.slice(0,b)+e+a.E.slice(d);a.A+=c|0;if(a._>=d){a._+=c|0}else if(a._>b){a._=b}return c|0};function c(a,f){var b;var c;var d;var e;b=false;if((c=a.B)<0||c>(d=a.C)||d>(e=a.A)||e>a.E.length?false:true){B(a,a.B,a.C,f);b=true}return b};i.prototype.J=function(){return false};i.prototype.a=function(b){var a;var c;var d;var e;a=this.G['.'+b];if(a==null){c=this.E=b;d=this._=0;e=this.A=c.length;this.D=0;this.B=d;this.C=e;this.J();a=this.E;this.G['.'+b]=a}return a};i.prototype.stemWord=i.prototype.a;i.prototype.b=function(e){var d;var b;var c;var a;var f;var g;var h;d=[];for(b=0;b<e.length;b++){c=e[b];a=this.G['.'+c];if(a==null){f=this.E=c;g=this._=0;h=this.A=f.length;this.D=0;this.B=g;this.C=h;this.J();a=this.E;this.G['.'+c]=a}d.push(a)}return d};i.prototype.stemWords=i.prototype.b;function b(){i.call(this);this.I_p2=0;this.I_p1=0;this.I_pV=0};l([b],i);b.prototype.M=function(a){this.I_p2=a.I_p2;this.I_p1=a.I_p1;this.I_pV=a.I_pV;v(this,a)};b.prototype.copy_from=b.prototype.M;b.prototype.V=function(){var a;var e;var d;b:while(true){e=this._;d=true;a:while(d===true){d=false;this.B=this._;a=m(this,b.a_0,3);if(a===0){break a}this.C=this._;switch(a){case 0:break a;case 1:if(!c(this,'a~')){return false}break;case 2:if(!c(this,'o~')){return false}break;case 3:if(this._>=this.A){break a}this._++;break}continue b}this._=e;break b}return true};b.prototype.r_prelude=b.prototype.V;function E(a){var d;var f;var e;b:while(true){f=a._;e=true;a:while(e===true){e=false;a.B=a._;d=m(a,b.a_0,3);if(d===0){break a}a.C=a._;switch(d){case 0:break a;case 1:if(!c(a,'a~')){return false}break;case 2:if(!c(a,'o~')){return false}break;case 3:if(a._>=a.A){break a}a._++;break}continue b}a._=f;break b}return true};b.prototype.T=function(){var u;var w;var x;var y;var t;var l;var d;var e;var h;var i;var c;var j;var k;var a;var m;var n;var o;var p;var q;var r;var s;var v;this.I_pV=s=this.A;this.I_p1=s;this.I_p2=s;u=this._;l=true;a:while(l===true){l=false;d=true;g:while(d===true){d=false;w=this._;e=true;b:while(e===true){e=false;if(!f(this,b.g_v,97,250)){break b}h=true;f:while(h===true){h=false;x=this._;i=true;c:while(i===true){i=false;if(!g(this,b.g_v,97,250)){break c}d:while(true){c=true;e:while(c===true){c=false;if(!f(this,b.g_v,97,250)){break e}break d}if(this._>=this.A){break c}this._++}break f}this._=x;if(!f(this,b.g_v,97,250)){break b}c:while(true){j=true;d:while(j===true){j=false;if(!g(this,b.g_v,97,250)){break d}break c}if(this._>=this.A){break b}this._++}}break g}this._=w;if(!g(this,b.g_v,97,250)){break a}k=true;c:while(k===true){k=false;y=this._;a=true;b:while(a===true){a=false;if(!g(this,b.g_v,97,250)){break b}e:while(true){m=true;d:while(m===true){m=false;if(!f(this,b.g_v,97,250)){break d}break e}if(this._>=this.A){break b}this._++}break c}this._=y;if(!f(this,b.g_v,97,250)){break a}if(this._>=this.A){break a}this._++}}this.I_pV=this._}v=this._=u;t=v;n=true;a:while(n===true){n=false;b:while(true){o=true;c:while(o===true){o=false;if(!f(this,b.g_v,97,250)){break c}break b}if(this._>=this.A){break a}this._++}b:while(true){p=true;c:while(p===true){p=false;if(!g(this,b.g_v,97,250)){break c}break b}if(this._>=this.A){break a}this._++}this.I_p1=this._;b:while(true){q=true;c:while(q===true){q=false;if(!f(this,b.g_v,97,250)){break c}break b}if(this._>=this.A){break a}this._++}c:while(true){r=true;b:while(r===true){r=false;if(!g(this,b.g_v,97,250)){break b}break c}if(this._>=this.A){break a}this._++}this.I_p2=this._}this._=t;return true};b.prototype.r_mark_regions=b.prototype.T;function F(a){var x;var y;var z;var u;var v;var l;var d;var e;var h;var i;var j;var k;var c;var m;var n;var o;var p;var q;var r;var s;var t;var w;a.I_pV=t=a.A;a.I_p1=t;a.I_p2=t;x=a._;l=true;a:while(l===true){l=false;d=true;g:while(d===true){d=false;y=a._;e=true;b:while(e===true){e=false;if(!f(a,b.g_v,97,250)){break b}h=true;f:while(h===true){h=false;z=a._;i=true;c:while(i===true){i=false;if(!g(a,b.g_v,97,250)){break c}d:while(true){j=true;e:while(j===true){j=false;if(!f(a,b.g_v,97,250)){break e}break d}if(a._>=a.A){break c}a._++}break f}a._=z;if(!f(a,b.g_v,97,250)){break b}c:while(true){k=true;d:while(k===true){k=false;if(!g(a,b.g_v,97,250)){break d}break c}if(a._>=a.A){break b}a._++}}break g}a._=y;if(!g(a,b.g_v,97,250)){break a}c=true;c:while(c===true){c=false;u=a._;m=true;b:while(m===true){m=false;if(!g(a,b.g_v,97,250)){break b}e:while(true){n=true;d:while(n===true){n=false;if(!f(a,b.g_v,97,250)){break d}break e}if(a._>=a.A){break b}a._++}break c}a._=u;if(!f(a,b.g_v,97,250)){break a}if(a._>=a.A){break a}a._++}}a.I_pV=a._}w=a._=x;v=w;o=true;a:while(o===true){o=false;b:while(true){p=true;c:while(p===true){p=false;if(!f(a,b.g_v,97,250)){break c}break b}if(a._>=a.A){break a}a._++}b:while(true){q=true;c:while(q===true){q=false;if(!g(a,b.g_v,97,250)){break c}break b}if(a._>=a.A){break a}a._++}a.I_p1=a._;b:while(true){r=true;c:while(r===true){r=false;if(!f(a,b.g_v,97,250)){break c}break b}if(a._>=a.A){break a}a._++}c:while(true){s=true;b:while(s===true){s=false;if(!g(a,b.g_v,97,250)){break b}break c}if(a._>=a.A){break a}a._++}a.I_p2=a._}a._=v;return true};b.prototype.U=function(){var a;var e;var d;b:while(true){e=this._;d=true;a:while(d===true){d=false;this.B=this._;a=m(this,b.a_1,3);if(a===0){break a}this.C=this._;switch(a){case 0:break a;case 1:if(!c(this,'ã')){return false}break;case 2:if(!c(this,'õ')){return false}break;case 3:if(this._>=this.A){break a}this._++;break}continue b}this._=e;break b}return true};b.prototype.r_postlude=b.prototype.U;function G(a){var d;var f;var e;b:while(true){f=a._;e=true;a:while(e===true){e=false;a.B=a._;d=m(a,b.a_1,3);if(d===0){break a}a.C=a._;switch(d){case 0:break a;case 1:if(!c(a,'ã')){return false}break;case 2:if(!c(a,'õ')){return false}break;case 3:if(a._>=a.A){break a}a._++;break}continue b}a._=f;break b}return true};b.prototype.S=function(){return!(this.I_pV<=this._)?false:true};b.prototype.r_RV=b.prototype.S;b.prototype.Q=function(){return!(this.I_p1<=this._)?false:true};b.prototype.r_R1=b.prototype.Q;b.prototype.R=function(){return!(this.I_p2<=this._)?false:true};b.prototype.r_R2=b.prototype.R;b.prototype.Y=function(){var a;var f;var g;var h;var j;var i;var k;var l;var m;var o;var p;var n;this.C=this._;a=e(this,b.a_5,45);if(a===0){return false}this.B=this._;switch(a){case 0:return false;case 1:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'')){return false}break;case 2:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'log')){return false}break;case 3:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'u')){return false}break;case 4:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'ente')){return false}break;case 5:if(!(!(this.I_p1<=this._)?false:true)){return false}if(!c(this,'')){return false}f=this.A-this._;i=true;a:while(i===true){i=false;this.C=this._;a=e(this,b.a_2,4);if(a===0){this._=this.A-f;break a}this.B=o=this._;if(!(!(this.I_p2<=o)?false:true)){this._=this.A-f;break a}if(!c(this,'')){return false}switch(a){case 0:this._=this.A-f;break a;case 1:this.C=this._;if(!d(this,2,'at')){this._=this.A-f;break a}this.B=p=this._;if(!(!(this.I_p2<=p)?false:true)){this._=this.A-f;break a}if(!c(this,'')){return false}break}}break;case 6:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'')){return false}g=this.A-this._;k=true;a:while(k===true){k=false;this.C=this._;a=e(this,b.a_3,3);if(a===0){this._=this.A-g;break a}this.B=this._;switch(a){case 0:this._=this.A-g;break a;case 1:if(!(!(this.I_p2<=this._)?false:true)){this._=this.A-g;break a}if(!c(this,'')){return false}break}}break;case 7:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'')){return false}h=this.A-this._;l=true;a:while(l===true){l=false;this.C=this._;a=e(this,b.a_4,3);if(a===0){this._=this.A-h;break a}this.B=this._;switch(a){case 0:this._=this.A-h;break a;case 1:if(!(!(this.I_p2<=this._)?false:true)){this._=this.A-h;break a}if(!c(this,'')){return false}break}}break;case 8:if(!(!(this.I_p2<=this._)?false:true)){return false}if(!c(this,'')){return false}j=this.A-this._;m=true;a:while(m===true){m=false;this.C=this._;if(!d(this,2,'at')){this._=this.A-j;break a}this.B=n=this._;if(!(!(this.I_p2<=n)?false:true)){this._=this.A-j;break a}if(!c(this,'')){return false}}break;case 9:if(!(!(this.I_pV<=this._)?false:true)){return false}if(!d(this,1,'e')){return false}if(!c(this,'ir')){return false}break}return true};b.prototype.r_standard_suffix=b.prototype.Y;function H(a){var f;var g;var h;var i;var k;var j;var l;var m;var n;var p;var q;var o;a.C=a._;f=e(a,b.a_5,45);if(f===0){return false}a.B=a._;switch(f){case 0:return false;case 1:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'')){return false}break;case 2:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'log')){return false}break;case 3:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'u')){return false}break;case 4:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'ente')){return false}break;case 5:if(!(!(a.I_p1<=a._)?false:true)){return false}if(!c(a,'')){return false}g=a.A-a._;j=true;a:while(j===true){j=false;a.C=a._;f=e(a,b.a_2,4);if(f===0){a._=a.A-g;break a}a.B=p=a._;if(!(!(a.I_p2<=p)?false:true)){a._=a.A-g;break a}if(!c(a,'')){return false}switch(f){case 0:a._=a.A-g;break a;case 1:a.C=a._;if(!d(a,2,'at')){a._=a.A-g;break a}a.B=q=a._;if(!(!(a.I_p2<=q)?false:true)){a._=a.A-g;break a}if(!c(a,'')){return false}break}}break;case 6:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'')){return false}h=a.A-a._;l=true;a:while(l===true){l=false;a.C=a._;f=e(a,b.a_3,3);if(f===0){a._=a.A-h;break a}a.B=a._;switch(f){case 0:a._=a.A-h;break a;case 1:if(!(!(a.I_p2<=a._)?false:true)){a._=a.A-h;break a}if(!c(a,'')){return false}break}}break;case 7:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'')){return false}i=a.A-a._;m=true;a:while(m===true){m=false;a.C=a._;f=e(a,b.a_4,3);if(f===0){a._=a.A-i;break a}a.B=a._;switch(f){case 0:a._=a.A-i;break a;case 1:if(!(!(a.I_p2<=a._)?false:true)){a._=a.A-i;break a}if(!c(a,'')){return false}break}}break;case 8:if(!(!(a.I_p2<=a._)?false:true)){return false}if(!c(a,'')){return false}k=a.A-a._;n=true;a:while(n===true){n=false;a.C=a._;if(!d(a,2,'at')){a._=a.A-k;break a}a.B=o=a._;if(!(!(a.I_p2<=o)?false:true)){a._=a.A-k;break a}if(!c(a,'')){return false}}break;case 9:if(!(!(a.I_pV<=a._)?false:true)){return false}if(!d(a,1,'e')){return false}if(!c(a,'ir')){return false}break}return true};b.prototype.Z=function(){var d;var f;var a;var g;var h;var i;f=this.A-(g=this._);if(g<this.I_pV){return false}h=this._=this.I_pV;a=this.D;this.D=h;i=this._=this.A-f;this.C=i;d=e(this,b.a_6,120);if(d===0){this.D=a;return false}this.B=this._;switch(d){case 0:this.D=a;return false;case 1:if(!c(this,'')){return false}break}this.D=a;return true};b.prototype.r_verb_suffix=b.prototype.Z;function D(a){var f;var g;var d;var h;var i;var j;g=a.A-(h=a._);if(h<a.I_pV){return false}i=a._=a.I_pV;d=a.D;a.D=i;j=a._=a.A-g;a.C=j;f=e(a,b.a_6,120);if(f===0){a.D=d;return false}a.B=a._;switch(f){case 0:a.D=d;return false;case 1:if(!c(a,'')){return false}break}a.D=d;return true};b.prototype.X=function(){var a;this.C=this._;a=e(this,b.a_7,7);if(a===0){return false}this.B=this._;switch(a){case 0:return false;case 1:if(!(!(this.I_pV<=this._)?false:true)){return false}if(!c(this,'')){return false}break}return true};b.prototype.r_residual_suffix=b.prototype.X;function C(a){var d;a.C=a._;d=e(a,b.a_7,7);if(d===0){return false}a.B=a._;switch(d){case 0:return false;case 1:if(!(!(a.I_pV<=a._)?false:true)){return false}if(!c(a,'')){return false}break}return true};b.prototype.W=function(){var a;var h;var i;var j;var f;var g;var k;var l;this.C=this._;a=e(this,b.a_8,4);if(a===0){return false}this.B=this._;switch(a){case 0:return false;case 1:if(!(!(this.I_pV<=this._)?false:true)){return false}if(!c(this,'')){return false}this.C=this._;f=true;b:while(f===true){f=false;h=this.A-this._;g=true;a:while(g===true){g=false;if(!d(this,1,'u')){break a}this.B=k=this._;i=this.A-k;if(!d(this,1,'g')){break a}this._=this.A-i;break b}this._=this.A-h;if(!d(this,1,'i')){return false}this.B=l=this._;j=this.A-l;if(!d(this,1,'c')){return false}this._=this.A-j}if(!(!(this.I_pV<=this._)?false:true)){return false}if(!c(this,'')){return false}break;case 2:if(!c(this,'c')){return false}break}return true};b.prototype.r_residual_form=b.prototype.W;function y(a){var f;var i;var j;var k;var g;var h;var l;var m;a.C=a._;f=e(a,b.a_8,4);if(f===0){return false}a.B=a._;switch(f){case 0:return false;case 1:if(!(!(a.I_pV<=a._)?false:true)){return false}if(!c(a,'')){return false}a.C=a._;g=true;b:while(g===true){g=false;i=a.A-a._;h=true;a:while(h===true){h=false;if(!d(a,1,'u')){break a}a.B=l=a._;j=a.A-l;if(!d(a,1,'g')){break a}a._=a.A-j;break b}a._=a.A-i;if(!d(a,1,'i')){return false}a.B=m=a._;k=a.A-m;if(!d(a,1,'c')){return false}a._=a.A-k}if(!(!(a.I_pV<=a._)?false:true)){return false}if(!c(a,'')){return false}break;case 2:if(!c(a,'c')){return false}break}return true};b.prototype.J=function(){var q;var n;var o;var p;var r;var s;var t;var u;var v;var b;var e;var f;var g;var a;var h;var i;var j;var k;var l;var w;var x;var z;var A;var B;var I;var J;var K;var m;q=this._;b=true;a:while(b===true){b=false;if(!E(this)){break a}}w=this._=q;n=w;e=true;a:while(e===true){e=false;if(!F(this)){break a}}I=this._=n;this.D=I;K=this._=J=this.A;o=J-K;f=true;b:while(f===true){f=false;g=true;c:while(g===true){g=false;p=this.A-this._;a=true;d:while(a===true){a=false;r=this.A-this._;h=true;a:while(h===true){h=false;s=this.A-this._;i=true;e:while(i===true){i=false;if(!H(this)){break e}break a}this._=this.A-s;if(!D(this)){break d}}B=this._=(A=this.A)-r;t=A-B;j=true;a:while(j===true){j=false;this.C=this._;if(!d(this,1,'i')){break a}this.B=x=this._;u=this.A-x;if(!d(this,1,'c')){break a}z=this._=this.A-u;if(!(!(this.I_pV<=z)?false:true)){break a}if(!c(this,'')){return false}}this._=this.A-t;break c}this._=this.A-p;if(!C(this)){break b}}}this._=this.A-o;k=true;a:while(k===true){k=false;if(!y(this)){break a}}m=this._=this.D;v=m;l=true;a:while(l===true){l=false;if(!G(this)){break a}}this._=v;return true};b.prototype.stem=b.prototype.J;b.prototype.N=function(a){return a instanceof b};b.prototype.equals=b.prototype.N;b.prototype.O=function(){var c;var a;var b;var d;c='PortugueseStemmer';a=0;for(b=0;b<c.length;b++){d=c.charCodeAt(b);a=(a<<5)-a+d;a=a&a}return a|0};b.prototype.hashCode=b.prototype.O;b.serialVersionUID=1;h(b,'methodObject',function(){return new b});h(b,'a_0',function(){return[new a('',-1,3),new a('ã',0,1),new a('õ',0,2)]});h(b,'a_1',function(){return[new a('',-1,3),new a('a~',0,1),new a('o~',0,2)]});h(b,'a_2',function(){return[new a('ic',-1,-1),new a('ad',-1,-1),new a('os',-1,-1),new a('iv',-1,1)]});h(b,'a_3',function(){return[new a('ante',-1,1),new a('avel',-1,1),new a('ível',-1,1)]});h(b,'a_4',function(){return[new a('ic',-1,1),new a('abil',-1,1),new a('iv',-1,1)]});h(b,'a_5',function(){return[new a('ica',-1,1),new a('ância',-1,1),new a('ência',-1,4),new a('ira',-1,9),new a('adora',-1,1),new a('osa',-1,1),new a('ista',-1,1),new a('iva',-1,8),new a('eza',-1,1),new a('logía',-1,2),new a('idade',-1,7),new a('ante',-1,1),new a('mente',-1,6),new a('amente',12,5),new a('ável',-1,1),new a('ível',-1,1),new a('ución',-1,3),new a('ico',-1,1),new a('ismo',-1,1),new a('oso',-1,1),new a('amento',-1,1),new a('imento',-1,1),new a('ivo',-1,8),new a('aça~o',-1,1),new a('ador',-1,1),new a('icas',-1,1),new a('ências',-1,4),new a('iras',-1,9),new a('adoras',-1,1),new a('osas',-1,1),new a('istas',-1,1),new a('ivas',-1,8),new a('ezas',-1,1),new a('logías',-1,2),new a('idades',-1,7),new a('uciones',-1,3),new a('adores',-1,1),new a('antes',-1,1),new a('aço~es',-1,1),new a('icos',-1,1),new a('ismos',-1,1),new a('osos',-1,1),new a('amentos',-1,1),new a('imentos',-1,1),new a('ivos',-1,8)]});h(b,'a_6',function(){return[new a('ada',-1,1),new a('ida',-1,1),new a('ia',-1,1),new a('aria',2,1),new a('eria',2,1),new a('iria',2,1),new a('ara',-1,1),new a('era',-1,1),new a('ira',-1,1),new a('ava',-1,1),new a('asse',-1,1),new a('esse',-1,1),new a('isse',-1,1),new a('aste',-1,1),new a('este',-1,1),new a('iste',-1,1),new a('ei',-1,1),new a('arei',16,1),new a('erei',16,1),new a('irei',16,1),new a('am',-1,1),new a('iam',20,1),new a('ariam',21,1),new a('eriam',21,1),new a('iriam',21,1),new a('aram',20,1),new a('eram',20,1),new a('iram',20,1),new a('avam',20,1),new a('em',-1,1),new a('arem',29,1),new a('erem',29,1),new a('irem',29,1),new a('assem',29,1),new a('essem',29,1),new a('issem',29,1),new a('ado',-1,1),new a('ido',-1,1),new a('ando',-1,1),new a('endo',-1,1),new a('indo',-1,1),new a('ara~o',-1,1),new a('era~o',-1,1),new a('ira~o',-1,1),new a('ar',-1,1),new a('er',-1,1),new a('ir',-1,1),new a('as',-1,1),new a('adas',47,1),new a('idas',47,1),new a('ias',47,1),new a('arias',50,1),new a('erias',50,1),new a('irias',50,1),new a('aras',47,1),new a('eras',47,1),new a('iras',47,1),new a('avas',47,1),new a('es',-1,1),new a('ardes',58,1),new a('erdes',58,1),new a('irdes',58,1),new a('ares',58,1),new a('eres',58,1),new a('ires',58,1),new a('asses',58,1),new a('esses',58,1),new a('isses',58,1),new a('astes',58,1),new a('estes',58,1),new a('istes',58,1),new a('is',-1,1),new a('ais',71,1),new a('eis',71,1),new a('areis',73,1),new a('ereis',73,1),new a('ireis',73,1),new a('áreis',73,1),new a('éreis',73,1),new a('íreis',73,1),new a('ásseis',73,1),new a('ésseis',73,1),new a('ísseis',73,1),new a('áveis',73,1),new a('íeis',73,1),new a('aríeis',84,1),new a('eríeis',84,1),new a('iríeis',84,1),new a('ados',-1,1),new a('idos',-1,1),new a('amos',-1,1),new a('áramos',90,1),new a('éramos',90,1),new a('íramos',90,1),new a('ávamos',90,1),new a('íamos',90,1),new a('aríamos',95,1),new a('eríamos',95,1),new a('iríamos',95,1),new a('emos',-1,1),new a('aremos',99,1),new a('eremos',99,1),new a('iremos',99,1),new a('ássemos',99,1),new a('êssemos',99,1),new a('íssemos',99,1),new a('imos',-1,1),new a('armos',-1,1),new a('ermos',-1,1),new a('irmos',-1,1),new a('ámos',-1,1),new a('arás',-1,1),new a('erás',-1,1),new a('irás',-1,1),new a('eu',-1,1),new a('iu',-1,1),new a('ou',-1,1),new a('ará',-1,1),new a('erá',-1,1),new a('irá',-1,1)]});h(b,'a_7',function(){return[new a('a',-1,1),new a('i',-1,1),new a('o',-1,1),new a('os',-1,1),new a('á',-1,1),new a('í',-1,1),new a('ó',-1,1)]});h(b,'a_8',function(){return[new a('e',-1,1),new a('ç',-1,2),new a('é',-1,1),new a('ê',-1,1)]});h(b,'g_v',function(){return[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,3,19,12,2]});var o={'src/stemmer.jsx':{Stemmer:n},'src/portuguese-stemmer.jsx':{PortugueseStemmer:b}}}(JSX))
+var Stemmer = JSX.require("src/portuguese-stemmer.jsx").PortugueseStemmer;
+"""
+
+
+class SearchPortuguese(SearchLanguage):
+    lang = 'pt'
+    language_name = 'Portuguese'
+    js_stemmer_code = js_stemmer
+    stopwords = portuguese_stopwords
+
+    def init(self, options):
+        self.stemmer = snowballstemmer.stemmer('portuguese')
+
+    def stem(self, word):
+        return self.stemmer.stemWord(word)
diff --git a/sphinx/search/ro.py b/sphinx/search/ro.py
new file mode 100644
index 0000000..c4336f8
--- /dev/null
+++ b/sphinx/search/ro.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.search.ro
+    ~~~~~~~~~~~~~~~~
+
+    Romanian search language: includes the JS Romanian stemmer.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from sphinx.search import SearchLanguage
+
+import snowballstemmer
+
+js_stemmer = u"""
+var JSX={};(function(j){function l(b,e){var a=function(){};a.prototype=e.prototype;var c=new a;for(var d in b){b[d].prototype=c}}function L(c,b){for(var a in b.prototype)if(b.prototype.hasOwnProperty(a))c.prototype[a]=b.prototype[a]}function h(a,b,d){function c(a,b,c){delete a[b];a[b]=c;return c}Object.defineProperty(a,b,{get:function(){return c(a,b,d())},set:function(d){c(a,b,d)},enumerable:true,configurable:true})}function M(a,b,c){return a[b]=a[b]/c|0}var E=parseInt;var C=parseFloat;function N(a){return a!==a}var A=isFinite;var z=encodeURIComponent;var y=decodeURIComponent;var x=encodeURI;var w=decodeURI;var u=Object.prototype.toString;var D=Object.prototype.hasOwnProperty;function k(){}j.require=function(b){var a=r[b];return a!==undefined?a:null};j.profilerIsRunning=function(){return k.getResults!=null};j.getProfileResults=function(){return(k.getResults||function(){return{}})()};j.postProfileResults=function(a,b){if(k.postResults==null)throw new Error('profiler has not been turned on');return k.postResults(a,b)};j.resetProfileResults=function(){if(k.resetResults==null)throw new Error('profiler has not been turned on');return k.resetResults()};j.DEBUG=false;function t(){};l([t],Error);function a(a,b,c){this.F=a.length;this.K=a;this.L=b;this.I=c;this.H=null;this.P=null};l([a],Object);function n(){};l([n],Object);function g(){var a;var b;var c;this.G={};a=this.E='';b=this._=0;c=this.A=a.length;this.D=0;this.B=b;this.C=c};l([g],n);function v(a,b){a.E=b.E;a._=b._;a.A=b.A;a.D=b.D;a.B=b.B;a.C=b.C};function d(b,d,c,e){var a;if(b._>=b.A){return false}a=b.E.charCodeAt(b._);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._++;return true};function e(a,d,c,e){var b;if(a._>=a.A){return false}b=a.E.charCodeAt(a._);if(b>e||b<c){a._++;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._++;return true}return false};function p(a,d,c,e){var b;if(a._<=a.D){return false}b=a.E.charCodeAt(a._-1);if(b>e||b<c){a._--;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._--;return true}return false};function m(a,b,d){var c;if(a.A-a._<b){return false}if(a.E.slice(c=a._,c+b)!==d){return false}a._+=b;return true};function i(a,b,d){var c;if(a._-a.D<b){return false}if(a.E.slice((c=a._)-b,c)!==d){return false}a._-=b;return true};function q(f,m,p){var b;var d;var e;var n;var g;var k;var l;var i;var h;var c;var a;var j;var o;b=0;d=p;e=f._;n=f.A;g=0;k=0;l=false;while(true){i=b+(d-b>>>1);h=0;c=g<k?g:k;a=m[i];for(j=c;j<a.F;j++){if(e+c===n){h=-1;break}h=f.E.charCodeAt(e+c)-a.K.charCodeAt(j);if(h!==0){break}c++}if(h<0){d=i;k=c}else{b=i;g=c}if(d-b<=1){if(b>0){break}if(d===b){break}if(l){break}l=true}}while(true){a=m[b];if(g>=a.F){f._=e+a.F|0;if(a.H==null){return a.I}o=a.H(a.P);f._=e+a.F|0;if(o){return a.I}}b=a.L;if(b<0){return 0}}return-1};function f(d,m,p){var b;var g;var e;var n;var f;var k;var l;var i;var h;var c;var a;var j;var o;b=0;g=p;e=d._;n=d.D;f=0;k=0;l=false;while(true){i=b+(g-b>>1);h=0;c=f<k?f:k;a=m[i];for(j=a.F-1-c;j>=0;j--){if(e-c===n){h=-1;break}h=d.E.charCodeAt(e-1-c)-a.K.charCodeAt(j);if(h!==0){break}c++}if(h<0){g=i;k=c}else{b=i;f=c}if(g-b<=1){if(b>0){break}if(g===b){break}if(l){break}l=true}}while(true){a=m[b];if(f>=a.F){d._=e-a.F|0;if(a.H==null){return a.I}o=a.H(d);d._=e-a.F|0;if(o){return a.I}}b=a.L;if(b<0){return 0}}return-1};function s(a,b,d,e){var c;c=e.length-(d-b);a.E=a.E.slice(0,b)+e+a.E.slice(d);a.A+=c|0;if(a._>=d){a._+=c|0}else if(a._>b){a._=b}return c|0};function c(a,f){var b;var c;var d;var e;b=false;if((c=a.B)<0||c>(d=a.C)||d>(e=a.A)||e>a.E.length?false:true){s(a,a.B,a.C,f);b=true}return b};g.prototype.J=function(){return false};g.prototype.b=function(b){var a;var c;var d;var e;a=this.G['.'+b];if(a==null){c=this.E=b;d=this._=0;e=this.A=c.length;this.D=0;this.B=d;this.C=e;this.J();a=this.E;this.G['.'+b]=a}return a};g.prototype.stemWord=g.prototype.b;g.prototype.c=function(e){var d;var b;var c;var a;var f;var g;var h;d=[];for(b=0;b<e.length;b++){c=e[b];a=this.G['.'+c];if(a==null){f=this.E=c;g=this._=0;h=this.A=f.length;this.D=0;this.B=g;this.C=h;this.J();a=this.E;this.G['.'+c]=a}d.push(a)}return d};g.prototype.stemWords=g.prototype.c;function b(){g.call(this);this.B_standard_suffix_removed=false;this.I_p2=0;this.I_p1=0;this.I_pV=0};l([b],g);b.prototype.M=function(a){this.B_standard_suffix_removed=a.B_standard_suffix_removed;this.I_p2=a.I_p2;this.I_p1=a.I_p1;this.I_pV=a.I_pV;v(this,a)};b.prototype.copy_from=b.prototype.M;b.prototype.W=function(){var i;var a;var j;var e;var f;var g;var h;var k;b:while(true){i=this._;e=true;d:while(e===true){e=false;e:while(true){a=this._;f=true;a:while(f===true){f=false;if(!d(this,b.g_v,97,259)){break a}this.B=this._;g=true;f:while(g===true){g=false;j=this._;h=true;c:while(h===true){h=false;if(!m(this,1,'u')){break c}this.C=this._;if(!d(this,b.g_v,97,259)){break c}if(!c(this,'U')){return false}break f}this._=j;if(!m(this,1,'i')){break a}this.C=this._;if(!d(this,b.g_v,97,259)){break a}if(!c(this,'I')){return false}}this._=a;break e}k=this._=a;if(k>=this.A){break d}this._++}continue b}this._=i;break b}return true};b.prototype.r_prelude=b.prototype.W;function G(a){var j;var e;var k;var f;var g;var h;var i;var l;b:while(true){j=a._;f=true;d:while(f===true){f=false;e:while(true){e=a._;g=true;a:while(g===true){g=false;if(!d(a,b.g_v,97,259)){break a}a.B=a._;h=true;f:while(h===true){h=false;k=a._;i=true;c:while(i===true){i=false;if(!m(a,1,'u')){break c}a.C=a._;if(!d(a,b.g_v,97,259)){break c}if(!c(a,'U')){return false}break f}a._=k;if(!m(a,1,'i')){break a}a.C=a._;if(!d(a,b.g_v,97,259)){break a}if(!c(a,'I')){return false}}a._=e;break e}l=a._=e;if(l>=a.A){break d}a._++}continue b}a._=j;break b}return true};b.prototype.U=function(){var u;var w;var x;var y;var t;var l;var f;var g;var h;var i;var c;var j;var k;var a;var m;var n;var o;var p;var q;var r;var s;var v;this.I_pV=s=this.A;this.I_p1=s;this.I_p2=s;u=this._;l=true;a:while(l===true){l=false;f=true;g:while(f===true){f=false;w=this._;g=true;b:while(g===true){g=false;if(!d(this,b.g_v,97,259)){break b}h=true;f:while(h===true){h=false;x=this._;i=true;c:while(i===true){i=false;if(!e(this,b.g_v,97,259)){break c}d:while(true){c=true;e:while(c===true){c=false;if(!d(this,b.g_v,97,259)){break e}break d}if(this._>=this.A){break c}this._++}break f}this._=x;if(!d(this,b.g_v,97,259)){break b}c:while(true){j=true;d:while(j===true){j=false;if(!e(this,b.g_v,97,259)){break d}break c}if(this._>=this.A){break b}this._++}}break g}this._=w;if(!e(this,b.g_v,97,259)){break a}k=true;c:while(k===true){k=false;y=this._;a=true;b:while(a===true){a=false;if(!e(this,b.g_v,97,259)){break b}e:while(true){m=true;d:while(m===true){m=false;if(!d(this,b.g_v,97,259)){break d}break e}if(this._>=this.A){break b}this._++}break c}this._=y;if(!d(this,b.g_v,97,259)){break a}if(this._>=this.A){break a}this._++}}this.I_pV=this._}v=this._=u;t=v;n=true;a:while(n===true){n=false;b:while(true){o=true;c:while(o===true){o=false;if(!d(this,b.g_v,97,259)){break c}break b}if(this._>=this.A){break a}this._++}b:while(true){p=true;c:while(p===true){p=false;if(!e(this,b.g_v,97,259)){break c}break b}if(this._>=this.A){break a}this._++}this.I_p1=this._;b:while(true){q=true;c:while(q===true){q=false;if(!d(this,b.g_v,97,259)){break c}break b}if(this._>=this.A){break a}this._++}c:while(true){r=true;b:while(r===true){r=false;if(!e(this,b.g_v,97,259)){break b}break c}if(this._>=this.A){break a}this._++}this.I_p2=this._}this._=t;return true};b.prototype.r_mark_regions=b.prototype.U;function H(a){var x;var y;var z;var u;var v;var l;var f;var g;var h;var i;var j;var k;var c;var m;var n;var o;var p;var q;var r;var s;var t;var w;a.I_pV=t=a.A;a.I_p1=t;a.I_p2=t;x=a._;l=true;a:while(l===true){l=false;f=true;g:while(f===true){f=false;y=a._;g=true;b:while(g===true){g=false;if(!d(a,b.g_v,97,259)){break b}h=true;f:while(h===true){h=false;z=a._;i=true;c:while(i===true){i=false;if(!e(a,b.g_v,97,259)){break c}d:while(true){j=true;e:while(j===true){j=false;if(!d(a,b.g_v,97,259)){break e}break d}if(a._>=a.A){break c}a._++}break f}a._=z;if(!d(a,b.g_v,97,259)){break b}c:while(true){k=true;d:while(k===true){k=false;if(!e(a,b.g_v,97,259)){break d}break c}if(a._>=a.A){break b}a._++}}break g}a._=y;if(!e(a,b.g_v,97,259)){break a}c=true;c:while(c===true){c=false;u=a._;m=true;b:while(m===true){m=false;if(!e(a,b.g_v,97,259)){break b}e:while(true){n=true;d:while(n===true){n=false;if(!d(a,b.g_v,97,259)){break d}break e}if(a._>=a.A){break b}a._++}break c}a._=u;if(!d(a,b.g_v,97,259)){break a}if(a._>=a.A){break a}a._++}}a.I_pV=a._}w=a._=x;v=w;o=true;a:while(o===true){o=false;b:while(true){p=true;c:while(p===true){p=false;if(!d(a,b.g_v,97,259)){break c}break b}if(a._>=a.A){break a}a._++}b:while(true){q=true;c:while(q===true){q=false;if(!e(a,b.g_v,97,259)){break c}break b}if(a._>=a.A){break a}a._++}a.I_p1=a._;b:while(true){r=true;c:while(r===true){r=false;if(!d(a,b.g_v,97,259)){break c}break b}if(a._>=a.A){break a}a._++}c:while(true){s=true;b:while(s===true){s=false;if(!e(a,b.g_v,97,259)){break b}break c}if(a._>=a.A){break a}a._++}a.I_p2=a._}a._=v;return true};b.prototype.V=function(){var a;var e;var d;b:while(true){e=this._;d=true;a:while(d===true){d=false;this.B=this._;a=q(this,b.a_0,3);if(a===0){break a}this.C=this._;switch(a){case 0:break a;case 1:if(!c(this,'i')){return false}break;case 2:if(!c(this,'u')){return false}break;case 3:if(this._>=this.A){break a}this._++;break}continue b}this._=e;break b}return true};b.prototype.r_postlude=b.prototype.V;function I(a){var d;var f;var e;b:while(true){f=a._;e=true;a:while(e===true){e=false;a.B=a._;d=q(a,b.a_0,3);if(d===0){break a}a.C=a._;switch(d){case 0:break a;case 1:if(!c(a,'i')){return false}break;case 2:if(!c(a,'u')){return false}break;case 3:if(a._>=a.A){break a}a._++;break}continue b}a._=f;break b}return true};b.prototype.S=function(){return!(this.I_pV<=this._)?false:true};b.prototype.r_RV=b.prototype.S;b.prototype.Q=function(){return!(this.I_p1<=this._)?false:true};b.prototype.r_R1=b.prototype.Q;b.prototype.R=function(){return!(this.I_p2<=this._)?false:true};b.prototype.r_R2=b.prototype.R;b.prototype.Y=function(){var a;var e;var d;var g;this.C=this._;a=f(this,b.a_1,16);if(a===0){return false}this.B=g=this._;if(!(!(this.I_p1<=g)?false:true)){return false}switch(a){case 0:return false;case 1:if(!c(this,'')){return false}break;case 2:if(!c(this,'a')){return false}break;case 3:if(!c(this,'e')){return false}break;case 4:if(!c(this,'i')){return false}break;case 5:e=this.A-this._;d=true;a:while(d===true){d=false;if(!i(this,2,'ab')){break a}return false}this._=this.A-e;if(!c(this,'i')){return false}break;case 6:if(!c(this,'at')){return false}break;case 7:if(!c(this,'aţi')){return false}break}return true};b.prototype.r_step_0=b.prototype.Y;function J(a){var d;var g;var e;var h;a.C=a._;d=f(a,b.a_1,16);if(d===0){return false}a.B=h=a._;if(!(!(a.I_p1<=h)?false:true)){return false}switch(d){case 0:return false;case 1:if(!c(a,'')){return false}break;case 2:if(!c(a,'a')){return false}break;case 3:if(!c(a,'e')){return false}break;case 4:if(!c(a,'i')){return false}break;case 5:g=a.A-a._;e=true;a:while(e===true){e=false;if(!i(a,2,'ab')){break a}return false}a._=a.A-g;if(!c(a,'i')){return false}break;case 6:if(!c(a,'at')){return false}break;case 7:if(!c(a,'aţi')){return false}break}return true};b.prototype.T=function(){var a;var d;var e;var g;d=this.A-(e=this._);this.C=e;a=f(this,b.a_2,46);if(a===0){return false}this.B=g=this._;if(!(!(this.I_p1<=g)?false:true)){return false}switch(a){case 0:return false;case 1:if(!c(this,'abil')){return false}break;case 2:if(!c(this,'ibil')){return false}break;case 3:if(!c(this,'iv')){return false}break;case 4:if(!c(this,'ic')){return false}break;case 5:if(!c(this,'at')){return false}break;case 6:if(!c(this,'it')){return false}break}this.B_standard_suffix_removed=true;this._=this.A-d;return true};b.prototype.r_combo_suffix=b.prototype.T;function o(a){var d;var e;var g;var h;e=a.A-(g=a._);a.C=g;d=f(a,b.a_2,46);if(d===0){return false}a.B=h=a._;if(!(!(a.I_p1<=h)?false:true)){return false}switch(d){case 0:return false;case 1:if(!c(a,'abil')){return false}break;case 2:if(!c(a,'ibil')){return false}break;case 3:if(!c(a,'iv')){return false}break;case 4:if(!c(a,'ic')){return false}break;case 5:if(!c(a,'at')){return false}break;case 6:if(!c(a,'it')){return false}break}a.B_standard_suffix_removed=true;a._=a.A-e;return true};b.prototype.X=function(){var a;var e;var d;var g;this.B_standard_suffix_removed=false;a:while(true){e=this.A-this._;d=true;b:while(d===true){d=false;if(!o(this)){break b}continue a}this._=this.A-e;break a}this.C=this._;a=f(this,b.a_3,62);if(a===0){return false}this.B=g=this._;if(!(!(this.I_p2<=g)?false:true)){return false}switch(a){case 0:return false;case 1:if(!c(this,'')){return false}break;case 2:if(!i(this,1,'ţ')){return false}this.B=this._;if(!c(this,'t')){return false}break;case 3:if(!c(this,'ist')){return false}break}this.B_standard_suffix_removed=true;return true};b.prototype.r_standard_suffix=b.prototype.X;function K(a){var d;var g;var e;var h;a.B_standard_suffix_removed=false;a:while(true){g=a.A-a._;e=true;b:while(e===true){e=false;if(!o(a)){break b}continue a}a._=a.A-g;break a}a.C=a._;d=f(a,b.a_3,62);if(d===0){return false}a.B=h=a._;if(!(!(a.I_p2<=h)?false:true)){return false}switch(d){case 0:return false;case 1:if(!c(a,'')){return false}break;case 2:if(!i(a,1,'ţ')){return false}a.B=a._;if(!c(a,'t')){return false}break;case 3:if(!c(a,'ist')){return false}break}a.B_standard_suffix_removed=true;return true};b.prototype.Z=function(){var d;var h;var a;var j;var e;var g;var k;var l;var m;h=this.A-(k=this._);if(k<this.I_pV){return false}l=this._=this.I_pV;a=this.D;this.D=l;m=this._=this.A-h;this.C=m;d=f(this,b.a_4,94);if(d===0){this.D=a;return false}this.B=this._;switch(d){case 0:this.D=a;return false;case 1:e=true;a:while(e===true){e=false;j=this.A-this._;g=true;b:while(g===true){g=false;if(!p(this,b.g_v,97,259)){break b}break a}this._=this.A-j;if(!i(this,1,'u')){this.D=a;return false}}if(!c(this,'')){return false}break;case 2:if(!c(this,'')){return false}break}this.D=a;return true};b.prototype.r_verb_suffix=b.prototype.Z;function F(a){var e;var l;var d;var j;var g;var h;var m;var n;var k;l=a.A-(m=a._);if(m<a.I_pV){return false}n=a._=a.I_pV;d=a.D;a.D=n;k=a._=a.A-l;a.C=k;e=f(a,b.a_4,94);if(e===0){a.D=d;return false}a.B=a._;switch(e){case 0:a.D=d;return false;case 1:g=true;a:while(g===true){g=false;j=a.A-a._;h=true;b:while(h===true){h=false;if(!p(a,b.g_v,97,259)){break b}break a}a._=a.A-j;if(!i(a,1,'u')){a.D=d;return false}}if(!c(a,'')){return false}break;case 2:if(!c(a,'')){return false}break}a.D=d;return true};b.prototype.a=function(){var a;var d;this.C=this._;a=f(this,b.a_5,5);if(a===0){return false}this.B=d=this._;if(!(!(this.I_pV<=d)?false:true)){return false}switch(a){case 0:return false;case 1:if(!c(this,'')){return false}break}return true};b.prototype.r_vowel_suffix=b.prototype.a;function B(a){var d;var e;a.C=a._;d=f(a,b.a_5,5);if(d===0){return false}a.B=e=a._;if(!(!(a.I_pV<=e)?false:true)){return false}switch(d){case 0:return false;case 1:if(!c(a,'')){return false}break}return true};b.prototype.J=function(){var n;var j;var k;var l;var m;var o;var p;var b;var c;var d;var e;var f;var a;var g;var h;var i;var r;var s;var t;var u;var v;var w;var x;var y;var q;n=this._;b=true;a:while(b===true){b=false;if(!G(this)){break a}}r=this._=n;j=r;c=true;a:while(c===true){c=false;if(!H(this)){break a}}s=this._=j;this.D=s;u=this._=t=this.A;k=t-u;d=true;a:while(d===true){d=false;if(!J(this)){break a}}w=this._=(v=this.A)-k;l=v-w;e=true;a:while(e===true){e=false;if(!K(this)){break a}}y=this._=(x=this.A)-l;m=x-y;f=true;a:while(f===true){f=false;a=true;b:while(a===true){a=false;o=this.A-this._;g=true;c:while(g===true){g=false;if(!this.B_standard_suffix_removed){break c}break b}this._=this.A-o;if(!F(this)){break a}}}this._=this.A-m;h=true;a:while(h===true){h=false;if(!B(this)){break a}}q=this._=this.D;p=q;i=true;a:while(i===true){i=false;if(!I(this)){break a}}this._=p;return true};b.prototype.stem=b.prototype.J;b.prototype.N=function(a){return a instanceof b};b.prototype.equals=b.prototype.N;b.prototype.O=function(){var c;var a;var b;var d;c='RomanianStemmer';a=0;for(b=0;b<c.length;b++){d=c.charCodeAt(b);a=(a<<5)-a+d;a=a&a}return a|0};b.prototype.hashCode=b.prototype.O;b.serialVersionUID=1;h(b,'methodObject',function(){return new b});h(b,'a_0',function(){return[new a('',-1,3),new a('I',0,1),new a('U',0,2)]});h(b,'a_1',function(){return[new a('ea',-1,3),new a('aţia',-1,7),new a('aua',-1,2),new a('iua',-1,4),new a('aţie',-1,7),new a('ele',-1,3),new a('ile',-1,5),new a('iile',6,4),new a('iei',-1,4),new a('atei',-1,6),new a('ii',-1,4),new a('ului',-1,1),new a('ul',-1,1),new a('elor',-1,3),new a('ilor',-1,4),new a('iilor',14,4)]});h(b,'a_2',function(){return[new a('icala',-1,4),new a('iciva',-1,4),new a('ativa',-1,5),new a('itiva',-1,6),new a('icale',-1,4),new a('aţiune',-1,5),new a('iţiune',-1,6),new a('atoare',-1,5),new a('itoare',-1,6),new a('ătoare',-1,5),new a('icitate',-1,4),new a('abilitate',-1,1),new a('ibilitate',-1,2),new a('ivitate',-1,3),new a('icive',-1,4),new a('ative',-1,5),new a('itive',-1,6),new a('icali',-1,4),new a('atori',-1,5),new a('icatori',18,4),new a('itori',-1,6),new a('ători',-1,5),new a('icitati',-1,4),new a('abilitati',-1,1),new a('ivitati',-1,3),new a('icivi',-1,4),new a('ativi',-1,5),new a('itivi',-1,6),new a('icităi',-1,4),new a('abilităi',-1,1),new a('ivităi',-1,3),new a('icităţi',-1,4),new a('abilităţi',-1,1),new a('ivităţi',-1,3),new a('ical',-1,4),new a('ator',-1,5),new a('icator',35,4),new a('itor',-1,6),new a('ător',-1,5),new a('iciv',-1,4),new a('ativ',-1,5),new a('itiv',-1,6),new a('icală',-1,4),new a('icivă',-1,4),new a('ativă',-1,5),new a('itivă',-1,6)]});h(b,'a_3',function(){return[new a('ica',-1,1),new a('abila',-1,1),new a('ibila',-1,1),new a('oasa',-1,1),new a('ata',-1,1),new a('ita',-1,1),new a('anta',-1,1),new a('ista',-1,3),new a('uta',-1,1),new a('iva',-1,1),new a('ic',-1,1),new a('ice',-1,1),new a('abile',-1,1),new a('ibile',-1,1),new a('isme',-1,3),new a('iune',-1,2),new a('oase',-1,1),new a('ate',-1,1),new a('itate',17,1),new a('ite',-1,1),new a('ante',-1,1),new a('iste',-1,3),new a('ute',-1,1),new a('ive',-1,1),new a('ici',-1,1),new a('abili',-1,1),new a('ibili',-1,1),new a('iuni',-1,2),new a('atori',-1,1),new a('osi',-1,1),new a('ati',-1,1),new a('itati',30,1),new a('iti',-1,1),new a('anti',-1,1),new a('isti',-1,3),new a('uti',-1,1),new a('işti',-1,3),new a('ivi',-1,1),new a('ităi',-1,1),new a('oşi',-1,1),new a('ităţi',-1,1),new a('abil',-1,1),new a('ibil',-1,1),new a('ism',-1,3),new a('ator',-1,1),new a('os',-1,1),new a('at',-1,1),new a('it',-1,1),new a('ant',-1,1),new a('ist',-1,3),new a('ut',-1,1),new a('iv',-1,1),new a('ică',-1,1),new a('abilă',-1,1),new a('ibilă',-1,1),new a('oasă',-1,1),new a('ată',-1,1),new a('ită',-1,1),new a('antă',-1,1),new a('istă',-1,3),new a('ută',-1,1),new a('ivă',-1,1)]});h(b,'a_4',function(){return[new a('ea',-1,1),new a('ia',-1,1),new a('esc',-1,1),new a('ăsc',-1,1),new a('ind',-1,1),new a('ând',-1,1),new a('are',-1,1),new a('ere',-1,1),new a('ire',-1,1),new a('âre',-1,1),new a('se',-1,2),new a('ase',10,1),new a('sese',10,2),new a('ise',10,1),new a('use',10,1),new a('âse',10,1),new a('eşte',-1,1),new a('ăşte',-1,1),new a('eze',-1,1),new a('ai',-1,1),new a('eai',19,1),new a('iai',19,1),new a('sei',-1,2),new a('eşti',-1,1),new a('ăşti',-1,1),new a('ui',-1,1),new a('ezi',-1,1),new a('âi',-1,1),new a('aşi',-1,1),new a('seşi',-1,2),new a('aseşi',29,1),new a('seseşi',29,2),new a('iseşi',29,1),new a('useşi',29,1),new a('âseşi',29,1),new a('işi',-1,1),new a('uşi',-1,1),new a('âşi',-1,1),new a('aţi',-1,2),new a('eaţi',38,1),new a('iaţi',38,1),new a('eţi',-1,2),new a('iţi',-1,2),new a('âţi',-1,2),new a('arăţi',-1,1),new a('serăţi',-1,2),new a('aserăţi',45,1),new a('seserăţi',45,2),new a('iserăţi',45,1),new a('userăţi',45,1),new a('âserăţi',45,1),new a('irăţi',-1,1),new a('urăţi',-1,1),new a('ârăţi',-1,1),new a('am',-1,1),new a('eam',54,1),new a('iam',54,1),new a('em',-1,2),new a('asem',57,1),new a('sesem',57,2),new a('isem',57,1),new a('usem',57,1),new a('âsem',57,1),new a('im',-1,2),new a('âm',-1,2),new a('ăm',-1,2),new a('arăm',65,1),new a('serăm',65,2),new a('aserăm',67,1),new a('seserăm',67,2),new a('iserăm',67,1),new a('userăm',67,1),new a('âserăm',67,1),new a('irăm',65,1),new a('urăm',65,1),new a('ârăm',65,1),new a('au',-1,1),new a('eau',76,1),new a('iau',76,1),new a('indu',-1,1),new a('ându',-1,1),new a('ez',-1,1),new a('ească',-1,1),new a('ară',-1,1),new a('seră',-1,2),new a('aseră',84,1),new a('seseră',84,2),new a('iseră',84,1),new a('useră',84,1),new a('âseră',84,1),new a('iră',-1,1),new a('ură',-1,1),new a('âră',-1,1),new a('ează',-1,1)]});h(b,'a_5',function(){return[new a('a',-1,1),new a('e',-1,1),new a('ie',1,1),new a('i',-1,1),new a('ă',-1,1)]});h(b,'g_v',function(){return[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,2,32,0,0,4]});var r={'src/stemmer.jsx':{Stemmer:n},'src/romanian-stemmer.jsx':{RomanianStemmer:b}}}(JSX))
+var Stemmer = JSX.require("src/romanian-stemmer.jsx").RomanianStemmer;
+"""
+
+
+class SearchRomanian(SearchLanguage):
+    lang = 'ro'
+    language_name = 'Romanian'
+    js_stemmer_code = js_stemmer
+    stopwords = []
+
+    def init(self, options):
+        self.stemmer = snowballstemmer.stemmer('romanian')
+
+    def stem(self, word):
+        return self.stemmer.stemWord(word)
diff --git a/sphinx/search/ru.py b/sphinx/search/ru.py
new file mode 100644
index 0000000..af019ea
--- /dev/null
+++ b/sphinx/search/ru.py
@@ -0,0 +1,261 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.search.ru
+    ~~~~~~~~~~~~~~~~
+
+    Russian search language: includes the JS Russian stemmer.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from sphinx.search import SearchLanguage, parse_stop_word
+
+import snowballstemmer
+
+russian_stopwords = parse_stop_word(u'''
+| source: http://snowball.tartarus.org/algorithms/russian/stop.txt
+и              | and
+в              | in/into
+во             | alternative form
+не             | not
+что            | what/that
+он             | he
+на             | on/onto
+я              | i
+с              | from
+со             | alternative form
+как            | how
+а              | milder form of `no' (but)
+то             | conjunction and form of `that'
+все            | all
+она            | she
+так            | so, thus
+его            | him
+но             | but
+да             | yes/and
+ты             | thou
+к              | towards, by
+у              | around, chez
+же             | intensifier particle
+вы             | you
+за             | beyond, behind
+бы             | conditional/subj. particle
+по             | up to, along
+только         | only
+ее             | her
+мне            | to me
+было           | it was
+вот            | here is/are, particle
+от             | away from
+меня           | me
+еще            | still, yet, more
+нет            | no, there isnt/arent
+о              | about
+из             | out of
+ему            | to him
+теперь         | now
+когда          | when
+даже           | even
+ну             | so, well
+вдруг          | suddenly
+ли             | interrogative particle
+если           | if
+уже            | already, but homonym of `narrower'
+или            | or
+ни             | neither
+быть           | to be
+был            | he was
+него           | prepositional form of его
+до             | up to
+вас            | you accusative
+нибудь         | indef. suffix preceded by hyphen
+опять          | again
+уж             | already, but homonym of `adder'
+вам            | to you
+сказал         | he said
+ведь           | particle `after all'
+там            | there
+потом          | then
+себя           | oneself
+ничего         | nothing
+ей             | to her
+может          | usually with `быть' as `maybe'
+они            | they
+тут            | here
+где            | where
+есть           | there is/are
+надо           | got to, must
+ней            | prepositional form of  ей
+для            | for
+мы             | we
+тебя           | thee
+их             | them, their
+чем            | than
+была           | she was
+сам            | self
+чтоб           | in order to
+без            | without
+будто          | as if
+человек        | man, person, one
+чего           | genitive form of `what'
+раз            | once
+тоже           | also
+себе           | to oneself
+под            | beneath
+жизнь          | life
+будет          | will be
+ж              | short form of intensifer particle `же'
+тогда          | then
+кто            | who
+этот           | this
+говорил        | was saying
+того           | genitive form of `that'
+потому         | for that reason
+этого          | genitive form of `this'
+какой          | which
+совсем         | altogether
+ним            | prepositional form of `его', `они'
+здесь          | here
+этом           | prepositional form of `этот'
+один           | one
+почти          | almost
+мой            | my
+тем            | instrumental/dative plural of `тот', `то'
+чтобы          | full form of `in order that'
+нее            | her (acc.)
+кажется        | it seems
+сейчас         | now
+были           | they were
+куда           | where to
+зачем          | why
+сказать        | to say
+всех           | all (acc., gen. preposn. plural)
+никогда        | never
+сегодня        | today
+можно          | possible, one can
+при            | by
+наконец        | finally
+два            | two
+об             | alternative form of `о', about
+другой         | another
+хоть           | even
+после          | after
+над            | above
+больше         | more
+тот            | that one (masc.)
+через          | across, in
+эти            | these
+нас            | us
+про            | about
+всего          | in all, only, of all
+них            | prepositional form of `они' (they)
+какая          | which, feminine
+много          | lots
+разве          | interrogative particle
+сказала        | she said
+три            | three
+эту            | this, acc. fem. sing.
+моя            | my, feminine
+впрочем        | moreover, besides
+хорошо         | good
+свою           | ones own, acc. fem. sing.
+этой           | oblique form of `эта', fem. `this'
+перед          | in front of
+иногда         | sometimes
+лучше          | better
+чуть           | a little
+том            | preposn. form of `that one'
+нельзя         | one must not
+такой          | such a one
+им             | to them
+более          | more
+всегда         | always
+конечно        | of course
+всю            | acc. fem. sing of `all'
+между          | between
+
+
+  | b: some paradigms
+  |
+  | personal pronouns
+  |
+  | я  меня  мне  мной  [мною]
+  | ты  тебя  тебе  тобой  [тобою]
+  | он  его  ему  им  [него, нему, ним]
+  | она  ее  эи  ею  [нее, нэи, нею]
+  | оно  его  ему  им  [него, нему, ним]
+  |
+  | мы  нас  нам  нами
+  | вы  вас  вам  вами
+  | они  их  им  ими  [них, ним, ними]
+  |
+  |   себя  себе  собой   [собою]
+  |
+  | demonstrative pronouns: этот (this), тот (that)
+  |
+  | этот  эта  это  эти
+  | этого  эты  это  эти
+  | этого  этой  этого  этих
+  | этому  этой  этому  этим
+  | этим  этой  этим  [этою]  этими
+  | этом  этой  этом  этих
+  |
+  | тот  та  то  те
+  | того  ту  то  те
+  | того  той  того  тех
+  | тому  той  тому  тем
+  | тем  той  тем  [тою]  теми
+  | том  той  том  тех
+  |
+  | determinative pronouns
+  |
+  | (a) весь (all)
+  |
+  | весь  вся  все  все
+  | всего  всю  все  все
+  | всего  всей  всего  всех
+  | всему  всей  всему  всем
+  | всем  всей  всем  [всею]  всеми
+  | всем  всей  всем  всех
+  |
+  | (b) сам (himself etc)
+  |
+  | сам  сама  само  сами
+  | самого саму  само  самих
+  | самого самой самого  самих
+  | самому самой самому  самим
+  | самим  самой  самим  [самою]  самими
+  | самом самой самом  самих
+  |
+  | stems of verbs `to be', `to have', `to do' and modal
+  |
+  | быть  бы  буд  быв  есть  суть
+  | име
+  | дел
+  | мог   мож  мочь
+  | уме
+  | хоч  хот
+  | долж
+  | можн
+  | нужн
+  | нельзя
+''')
+
+js_stemmer = u"""
+var JSX={};(function(h){function j(b,e){var a=function(){};a.prototype=e.prototype;var c=new a;for(var d in b){b[d].prototype=c}}function J(c,b){for(var a in b.prototype)if(b.prototype.hasOwnProperty(a))c.prototype[a]=b.prototype[a]}function f(a,b,d){function c(a,b,c){delete a[b];a[b]=c;return c}Object.defineProperty(a,b,{get:function(){return c(a,b,d())},set:function(d){c(a,b,d)},enumerable:true,configurable:true})}function K(a,b,c){return a[b]=a[b]/c|0}var p=parseInt;var z=parseFloat;function L(a){return a!==a}var x=isFinite;var w=encodeURIComponent;var u=decodeURIComponent;var t=encodeURI;var s=decodeURI;var B=Object.prototype.toString;var q=Object.prototype.hasOwnProperty;function i(){}h.require=function(b){var a=o[b];return a!==undefined?a:null};h.profilerIsRunning=function(){return i.getResults!=null};h.getProfileResults=function(){return(i.getResults||function(){return{}})()};h.postProfileResults=function(a,b){if(i.postResults==null)throw new Error('profiler has not been turned on');return i.postResults(a,b)};h.resetProfileResults=function(){if(i.resetResults==null)throw new Error('profiler has not been turned on');return i.resetResults()};h.DEBUG=false;function r(){};j([r],Error);function a(a,b,c){this.G=a.length;this.X=a;this.a=b;this.J=c;this.I=null;this.b=null};j([a],Object);function m(){};j([m],Object);function g(){var a;var b;var c;this.F={};a=this.D='';b=this._=0;c=this.A=a.length;this.E=0;this.B=b;this.C=c};j([g],m);function v(a,b){a.D=b.D;a._=b._;a.A=b.A;a.E=b.E;a.B=b.B;a.C=b.C};function k(b,d,c,e){var a;if(b._>=b.A){return false}a=b.D.charCodeAt(b._);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._++;return true};function l(a,d,c,e){var b;if(a._>=a.A){return false}b=a.D.charCodeAt(a._);if(b>e||b<c){a._++;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._++;return true}return false};function d(a,b,d){var c;if(a._-a.E<b){return false}if(a.D.slice((c=a._)-b,c)!==d){return false}a._-=b;return true};function e(d,m,p){var b;var g;var e;var n;var f;var k;var l;var i;var h;var c;var a;var j;var o;b=0;g=p;e=d._;n=d.E;f=0;k=0;l=false;while(true){i=b+(g-b>>1);h=0;c=f<k?f:k;a=m[i];for(j=a.G-1-c;j>=0;j--){if(e-c===n){h=-1;break}h=d.D.charCodeAt(e-1-c)-a.X.charCodeAt(j);if(h!==0){break}c++}if(h<0){g=i;k=c}else{b=i;f=c}if(g-b<=1){if(b>0){break}if(g===b){break}if(l){break}l=true}}while(true){a=m[b];if(f>=a.G){d._=e-a.G|0;if(a.I==null){return a.J}o=a.I(d);d._=e-a.G|0;if(o){return a.J}}b=a.a;if(b<0){return 0}}return-1};function A(a,b,d,e){var c;c=e.length-(d-b);a.D=a.D.slice(0,b)+e+a.D.slice(d);a.A+=c|0;if(a._>=d){a._+=c|0}else if(a._>b){a._=b}return c|0};function c(a,f){var b;var c;var d;var e;b=false;if((c=a.B)<0||c>(d=a.C)||d>(e=a.A)||e>a.D.length?false:true){A(a,a.B,a.C,f);b=true}return b};g.prototype.H=function(){return false};g.prototype.Y=function(b){var a;var c;var d;var e;a=this.F['.'+b];if(a==null){c=this.D=b;d=this._=0;e=this.A=c.length;this.E=0;this.B=d;this.C=e;this.H();a=this.D;this.F['.'+b]=a}return a};g.prototype.stemWord=g.prototype.Y;g.prototype.Z=function(e){var d;var b;var c;var a;var f;var g;var h;d=[];for(b=0;b<e.length;b++){c=e[b];a=this.F['.'+c];if(a==null){f=this.D=c;g=this._=0;h=this.A=f.length;this.E=0;this.B=g;this.C=h;this.H();a=this.D;this.F['.'+c]=a}d.push(a)}return d};g.prototype.stemWords=g.prototype.Z;function b(){g.call(this);this.I_p2=0;this.I_pV=0};j([b],g);b.prototype.K=function(a){this.I_p2=a.I_p2;this.I_pV=a.I_pV;v(this,a)};b.prototype.copy_from=b.prototype.K;b.prototype.R=function(){var g;var a;var c;var d;var e;var f;var h;this.I_pV=h=this.A;this.I_p2=h;g=this._;a=true;a:while(a===true){a=false;b:while(true){c=true;c:while(c===true){c=false;if(!k(this,b.g_v,1072,1103)){break c}break b}if(this._>=this.A){break a}this._++}this.I_pV=this._;b:while(true){d=true;c:while(d===true){d=false;if(!l(this,b.g_v,1072,1103)){break c}break b}if(this._>=this.A){break a}this._++}b:while(true){e=true;c:while(e===true){e=false;if(!k(this,b.g_v,1072,1103)){break c}break b}if(this._>=this.A){break a}this._++}b:while(true){f=true;c:while(f===true){f=false;if(!l(this,b.g_v,1072,1103)){break c}break b}if(this._>=this.A){break a}this._++}this.I_p2=this._}this._=g;return true};b.prototype.r_mark_regions=b.prototype.R;function D(a){var h;var c;var d;var e;var f;var g;var i;a.I_pV=i=a.A;a.I_p2=i;h=a._;c=true;a:while(c===true){c=false;b:while(true){d=true;c:while(d===true){d=false;if(!k(a,b.g_v,1072,1103)){break c}break b}if(a._>=a.A){break a}a._++}a.I_pV=a._;b:while(true){e=true;c:while(e===true){e=false;if(!l(a,b.g_v,1072,1103)){break c}break b}if(a._>=a.A){break a}a._++}b:while(true){f=true;c:while(f===true){f=false;if(!k(a,b.g_v,1072,1103)){break c}break b}if(a._>=a.A){break a}a._++}b:while(true){g=true;c:while(g===true){g=false;if(!l(a,b.g_v,1072,1103)){break c}break b}if(a._>=a.A){break a}a._++}a.I_p2=a._}a._=h;return true};b.prototype.N=function(){return!(this.I_p2<=this._)?false:true};b.prototype.r_R2=b.prototype.N;b.prototype.T=function(){var a;var h;var f;var g;this.C=this._;a=e(this,b.a_0,9);if(a===0){return false}this.B=this._;switch(a){case 0:return false;case 1:f=true;a:while(f===true){f=false;h=this.A-this._;g=true;b:while(g===true){g=false;if(!d(this,1,'а')){break b}break a}this._=this.A-h;if(!d(this,1,'я')){return false}}if(!c(this,'')){return false}break;case 2:if(!c(this,'')){return false}break}return true};b.prototype.r_perfective_gerund=b.prototype.T;function E(a){var f;var i;var g;var h;a.C=a._;f=e(a,b.a_0,9);if(f===0){return false}a.B=a._;switch(f){case 0:return false;case 1:g=true;a:while(g===true){g=false;i=a.A-a._;h=true;b:while(h===true){h=false;if(!d(a,1,'а')){break b}break a}a._=a.A-i;if(!d(a,1,'я')){return false}}if(!c(a,'')){return false}break;case 2:if(!c(a,'')){return false}break}return true};b.prototype.P=function(){var a;this.C=this._;a=e(this,b.a_1,26);if(a===0){return false}this.B=this._;switch(a){case 0:return false;case 1:if(!c(this,'')){return false}break}return true};b.prototype.r_adjective=b.prototype.P;function n(a){var d;a.C=a._;d=e(a,b.a_1,26);if(d===0){return false}a.B=a._;switch(d){case 0:return false;case 1:if(!c(a,'')){return false}break}return true};b.prototype.O=function(){var f;var a;var j;var g;var h;var i;if(!n(this)){return false}a=this.A-this._;g=true;a:while(g===true){g=false;this.C=this._;f=e(this,b.a_2,8);if(f===0){this._=this.A-a;break a}this.B=this._;switch(f){case 0:this._=this.A-a;break a;case 1:h=true;b:while(h===true){h=false;j=this.A-this._;i=true;c:while(i===true){i=false;if(!d(this,1,'а')){break c}break b}this._=this.A-j;if(!d(this,1,'я')){this._=this.A-a;break a}}if(!c(this,'')){return false}break;case 2:if(!c(this,'')){return false}break}}return true};b.prototype.r_adjectival=b.prototype.O;function G(a){var g;var f;var k;var h;var i;var j;if(!n(a)){return false}f=a.A-a._;h=true;a:while(h===true){h=false;a.C=a._;g=e(a,b.a_2,8);if(g===0){a._=a.A-f;break a}a.B=a._;switch(g){case 0:a._=a.A-f;break a;case 1:i=true;b:while(i===true){i=false;k=a.A-a._;j=true;c:while(j===true){j=false;if(!d(a,1,'а')){break c}break b}a._=a.A-k;if(!d(a,1,'я')){a._=a.A-f;break a}}if(!c(a,'')){return false}break;case 2:if(!c(a,'')){return false}break}}return true};b.prototype.U=function(){var a;this.C=this._;a=e(this,b.a_3,2);if(a===0){return false}this.B=this._;switch(a){case 0:return false;case 1:if(!c(this,'')){return false}break}return true};b.prototype.r_reflexive=b.prototype.U;function H(a){var d;a.C=a._;d=e(a,b.a_3,2);if(d===0){return false}a.B=a._;switch(d){case 0:return false;case 1:if(!c(a,'')){return false}break}return true};b.prototype.W=function(){var a;var h;var f;var g;this.C=this._;a=e(this,b.a_4,46);if(a===0){return false}this.B=this._;switch(a){case 0:return false;case 1:f=true;a:while(f===true){f=false;h=this.A-this._;g=true;b:while(g===true){g=false;if(!d(this,1,'а')){break b}break a}this._=this.A-h;if(!d(this,1,'я')){return false}}if(!c(this,'')){return false}break;case 2:if(!c(this,'')){return false}break}return true};b.prototype.r_verb=b.prototype.W;function I(a){var f;var i;var g;var h;a.C=a._;f=e(a,b.a_4,46);if(f===0){return false}a.B=a._;switch(f){case 0:return false;case 1:g=true;a:while(g===true){g=false;i=a.A-a._;h=true;b:while(h===true){h=false;if(!d(a,1,'а')){break b}break a}a._=a.A-i;if(!d(a,1,'я')){return false}}if(!c(a,'')){return false}break;case 2:if(!c(a,'')){return false}break}return true};b.prototype.S=function(){var a;this.C=this._;a=e(this,b.a_5,36);if(a===0){return false}this.B=this._;switch(a){case 0:return false;case 1:if(!c(this,'')){return false}break}return true};b.prototype.r_noun=b.prototype.S;function F(a){var d;a.C=a._;d=e(a,b.a_5,36);if(d===0){return false}a.B=a._;switch(d){case 0:return false;case 1:if(!c(a,'')){return false}break}return true};b.prototype.Q=function(){var a;var d;this.C=this._;a=e(this,b.a_6,2);if(a===0){return false}this.B=d=this._;if(!(!(this.I_p2<=d)?false:true)){return false}switch(a){case 0:return false;case 1:if(!c(this,'')){return false}break}return true};b.prototype.r_derivational=b.prototype.Q;function C(a){var d;var f;a.C=a._;d=e(a,b.a_6,2);if(d===0){return false}a.B=f=a._;if(!(!(a.I_p2<=f)?false:true)){return false}switch(d){case 0:return false;case 1:if(!c(a,'')){return false}break}return true};b.prototype.V=function(){var a;this.C=this._;a=e(this,b.a_7,4);if(a===0){return false}this.B=this._;switch(a){case 0:return false;case 1:if(!c(this,'')){return false}this.C=this._;if(!d(this,1,'н')){return false}this.B=this._;if(!d(this,1,'н')){return false}if(!c(this,'')){return false}break;case 2:if(!d(this,1,'н')){return false}if(!c(this,'')){return false}break;case 3:if(!c(this,'')){return false}break}return true};b.prototype.r_tidy_up=b.prototype.V;function y(a){var f;a.C=a._;f=e(a,b.a_7,4);if(f===0){return false}a.B=a._;switch(f){case 0:return false;case 1:if(!c(a,'')){return false}a.C=a._;if(!d(a,1,'н')){return false}a.B=a._;if(!d(a,1,'н')){return false}if(!c(a,'')){return false}break;case 2:if(!d(a,1,'н')){return false}if(!c(a,'')){return false}break;case 3:if(!c(a,'')){return false}break}return true};b.prototype.H=function(){var s;var v;var w;var A;var p;var q;var i;var t;var u;var e;var f;var g;var h;var a;var j;var b;var k;var l;var m;var n;var x;var z;var o;var B;var J;var K;var L;var M;var N;var O;var r;s=this._;e=true;a:while(e===true){e=false;if(!D(this)){break a}}x=this._=s;this.E=x;o=this._=z=this.A;v=z-o;if(o<this.I_pV){return false}K=this._=this.I_pV;w=this.E;this.E=K;M=this._=(L=this.A)-v;A=L-M;f=true;c:while(f===true){f=false;g=true;b:while(g===true){g=false;p=this.A-this._;h=true;a:while(h===true){h=false;if(!E(this)){break a}break b}J=this._=(B=this.A)-p;q=B-J;a=true;a:while(a===true){a=false;if(!H(this)){this._=this.A-q;break a}}j=true;a:while(j===true){j=false;i=this.A-this._;b=true;d:while(b===true){b=false;if(!G(this)){break d}break a}this._=this.A-i;k=true;d:while(k===true){k=false;if(!I(this)){break d}break a}this._=this.A-i;if(!F(this)){break c}}}}O=this._=(N=this.A)-A;t=N-O;l=true;a:while(l===true){l=false;this.C=this._;if(!d(this,1,'и')){this._=this.A-t;break a}this.B=this._;if(!c(this,'')){return false}}u=this.A-this._;m=true;a:while(m===true){m=false;if(!C(this)){break a}}this._=this.A-u;n=true;a:while(n===true){n=false;if(!y(this)){break a}}r=this.E=w;this._=r;return true};b.prototype.stem=b.prototype.H;b.prototype.L=function(a){return a instanceof b};b.prototype.equals=b.prototype.L;b.prototype.M=function(){var c;var a;var b;var d;c='RussianStemmer';a=0;for(b=0;b<c.length;b++){d=c.charCodeAt(b);a=(a<<5)-a+d;a=a&a}return a|0};b.prototype.hashCode=b.prototype.M;b.serialVersionUID=1;f(b,'methodObject',function(){return new b});f(b,'a_0',function(){return[new a('в',-1,1),new a('ив',0,2),new a('ыв',0,2),new a('вши',-1,1),new a('ивши',3,2),new a('ывши',3,2),new a('вшись',-1,1),new a('ившись',6,2),new a('ывшись',6,2)]});f(b,'a_1',function(){return[new a('ее',-1,1),new a('ие',-1,1),new a('ое',-1,1),new a('ые',-1,1),new a('ими',-1,1),new a('ыми',-1,1),new a('ей',-1,1),new a('ий',-1,1),new a('ой',-1,1),new a('ый',-1,1),new a('ем',-1,1),new a('им',-1,1),new a('ом',-1,1),new a('ым',-1,1),new a('его',-1,1),new a('ого',-1,1),new a('ему',-1,1),new a('ому',-1,1),new a('их',-1,1),new a('ых',-1,1),new a('ею',-1,1),new a('ою',-1,1),new a('ую',-1,1),new a('юю',-1,1),new a('ая',-1,1),new a('яя',-1,1)]});f(b,'a_2',function(){return[new a('ем',-1,1),new a('нн',-1,1),new a('вш',-1,1),new a('ивш',2,2),new a('ывш',2,2),new a('щ',-1,1),new a('ющ',5,1),new a('ующ',6,2)]});f(b,'a_3',function(){return[new a('сь',-1,1),new a('ся',-1,1)]});f(b,'a_4',function(){return[new a('ла',-1,1),new a('ила',0,2),new a('ыла',0,2),new a('на',-1,1),new a('ена',3,2),new a('ете',-1,1),new a('ите',-1,2),new a('йте',-1,1),new a('ейте',7,2),new a('уйте',7,2),new a('ли',-1,1),new a('или',10,2),new a('ыли',10,2),new a('й',-1,1),new a('ей',13,2),new a('уй',13,2),new a('л',-1,1),new a('ил',16,2),new a('ыл',16,2),new a('ем',-1,1),new a('им',-1,2),new a('ым',-1,2),new a('н',-1,1),new a('ен',22,2),new a('ло',-1,1),new a('ило',24,2),new a('ыло',24,2),new a('но',-1,1),new a('ено',27,2),new a('нно',27,1),new a('ет',-1,1),new a('ует',30,2),new a('ит',-1,2),new a('ыт',-1,2),new a('ют',-1,1),new a('уют',34,2),new a('ят',-1,2),new a('ны',-1,1),new a('ены',37,2),new a('ть',-1,1),new a('ить',39,2),new a('ыть',39,2),new a('ешь',-1,1),new a('ишь',-1,2),new a('ю',-1,2),new a('ую',44,2)]});f(b,'a_5',function(){return[new a('а',-1,1),new a('ев',-1,1),new a('ов',-1,1),new a('е',-1,1),new a('ие',3,1),new a('ье',3,1),new a('и',-1,1),new a('еи',6,1),new a('ии',6,1),new a('ами',6,1),new a('ями',6,1),new a('иями',10,1),new a('й',-1,1),new a('ей',12,1),new a('ией',13,1),new a('ий',12,1),new a('ой',12,1),new a('ам',-1,1),new a('ем',-1,1),new a('ием',18,1),new a('ом',-1,1),new a('ям',-1,1),new a('иям',21,1),new a('о',-1,1),new a('у',-1,1),new a('ах',-1,1),new a('ях',-1,1),new a('иях',26,1),new a('ы',-1,1),new a('ь',-1,1),new a('ю',-1,1),new a('ию',30,1),new a('ью',30,1),new a('я',-1,1),new a('ия',33,1),new a('ья',33,1)]});f(b,'a_6',function(){return[new a('ост',-1,1),new a('ость',-1,1)]});f(b,'a_7',function(){return[new a('ейше',-1,1),new a('н',-1,2),new a('ейш',-1,1),new a('ь',-1,3)]});f(b,'g_v',function(){return[33,65,8,232]});var o={'src/stemmer.jsx':{Stemmer:m},'src/russian-stemmer.jsx':{RussianStemmer:b}}}(JSX))
+var Stemmer = JSX.require("src/russian-stemmer.jsx").RussianStemmer;
+"""
+
+
+class SearchRussian(SearchLanguage):
+    lang = 'ru'
+    language_name = 'Russian'
+    js_stemmer_code = js_stemmer
+    stopwords = russian_stopwords
+
+    def init(self, options):
+        self.stemmer = snowballstemmer.stemmer('russian')
+
+    def stem(self, word):
+        return self.stemmer.stemWord(word)
diff --git a/sphinx/search/sv.py b/sphinx/search/sv.py
new file mode 100644
index 0000000..eb4ab2e
--- /dev/null
+++ b/sphinx/search/sv.py
@@ -0,0 +1,150 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.search.sv
+    ~~~~~~~~~~~~~~~~
+
+    Swedish search language: includes the JS Swedish stemmer.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from sphinx.search import SearchLanguage, parse_stop_word
+
+import snowballstemmer
+
+swedish_stopwords = parse_stop_word(u'''
+| source: http://snowball.tartarus.org/algorithms/swedish/stop.txt
+och            | and
+det            | it, this/that
+att            | to (with infinitive)
+i              | in, at
+en             | a
+jag            | I
+hon            | she
+som            | who, that
+han            | he
+på             | on
+den            | it, this/that
+med            | with
+var            | where, each
+sig            | him(self) etc
+för            | for
+så             | so (also: seed)
+till           | to
+är             | is
+men            | but
+ett            | a
+om             | if; around, about
+hade           | had
+de             | they, these/those
+av             | of
+icke           | not, no
+mig            | me
+du             | you
+henne          | her
+då             | then, when
+sin            | his
+nu             | now
+har            | have
+inte           | inte någon = no one
+hans           | his
+honom          | him
+skulle         | 'sake'
+hennes         | her
+där            | there
+min            | my
+man            | one (pronoun)
+ej             | nor
+vid            | at, by, on (also: vast)
+kunde          | could
+något          | some etc
+från           | from, off
+ut             | out
+när            | when
+efter          | after, behind
+upp            | up
+vi             | we
+dem            | them
+vara           | be
+vad            | what
+över           | over
+än             | than
+dig            | you
+kan            | can
+sina           | his
+här            | here
+ha             | have
+mot            | towards
+alla           | all
+under          | under (also: wonder)
+någon          | some etc
+eller          | or (else)
+allt           | all
+mycket         | much
+sedan          | since
+ju             | why
+denna          | this/that
+själv          | myself, yourself etc
+detta          | this/that
+åt             | to
+utan           | without
+varit          | was
+hur            | how
+ingen          | no
+mitt           | my
+ni             | you
+bli            | to be, become
+blev           | from bli
+oss            | us
+din            | thy
+dessa          | these/those
+några          | some etc
+deras          | their
+blir           | from bli
+mina           | my
+samma          | (the) same
+vilken         | who, that
+er             | you, your
+sådan          | such a
+vår            | our
+blivit         | from bli
+dess           | its
+inom           | within
+mellan         | between
+sådant         | such a
+varför         | why
+varje          | each
+vilka          | who, that
+ditt           | thy
+vem            | who
+vilket         | who, that
+sitta          | his
+sådana         | such a
+vart           | each
+dina           | thy
+vars           | whose
+vårt           | our
+våra           | our
+ert            | your
+era            | your
+vilkas         | whose
+''')
+
+js_stemmer = u"""
+var JSX={};(function(e){function i(b,e){var a=function(){};a.prototype=e.prototype;var c=new a;for(var d in b){b[d].prototype=c}}function G(c,b){for(var a in b.prototype)if(b.prototype.hasOwnProperty(a))c.prototype[a]=b.prototype[a]}function h(a,b,d){function c(a,b,c){delete a[b];a[b]=c;return c}Object.defineProperty(a,b,{get:function(){return c(a,b,d())},set:function(d){c(a,b,d)},enumerable:true,configurable:true})}function F(a,b,c){return a[b]=a[b]/c|0}var t=parseInt;var u=parseFloat;function E(a){return a!==a}var x=isFinite;var y=encodeURIComponent;var z=decodeURIComponent;var B=encodeURI;var C=decodeURI;var o=Object.prototype.toString;var p=Object.prototype.hasOwnProperty;function f(){}e.require=function(b){var a=n[b];return a!==undefined?a:null};e.profilerIsRunning=function(){return f.getResults!=null};e.getProfileResults=function(){return(f.getResults||function(){return{}})()};e.postProfileResults=function(a,b){if(f.postResults==null)throw new Error('profiler has not been turned on');return f.postResults(a,b)};e.resetProfileResults=function(){if(f.resetResults==null)throw new Error('profiler has not been turned on');return f.resetResults()};e.DEBUG=false;function r(){};i([r],Error);function a(a,b,c){this.G=a.length;this.R=a;this.U=b;this.J=c;this.I=null;this.V=null};i([a],Object);function j(){};i([j],Object);function d(){var a;var b;var c;this.F={};a=this.C='';b=this._=0;c=this.B=a.length;this.A=0;this.D=b;this.E=c};i([d],j);function v(a,b){a.C=b.C;a._=b._;a.B=b.B;a.A=b.A;a.D=b.D;a.E=b.E};function k(b,d,c,e){var a;if(b._>=b.B){return false}a=b.C.charCodeAt(b._);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._++;return true};function l(b,d,c,e){var a;if(b._<=b.A){return false}a=b.C.charCodeAt(b._-1);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._--;return true};function m(a,d,c,e){var b;if(a._>=a.B){return false}b=a.C.charCodeAt(a._);if(b>e||b<c){a._++;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._++;return true}return false};function g(d,m,p){var b;var g;var e;var n;var f;var k;var l;var i;var h;var c;var a;var j;var o;b=0;g=p;e=d._;n=d.A;f=0;k=0;l=false;while(true){i=b+(g-b>>1);h=0;c=f<k?f:k;a=m[i];for(j=a.G-1-c;j>=0;j--){if(e-c===n){h=-1;break}h=d.C.charCodeAt(e-1-c)-a.R.charCodeAt(j);if(h!==0){break}c++}if(h<0){g=i;k=c}else{b=i;f=c}if(g-b<=1){if(b>0){break}if(g===b){break}if(l){break}l=true}}while(true){a=m[b];if(f>=a.G){d._=e-a.G|0;if(a.I==null){return a.J}o=a.I(d);d._=e-a.G|0;if(o){return a.J}}b=a.U;if(b<0){return 0}}return-1};function A(a,b,d,e){var c;c=e.length-(d-b);a.C=a.C.slice(0,b)+e+a.C.slice(d);a.B+=c|0;if(a._>=d){a._+=c|0}else if(a._>b){a._=b}return c|0};function c(a,f){var b;var c;var d;var e;b=false;if((c=a.D)<0||c>(d=a.E)||d>(e=a.B)||e>a.C.length?false:true){A(a,a.D,a.E,f);b=true}return b};d.prototype.H=function(){return false};d.prototype.S=function(b){var a;var c;var d;var e;a=this.F['.'+b];if(a==null){c=this.C=b;d=this._=0;e=this.B=c.length;this.A=0;this.D=d;this.E=e;this.H();a=this.C;this.F['.'+b]=a}return a};d.prototype.stemWord=d.prototype.S;d.prototype.T=function(e){var d;var b;var c;var a;var f;var g;var h;d=[];for(b=0;b<e.length;b++){c=e[b];a=this.F['.'+c];if(a==null){f=this.C=c;g=this._=0;h=this.B=f.length;this.A=0;this.D=g;this.E=h;this.H();a=this.C;this.F['.'+c]=a}d.push(a)}return d};d.prototype.stemWords=d.prototype.T;function b(){d.call(this);this.I_x=0;this.I_p1=0};i([b],d);b.prototype.K=function(a){this.I_x=a.I_x;this.I_p1=a.I_p1;v(this,a)};b.prototype.copy_from=b.prototype.K;b.prototype.P=function(){var g;var d;var a;var e;var c;var f;var i;var j;var l;var h;this.I_p1=j=this.B;g=i=this._;a=i+3|0;if(0>a||a>j){return false}h=this._=a;this.I_x=h;this._=g;a:while(true){d=this._;e=true;b:while(e===true){e=false;if(!k(this,b.g_v,97,246)){break b}this._=d;break a}l=this._=d;if(l>=this.B){return false}this._++}a:while(true){c=true;b:while(c===true){c=false;if(!m(this,b.g_v,97,246)){break b}break a}if(this._>=this.B){return false}this._++}this.I_p1=this._;f=true;a:while(f===true){f=false;if(!(this.I_p1<this.I_x)){break a}this.I_p1=this.I_x}return true};b.prototype.r_mark_regions=b.prototype.P;function D(a){var h;var e;var c;var f;var d;var g;var j;var l;var n;var i;a.I_p1=l=a.B;h=j=a._;c=j+3|0;if(0>c||c>l){return false}i=a._=c;a.I_x=i;a._=h;a:while(true){e=a._;f=true;b:while(f===true){f=false;if(!k(a,b.g_v,97,246)){break b}a._=e;break a}n=a._=e;if(n>=a.B){return false}a._++}a:while(true){d=true;b:while(d===true){d=false;if(!m(a,b.g_v,97,246)){break b}break a}if(a._>=a.B){return false}a._++}a.I_p1=a._;g=true;a:while(g===true){g=false;if(!(a.I_p1<a.I_x)){break a}a.I_p1=a.I_x}return true};b.prototype.O=function(){var a;var e;var d;var f;var h;var i;e=this.B-(f=this._);if(f<this.I_p1){return false}h=this._=this.I_p1;d=this.A;this.A=h;i=this._=this.B-e;this.E=i;a=g(this,b.a_0,37);if(a===0){this.A=d;return false}this.D=this._;this.A=d;switch(a){case 0:return false;case 1:if(!c(this,'')){return false}break;case 2:if(!l(this,b.g_s_ending,98,121)){return false}if(!c(this,'')){return false}break}return true};b.prototype.r_main_suffix=b.prototype.O;function w(a){var d;var f;var e;var h;var i;var j;f=a.B-(h=a._);if(h<a.I_p1){return false}i=a._=a.I_p1;e=a.A;a.A=i;j=a._=a.B-f;a.E=j;d=g(a,b.a_0,37);if(d===0){a.A=e;return false}a.D=a._;a.A=e;switch(d){case 0:return false;case 1:if(!c(a,'')){return false}break;case 2:if(!l(a,b.g_s_ending,98,121)){return false}if(!c(a,'')){return false}break}return true};b.prototype.N=function(){var e;var a;var f;var h;var i;var j;var k;var d;e=this.B-(h=this._);if(h<this.I_p1){return false}i=this._=this.I_p1;a=this.A;this.A=i;k=this._=(j=this.B)-e;f=j-k;if(g(this,b.a_1,7)===0){this.A=a;return false}d=this._=this.B-f;this.E=d;if(d<=this.A){this.A=a;return false}this._--;this.D=this._;if(!c(this,'')){return false}this.A=a;return true};b.prototype.r_consonant_pair=b.prototype.N;function s(a){var f;var d;var h;var i;var j;var k;var l;var e;f=a.B-(i=a._);if(i<a.I_p1){return false}j=a._=a.I_p1;d=a.A;a.A=j;l=a._=(k=a.B)-f;h=k-l;if(g(a,b.a_1,7)===0){a.A=d;return false}e=a._=a.B-h;a.E=e;if(e<=a.A){a.A=d;return false}a._--;a.D=a._;if(!c(a,'')){return false}a.A=d;return true};b.prototype.Q=function(){var d;var e;var a;var f;var h;var i;e=this.B-(f=this._);if(f<this.I_p1){return false}h=this._=this.I_p1;a=this.A;this.A=h;i=this._=this.B-e;this.E=i;d=g(this,b.a_2,5);if(d===0){this.A=a;return false}this.D=this._;switch(d){case 0:this.A=a;return false;case 1:if(!c(this,'')){return false}break;case 2:if(!c(this,'lös')){return false}break;case 3:if(!c(this,'full')){return false}break}this.A=a;return true};b.prototype.r_other_suffix=b.prototype.Q;function q(a){var e;var f;var d;var h;var i;var j;f=a.B-(h=a._);if(h<a.I_p1){return false}i=a._=a.I_p1;d=a.A;a.A=i;j=a._=a.B-f;a.E=j;e=g(a,b.a_2,5);if(e===0){a.A=d;return false}a.D=a._;switch(e){case 0:a.A=d;return false;case 1:if(!c(a,'')){return false}break;case 2:if(!c(a,'lös')){return false}break;case 3:if(!c(a,'full')){return false}break}a.A=d;return true};b.prototype.H=function(){var g;var f;var h;var b;var c;var a;var d;var i;var j;var k;var l;var e;g=this._;b=true;a:while(b===true){b=false;if(!D(this)){break a}}i=this._=g;this.A=i;k=this._=j=this.B;f=j-k;c=true;a:while(c===true){c=false;if(!w(this)){break a}}e=this._=(l=this.B)-f;h=l-e;a=true;a:while(a===true){a=false;if(!s(this)){break a}}this._=this.B-h;d=true;a:while(d===true){d=false;if(!q(this)){break a}}this._=this.A;return true};b.prototype.stem=b.prototype.H;b.prototype.L=function(a){return a instanceof b};b.prototype.equals=b.prototype.L;b.prototype.M=function(){var c;var a;var b;var d;c='SwedishStemmer';a=0;for(b=0;b<c.length;b++){d=c.charCodeAt(b);a=(a<<5)-a+d;a=a&a}return a|0};b.prototype.hashCode=b.prototype.M;b.serialVersionUID=1;h(b,'methodObject',function(){return new b});h(b,'a_0',function(){return[new a('a',-1,1),new a('arna',0,1),new a('erna',0,1),new a('heterna',2,1),new a('orna',0,1),new a('ad',-1,1),new a('e',-1,1),new a('ade',6,1),new a('ande',6,1),new a('arne',6,1),new a('are',6,1),new a('aste',6,1),new a('en',-1,1),new a('anden',12,1),new a('aren',12,1),new a('heten',12,1),new a('ern',-1,1),new a('ar',-1,1),new a('er',-1,1),new a('heter',18,1),new a('or',-1,1),new a('s',-1,2),new a('as',21,1),new a('arnas',22,1),new a('ernas',22,1),new a('ornas',22,1),new a('es',21,1),new a('ades',26,1),new a('andes',26,1),new a('ens',21,1),new a('arens',29,1),new a('hetens',29,1),new a('erns',21,1),new a('at',-1,1),new a('andet',-1,1),new a('het',-1,1),new a('ast',-1,1)]});h(b,'a_1',function(){return[new a('dd',-1,-1),new a('gd',-1,-1),new a('nn',-1,-1),new a('dt',-1,-1),new a('gt',-1,-1),new a('kt',-1,-1),new a('tt',-1,-1)]});h(b,'a_2',function(){return[new a('ig',-1,1),new a('lig',0,1),new a('els',-1,1),new a('fullt',-1,3),new a('löst',-1,2)]});h(b,'g_v',function(){return[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32]});h(b,'g_s_ending',function(){return[119,127,149]});var n={'src/stemmer.jsx':{Stemmer:j},'src/swedish-stemmer.jsx':{SwedishStemmer:b}}}(JSX))
+var Stemmer = JSX.require("src/swedish-stemmer.jsx").SwedishStemmer;
+"""
+
+
+class SearchSwedish(SearchLanguage):
+    lang = 'sv'
+    language_name = 'Swedish'
+    js_stemmer_code = js_stemmer
+    stopwords = swedish_stopwords
+
+    def init(self, options):
+        self.stemmer = snowballstemmer.stemmer('swedish')
+
+    def stem(self, word):
+        return self.stemmer.stemWord(word)
diff --git a/sphinx/search/tr.py b/sphinx/search/tr.py
new file mode 100644
index 0000000..52c5bb2
--- /dev/null
+++ b/sphinx/search/tr.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.search.tr
+    ~~~~~~~~~~~~~~~~
+
+    Turkish search language: includes the JS Turkish stemmer.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from sphinx.search import SearchLanguage
+
+import snowballstemmer
+
+js_stemmer = u"""
+var JSX={};(function(q){function r(b,e){var a=function(){};a.prototype=e.prototype;var c=new a;for(var d in b){b[d].prototype=c}}function Q(c,b){for(var a in b.prototype)if(b.prototype.hasOwnProperty(a))c.prototype[a]=b.prototype[a]}function j(a,b,d){function c(a,b,c){delete a[b];a[b]=c;return c}Object.defineProperty(a,b,{get:function(){return c(a,b,d())},set:function(d){c(a,b,d)},enumerable:true,configurable:true})}function R(a,b,c){return a[b]=a[b]/c|0}var M=parseInt;var K=parseFloat;function P(a){return a!==a}var A=isFinite;var G=encodeURIComponent;var F=decodeURIComponent;var E=encodeURI;var D=decodeURI;var C=Object.prototype.toString;var H=Object.prototype.hasOwnProperty;function p(){}q.require=function(b){var a=y[b];return a!==undefined?a:null};q.profilerIsRunning=function(){return p.getResults!=null};q.getProfileResults=function(){return(p.getResults||function(){return{}})()};q.postProfileResults=function(a,b){if(p.postResults==null)throw new Error('profiler has not been turned on');return p.postResults(a,b)};q.resetProfileResults=function(){if(p.resetResults==null)throw new Error('profiler has not been turned on');return p.resetResults()};q.DEBUG=false;function I(){};r([I],Error);function d(a,b,c){this.G=a.length;this.A_=a;this.D_=b;this.J=c;this.I=null;this.E_=null};r([d],Object);function u(){};r([u],Object);function m(){var a;var b;var c;this.F={};a=this.E='';b=this._=0;c=this.A=a.length;this.D=0;this.B=b;this.C=c};r([m],u);function B(a,b){a.E=b.E;a._=b._;a.A=b.A;a.D=b.D;a.B=b.B;a.C=b.C};function v(b,d,c,e){var a;if(b._>=b.A){return false}a=b.E.charCodeAt(b._);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._++;return true};function f(b,d,c,e){var a;if(b._<=b.D){return false}a=b.E.charCodeAt(b._-1);if(a>e||a<c){return false}a-=c;if((d[a>>>3]&1<<(a&7))===0){return false}b._--;return true};function t(a,d,c,e){var b;if(a._<=a.D){return false}b=a.E.charCodeAt(a._-1);if(b>e||b<c){a._--;return true}b-=c;if((d[b>>>3]&1<<(b&7))===0){a._--;return true}return false};function s(a,b,d){var c;if(a.A-a._<b){return false}if(a.E.slice(c=a._,c+b)!==d){return false}a._+=b;return true};function g(a,b,d){var c;if(a._-a.D<b){return false}if(a.E.slice((c=a._)-b,c)!==d){return false}a._-=b;return true};function b(d,m,p){var b;var g;var e;var n;var f;var k;var l;var i;var h;var c;var a;var j;var o;b=0;g=p;e=d._;n=d.D;f=0;k=0;l=false;while(true){i=b+(g-b>>1);h=0;c=f<k?f:k;a=m[i];for(j=a.G-1-c;j>=0;j--){if(e-c===n){h=-1;break}h=d.E.charCodeAt(e-1-c)-a.A_.charCodeAt(j);if(h!==0){break}c++}if(h<0){g=i;k=c}else{b=i;f=c}if(g-b<=1){if(b>0){break}if(g===b){break}if(l){break}l=true}}while(true){a=m[b];if(f>=a.G){d._=e-a.G|0;if(a.I==null){return a.J}o=a.I(d);d._=e-a.G|0;if(o){return a.J}}b=a.D_;if(b<0){return 0}}return-1};function n(a,b,d,e){var c;c=e.length-(d-b);a.E=a.E.slice(0,b)+e+a.E.slice(d);a.A+=c|0;if(a._>=d){a._+=c|0}else if(a._>b){a._=b}return c|0};function e(a,f){var b;var c;var d;var e;b=false;if((c=a.B)<0||c>(d=a.C)||d>(e=a.A)||e>a.E.length?false:true){n(a,a.B,a.C,f);b=true}return b};m.prototype.H=function(){return false};m.prototype.B_=function(b){var a;var c;var d;var e;a=this.F['.'+b];if(a==null){c=this.E=b;d=this._=0;e=this.A=c.length;this.D=0;this.B=d;this.C=e;this.H();a=this.E;this.F['.'+b]=a}return a};m.prototype.stemWord=m.prototype.B_;m.prototype.C_=function(e){var d;var b;var c;var a;var f;var g;var h;d=[];for(b=0;b<e.length;b++){c=e[b];a=this.F['.'+c];if(a==null){f=this.E=c;g=this._=0;h=this.A=f.length;this.D=0;this.B=g;this.C=h;this.H();a=this.E;this.F['.'+c]=a}d.push(a)}return d};m.prototype.stemWords=m.prototype.C_;function a(){m.call(this);this.B_continue_stemming_noun_suffixes=false;this.I_strlen=0};r([a],m);a.prototype.K=function(a){this.B_continue_stemming_noun_suffixes=a.B_continue_stemming_noun_suffixes;this.I_strlen=a.I_strlen;B(this,a)};a.prototype.copy_from=a.prototype.K;a.prototype.O=function(){var E;var q;var b;var e;var h;var i;var j;var k;var l;var m;var n;var o;var p;var c;var r;var s;var t;var u;var d;var v;var w;var x;var y;var z;var A;var B;var C;var D;var G;var H;var I;var J;var K;var L;var M;var N;var F;E=this.A-this._;b:while(true){q=this.A-this._;o=true;a:while(o===true){o=false;if(!f(this,a.g_vowel,97,305)){break a}this._=this.A-q;break b}G=this._=this.A-q;if(G<=this.D){return false}this._--}p=true;a:while(p===true){p=false;b=this.A-this._;c=true;b:while(c===true){c=false;if(!g(this,1,'a')){break b}c:while(true){e=this.A-this._;r=true;d:while(r===true){r=false;if(!f(this,a.g_vowel1,97,305)){break d}this._=this.A-e;break c}H=this._=this.A-e;if(H<=this.D){break b}this._--}break a}this._=this.A-b;s=true;b:while(s===true){s=false;if(!g(this,1,'e')){break b}c:while(true){h=this.A-this._;t=true;d:while(t===true){t=false;if(!f(this,a.g_vowel2,101,252)){break d}this._=this.A-h;break c}I=this._=this.A-h;if(I<=this.D){break b}this._--}break a}this._=this.A-b;u=true;b:while(u===true){u=false;if(!g(this,1,'ı')){break b}c:while(true){i=this.A-this._;d=true;d:while(d===true){d=false;if(!f(this,a.g_vowel3,97,305)){break d}this._=this.A-i;break c}J=this._=this.A-i;if(J<=this.D){break b}this._--}break a}this._=this.A-b;v=true;b:while(v===true){v=false;if(!g(this,1,'i')){break b}c:while(true){j=this.A-this._;w=true;d:while(w===true){w=false;if(!f(this,a.g_vowel4,101,105)){break d}this._=this.A-j;break c}K=this._=this.A-j;if(K<=this.D){break b}this._--}break a}this._=this.A-b;x=true;b:while(x===true){x=false;if(!g(this,1,'o')){break b}c:while(true){k=this.A-this._;y=true;d:while(y===true){y=false;if(!f(this,a.g_vowel5,111,117)){break d}this._=this.A-k;break c}L=this._=this.A-k;if(L<=this.D){break b}this._--}break a}this._=this.A-b;z=true;b:while(z===true){z=false;if(!g(this,1,'ö')){break b}c:while(true){l=this.A-this._;A=true;d:while(A===true){A=false;if(!f(this,a.g_vowel6,246,252)){break d}this._=this.A-l;break c}M=this._=this.A-l;if(M<=this.D){break b}this._--}break a}this._=this.A-b;B=true;b:while(B===true){B=false;if(!g(this,1,'u')){break b}c:while(true){m=this.A-this._;C=true;d:while(C===true){C=false;if(!f(this,a.g_vowel5,111,117)){break d}this._=this.A-m;break c}N=this._=this.A-m;if(N<=this.D){break b}this._--}break a}this._=this.A-b;if(!g(this,1,'ü')){return false}b:while(true){n=this.A-this._;D=true;c:while(D===true){D=false;if(!f(this,a.g_vowel6,246,252)){break c}this._=this.A-n;break b}F=this._=this.A-n;if(F<=this.D){return false}this._--}}this._=this.A-E;return true};a.prototype.r_check_vowel_harmony=a.prototype.O;function c(b){var F;var r;var c;var e;var h;var i;var j;var k;var l;var m;var n;var o;var p;var q;var d;var s;var t;var u;var v;var w;var x;var y;var z;var A;var B;var C;var D;var E;var H;var I;var J;var K;var L;var M;var N;var O;var G;F=b.A-b._;b:while(true){r=b.A-b._;o=true;a:while(o===true){o=false;if(!f(b,a.g_vowel,97,305)){break a}b._=b.A-r;break b}H=b._=b.A-r;if(H<=b.D){return false}b._--}p=true;a:while(p===true){p=false;c=b.A-b._;q=true;b:while(q===true){q=false;if(!g(b,1,'a')){break b}c:while(true){e=b.A-b._;d=true;d:while(d===true){d=false;if(!f(b,a.g_vowel1,97,305)){break d}b._=b.A-e;break c}I=b._=b.A-e;if(I<=b.D){break b}b._--}break a}b._=b.A-c;s=true;b:while(s===true){s=false;if(!g(b,1,'e')){break b}c:while(true){h=b.A-b._;t=true;d:while(t===true){t=false;if(!f(b,a.g_vowel2,101,252)){break d}b._=b.A-h;break c}J=b._=b.A-h;if(J<=b.D){break b}b._--}break a}b._=b.A-c;u=true;b:while(u===true){u=false;if(!g(b,1,'ı')){break b}c:while(true){i=b.A-b._;v=true;d:while(v===true){v=false;if(!f(b,a.g_vowel3,97,305)){break d}b._=b.A-i;break c}K=b._=b.A-i;if(K<=b.D){break b}b._--}break a}b._=b.A-c;w=true;b:while(w===true){w=false;if(!g(b,1,'i')){break b}c:while(true){j=b.A-b._;x=true;d:while(x===true){x=false;if(!f(b,a.g_vowel4,101,105)){break d}b._=b.A-j;break c}L=b._=b.A-j;if(L<=b.D){break b}b._--}break a}b._=b.A-c;y=true;b:while(y===true){y=false;if(!g(b,1,'o')){break b}c:while(true){k=b.A-b._;z=true;d:while(z===true){z=false;if(!f(b,a.g_vowel5,111,117)){break d}b._=b.A-k;break c}M=b._=b.A-k;if(M<=b.D){break b}b._--}break a}b._=b.A-c;A=true;b:while(A===true){A=false;if(!g(b,1,'ö')){break b}c:while(true){l=b.A-b._;B=true;d:while(B===true){B=false;if(!f(b,a.g_vowel6,246,252)){break d}b._=b.A-l;break c}N=b._=b.A-l;if(N<=b.D){break b}b._--}break a}b._=b.A-c;C=true;b:while(C===true){C=false;if(!g(b,1,'u')){break b}c:while(true){m=b.A-b._;D=true;d:while(D===true){D=false;if(!f(b,a.g_vowel5,111,117)){break d}b._=b.A-m;break c}O=b._=b.A-m;if(O<=b.D){break b}b._--}break a}b._=b.A-c;if(!g(b,1,'ü')){return false}b:while(true){n=b.A-b._;E=true;c:while(E===true){E=false;if(!f(b,a.g_vowel6,246,252)){break c}b._=b.A-n;break b}G=b._=b.A-n;if(G<=b.D){return false}b._--}}b._=b.A-F;return true};a.prototype.j=function(){var k;var h;var l;var i;var m;var j;var b;var e;var d;var n;var o;var p;var q;var c;b=true;b:while(b===true){b=false;k=this.A-this._;e=true;a:while(e===true){e=false;h=this.A-this._;if(!g(this,1,'n')){break a}n=this._=this.A-h;if(n<=this.D){break a}this._--;l=this.A-this._;if(!f(this,a.g_vowel,97,305)){break a}this._=this.A-l;break b}p=this._=(o=this.A)-k;i=o-p;d=true;a:while(d===true){d=false;m=this.A-this._;if(!g(this,1,'n')){break a}this._=this.A-m;return false}c=this._=(q=this.A)-i;j=q-c;if(c<=this.D){return false}this._--;if(!f(this,a.g_vowel,97,305)){return false}this._=this.A-j}return true};a.prototype.r_mark_suffix_with_optional_n_consonant=a.prototype.j;function o(b){var i;var m;var l;var j;var n;var k;var c;var e;var d;var o;var p;var q;var r;var h;c=true;b:while(c===true){c=false;i=b.A-b._;e=true;a:while(e===true){e=false;m=b.A-b._;if(!g(b,1,'n')){break a}o=b._=b.A-m;if(o<=b.D){break a}b._--;l=b.A-b._;if(!f(b,a.g_vowel,97,305)){break a}b._=b.A-l;break b}q=b._=(p=b.A)-i;j=p-q;d=true;a:while(d===true){d=false;n=b.A-b._;if(!g(b,1,'n')){break a}b._=b.A-n;return false}h=b._=(r=b.A)-j;k=r-h;if(h<=b.D){return false}b._--;if(!f(b,a.g_vowel,97,305)){return false}b._=b.A-k}return true};a.prototype.k=function(){var k;var h;var l;var i;var m;var j;var b;var e;var d;var n;var o;var p;var q;var c;b=true;b:while(b===true){b=false;k=this.A-this._;e=true;a:while(e===true){e=false;h=this.A-this._;if(!g(this,1,'s')){break a}n=this._=this.A-h;if(n<=this.D){break a}this._--;l=this.A-this._;if(!f(this,a.g_vowel,97,305)){break a}this._=this.A-l;break b}p=this._=(o=this.A)-k;i=o-p;d=true;a:while(d===true){d=false;m=this.A-this._;if(!g(this,1,'s')){break a}this._=this.A-m;return false}c=this._=(q=this.A)-i;j=q-c;if(c<=this.D){return false}this._--;if(!f(this,a.g_vowel,97,305)){return false}this._=this.A-j}return true};a.prototype.r_mark_suffix_with_optional_s_consonant=a.prototype.k;function l(b){var i;var m;var l;var j;var n;var k;var c;var e;var d;var o;var p;var q;var r;var h;c=true;b:while(c===true){c=false;i=b.A-b._;e=true;a:while(e===true){e=false;m=b.A-b._;if(!g(b,1,'s')){break a}o=b._=b.A-m;if(o<=b.D){break a}b._--;l=b.A-b._;if(!f(b,a.g_vowel,97,305)){break a}b._=b.A-l;break b}q=b._=(p=b.A)-i;j=p-q;d=true;a:while(d===true){d=false;n=b.A-b._;if(!g(b,1,'s')){break a}b._=b.A-n;return false}h=b._=(r=b.A)-j;k=r-h;if(h<=b.D){return false}b._--;if(!f(b,a.g_vowel,97,305)){return false}b._=b.A-k}return true};a.prototype.l=function(){var k;var h;var l;var i;var m;var j;var b;var e;var d;var n;var o;var p;var q;var c;b=true;b:while(b===true){b=false;k=this.A-this._;e=true;a:while(e===true){e=false;h=this.A-this._;if(!g(this,1,'y')){break a}n=this._=this.A-h;if(n<=this.D){break a}this._--;l=this.A-this._;if(!f(this,a.g_vowel,97,305)){break a}this._=this.A-l;break b}p=this._=(o=this.A)-k;i=o-p;d=true;a:while(d===true){d=false;m=this.A-this._;if(!g(this,1,'y')){break a}this._=this.A-m;return false}c=this._=(q=this.A)-i;j=q-c;if(c<=this.D){return false}this._--;if(!f(this,a.g_vowel,97,305)){return false}this._=this.A-j}return true};a.prototype.r_mark_suffix_with_optional_y_consonant=a.prototype.l;function h(b){var i;var m;var l;var j;var n;var k;var c;var e;var d;var o;var p;var q;var r;var h;c=true;b:while(c===true){c=false;i=b.A-b._;e=true;a:while(e===true){e=false;m=b.A-b._;if(!g(b,1,'y')){break a}o=b._=b.A-m;if(o<=b.D){break a}b._--;l=b.A-b._;if(!f(b,a.g_vowel,97,305)){break a}b._=b.A-l;break b}q=b._=(p=b.A)-i;j=p-q;d=true;a:while(d===true){d=false;n=b.A-b._;if(!g(b,1,'y')){break a}b._=b.A-n;return false}h=b._=(r=b.A)-j;k=r-h;if(h<=b.D){return false}b._--;if(!f(b,a.g_vowel,97,305)){return false}b._=b.A-k}return true};a.prototype.i=function(){var j;var g;var k;var h;var l;var i;var b;var e;var d;var m;var n;var o;var p;var c;b=true;b:while(b===true){b=false;j=this.A-this._;e=true;a:while(e===true){e=false;g=this.A-this._;if(!f(this,a.g_U,105,305)){break a}m=this._=this.A-g;if(m<=this.D){break a}this._--;k=this.A-this._;if(!t(this,a.g_vowel,97,305)){break a}this._=this.A-k;break b}o=this._=(n=this.A)-j;h=n-o;d=true;a:while(d===true){d=false;l=this.A-this._;if(!f(this,a.g_U,105,305)){break a}this._=this.A-l;return false}c=this._=(p=this.A)-h;i=p-c;if(c<=this.D){return false}this._--;if(!t(this,a.g_vowel,97,305)){return false}this._=this.A-i}return true};a.prototype.r_mark_suffix_with_optional_U_vowel=a.prototype.i;function k(b){var h;var l;var k;var i;var m;var j;var c;var e;var d;var n;var o;var p;var q;var g;c=true;b:while(c===true){c=false;h=b.A-b._;e=true;a:while(e===true){e=false;l=b.A-b._;if(!f(b,a.g_U,105,305)){break a}n=b._=b.A-l;if(n<=b.D){break a}b._--;k=b.A-b._;if(!t(b,a.g_vowel,97,305)){break a}b._=b.A-k;break b}p=b._=(o=b.A)-h;i=o-p;d=true;a:while(d===true){d=false;m=b.A-b._;if(!f(b,a.g_U,105,305)){break a}b._=b.A-m;return false}g=b._=(q=b.A)-i;j=q-g;if(g<=b.D){return false}b._--;if(!t(b,a.g_vowel,97,305)){return false}b._=b.A-j}return true};a.prototype.e=function(){return b(this,a.a_0,10)===0?false:!k(this)?false:true};a.prototype.r_mark_possessives=a.prototype.e;a.prototype.f=function(){return!c(this)?false:!f(this,a.g_U,105,305)?false:!l(this)?false:true};a.prototype.r_mark_sU=a.prototype.f;a.prototype.W=function(){return b(this,a.a_1,2)===0?false:true};a.prototype.r_mark_lArI=a.prototype.W;a.prototype.o=function(){return!c(this)?false:!f(this,a.g_U,105,305)?false:!h(this)?false:true};a.prototype.r_mark_yU=a.prototype.o;a.prototype.Y=function(){return!c(this)?false:b(this,a.a_2,4)===0?false:true};a.prototype.r_mark_nU=a.prototype.Y;a.prototype.Z=function(){return!c(this)?false:b(this,a.a_3,4)===0?false:!o(this)?false:true};a.prototype.r_mark_nUn=a.prototype.Z;a.prototype.m=function(){return!c(this)?false:b(this,a.a_4,2)===0?false:!h(this)?false:true};a.prototype.r_mark_yA=a.prototype.m;a.prototype.X=function(){return!c(this)?false:b(this,a.a_5,2)===0?false:true};a.prototype.r_mark_nA=a.prototype.X;a.prototype.Q=function(){return!c(this)?false:b(this,a.a_6,4)===0?false:true};a.prototype.r_mark_DA=a.prototype.Q;a.prototype.c=function(){return!c(this)?false:b(this,a.a_7,2)===0?false:true};a.prototype.r_mark_ndA=a.prototype.c;a.prototype.R=function(){return!c(this)?false:b(this,a.a_8,4)===0?false:true};a.prototype.r_mark_DAn=a.prototype.R;a.prototype.d=function(){return!c(this)?false:b(this,a.a_9,2)===0?false:true};a.prototype.r_mark_ndAn=a.prototype.d;a.prototype.s=function(){return!c(this)?false:b(this,a.a_10,2)===0?false:!h(this)?false:true};a.prototype.r_mark_ylA=a.prototype.s;a.prototype.U=function(){return!g(this,2,'ki')?false:true};a.prototype.r_mark_ki=a.prototype.U;a.prototype.b=function(){return!c(this)?false:b(this,a.a_11,2)===0?false:!o(this)?false:true};a.prototype.r_mark_ncA=a.prototype.b;a.prototype.p=function(){return!c(this)?false:b(this,a.a_12,4)===0?false:!h(this)?false:true};a.prototype.r_mark_yUm=a.prototype.p;a.prototype.g=function(){return!c(this)?false:b(this,a.a_13,4)===0?false:true};a.prototype.r_mark_sUn=a.prototype.g;a.prototype.q=function(){return!c(this)?false:b(this,a.a_14,4)===0?false:!h(this)?false:true};a.prototype.r_mark_yUz=a.prototype.q;a.prototype.h=function(){return b(this,a.a_15,4)===0?false:true};a.prototype.r_mark_sUnUz=a.prototype.h;a.prototype.V=function(){return!c(this)?false:b(this,a.a_16,2)===0?false:true};a.prototype.r_mark_lAr=a.prototype.V;a.prototype.a=function(){return!c(this)?false:b(this,a.a_17,4)===0?false:true};a.prototype.r_mark_nUz=a.prototype.a;a.prototype.S=function(){return!c(this)?false:b(this,a.a_18,8)===0?false:true};a.prototype.r_mark_DUr=a.prototype.S;a.prototype.T=function(){return b(this,a.a_19,2)===0?false:true};a.prototype.r_mark_cAsInA=a.prototype.T;a.prototype.n=function(){return!c(this)?false:b(this,a.a_20,32)===0?false:!h(this)?false:true};a.prototype.r_mark_yDU=a.prototype.n;a.prototype.u=function(){return b(this,a.a_21,8)===0?false:!h(this)?false:true};a.prototype.r_mark_ysA=a.prototype.u;a.prototype.t=function(){return!c(this)?false:b(this,a.a_22,4)===0?false:!h(this)?false:true};a.prototype.r_mark_ymUs_=a.prototype.t;a.prototype.r=function(){return!g(this,3,'ken')?false:!h(this)?false:true};a.prototype.r_mark_yken=a.prototype.r;a.prototype.y=function(){var i;var j;var d;var Y;var k;var X;var l;var W;var V;var f;var r;var s;var t;var u;var v;var w;var x;var y;var z;var A;var B;var C;var m;var E;var F;var G;var H;var I;var J;var K;var L;var M;var N;var O;var P;var Q;var R;var S;var T;var U;var p;var o;var D;var n;var q;this.C=this._;this.B_continue_stemming_noun_suffixes=true;r=true;a:while(r===true){r=false;i=this.A-this._;s=true;d:while(s===true){s=false;t=true;b:while(t===true){t=false;j=this.A-this._;u=true;c:while(u===true){u=false;if(!(!c(this)?false:b(this,a.a_22,4)===0?false:!h(this)?false:true)){break c}break b}this._=this.A-j;v=true;c:while(v===true){v=false;if(!(!c(this)?false:b(this,a.a_20,32)===0?false:!h(this)?false:true)){break c}break b}this._=this.A-j;w=true;c:while(w===true){w=false;if(!(b(this,a.a_21,8)===0?false:!h(this)?false:true)){break c}break b}this._=this.A-j;if(!(!g(this,3,'ken')?false:!h(this)?false:true)){break d}}break a}this._=this.A-i;x=true;c:while(x===true){x=false;if(!(b(this,a.a_19,2)===0?false:true)){break c}y=true;b:while(y===true){y=false;d=this.A-this._;z=true;d:while(z===true){z=false;if(!(b(this,a.a_15,4)===0?false:true)){break d}break b}this._=this.A-d;A=true;d:while(A===true){A=false;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){break d}break b}this._=this.A-d;B=true;d:while(B===true){B=false;if(!(!c(this)?false:b(this,a.a_12,4)===0?false:!h(this)?false:true)){break d}break b}this._=this.A-d;C=true;d:while(C===true){C=false;if(!(!c(this)?false:b(this,a.a_13,4)===0?false:true)){break d}break b}this._=this.A-d;m=true;d:while(m===true){m=false;if(!(!c(this)?false:b(this,a.a_14,4)===0?false:!h(this)?false:true)){break d}break b}this._=this.A-d}if(!(!c(this)?false:b(this,a.a_22,4)===0?false:!h(this)?false:true)){break c}break a}this._=this.A-i;E=true;c:while(E===true){E=false;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){break c}this.B=this._;if(!e(this,'')){return false}Y=this.A-this._;F=true;d:while(F===true){F=false;this.C=this._;G=true;b:while(G===true){G=false;k=this.A-this._;H=true;e:while(H===true){H=false;if(!(!c(this)?false:b(this,a.a_18,8)===0?false:true)){break e}break b}this._=this.A-k;I=true;e:while(I===true){I=false;if(!(!c(this)?false:b(this,a.a_20,32)===0?false:!h(this)?false:true)){break e}break b}this._=this.A-k;J=true;e:while(J===true){J=false;if(!(b(this,a.a_21,8)===0?false:!h(this)?false:true)){break e}break b}this._=this.A-k;if(!(!c(this)?false:b(this,a.a_22,4)===0?false:!h(this)?false:true)){this._=this.A-Y;break d}}}this.B_continue_stemming_noun_suffixes=false;break a}this._=this.A-i;K=true;b:while(K===true){K=false;if(!(!c(this)?false:b(this,a.a_17,4)===0?false:true)){break b}L=true;c:while(L===true){L=false;X=this.A-this._;M=true;d:while(M===true){M=false;if(!(!c(this)?false:b(this,a.a_20,32)===0?false:!h(this)?false:true)){break d}break c}this._=this.A-X;if(!(b(this,a.a_21,8)===0?false:!h(this)?false:true)){break b}}break a}this._=this.A-i;N=true;c:while(N===true){N=false;O=true;b:while(O===true){O=false;l=this.A-this._;P=true;d:while(P===true){P=false;if(!(b(this,a.a_15,4)===0?false:true)){break d}break b}this._=this.A-l;Q=true;d:while(Q===true){Q=false;if(!(!c(this)?false:b(this,a.a_14,4)===0?false:!h(this)?false:true)){break d}break b}this._=this.A-l;R=true;d:while(R===true){R=false;if(!(!c(this)?false:b(this,a.a_13,4)===0?false:true)){break d}break b}this._=this.A-l;if(!(!c(this)?false:b(this,a.a_12,4)===0?false:!h(this)?false:true)){break c}}this.B=this._;if(!e(this,'')){return false}W=this.A-this._;S=true;b:while(S===true){S=false;this.C=this._;if(!(!c(this)?false:b(this,a.a_22,4)===0?false:!h(this)?false:true)){this._=this.A-W;break b}}break a}this._=this.A-i;if(!(!c(this)?false:b(this,a.a_18,8)===0?false:true)){return false}this.B=this._;if(!e(this,'')){return false}V=this.A-this._;T=true;d:while(T===true){T=false;this.C=this._;U=true;b:while(U===true){U=false;f=this.A-this._;p=true;c:while(p===true){p=false;if(!(b(this,a.a_15,4)===0?false:true)){break c}break b}this._=this.A-f;o=true;c:while(o===true){o=false;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){break c}break b}this._=this.A-f;D=true;c:while(D===true){D=false;if(!(!c(this)?false:b(this,a.a_12,4)===0?false:!h(this)?false:true)){break c}break b}this._=this.A-f;n=true;c:while(n===true){n=false;if(!(!c(this)?false:b(this,a.a_13,4)===0?false:true)){break c}break b}this._=this.A-f;q=true;c:while(q===true){q=false;if(!(!c(this)?false:b(this,a.a_14,4)===0?false:!h(this)?false:true)){break c}break b}this._=this.A-f}if(!(!c(this)?false:b(this,a.a_22,4)===0?false:!h(this)?false:true)){this._=this.A-V;break d}}}this.B=this._;return!e(this,'')?false:true};a.prototype.r_stem_nominal_verb_suffixes=a.prototype.y;function J(d){var f;var k;var i;var Z;var l;var Y;var m;var X;var W;var j;var s;var t;var u;var v;var w;var x;var y;var z;var A;var B;var C;var n;var E;var F;var G;var H;var I;var J;var K;var L;var M;var N;var O;var P;var Q;var R;var S;var T;var U;var V;var q;var p;var D;var o;var r;d.C=d._;d.B_continue_stemming_noun_suffixes=true;s=true;a:while(s===true){s=false;f=d.A-d._;t=true;d:while(t===true){t=false;u=true;b:while(u===true){u=false;k=d.A-d._;v=true;c:while(v===true){v=false;if(!(!c(d)?false:b(d,a.a_22,4)===0?false:!h(d)?false:true)){break c}break b}d._=d.A-k;w=true;c:while(w===true){w=false;if(!(!c(d)?false:b(d,a.a_20,32)===0?false:!h(d)?false:true)){break c}break b}d._=d.A-k;x=true;c:while(x===true){x=false;if(!(b(d,a.a_21,8)===0?false:!h(d)?false:true)){break c}break b}d._=d.A-k;if(!(!g(d,3,'ken')?false:!h(d)?false:true)){break d}}break a}d._=d.A-f;y=true;c:while(y===true){y=false;if(!(b(d,a.a_19,2)===0?false:true)){break c}z=true;b:while(z===true){z=false;i=d.A-d._;A=true;d:while(A===true){A=false;if(!(b(d,a.a_15,4)===0?false:true)){break d}break b}d._=d.A-i;B=true;d:while(B===true){B=false;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){break d}break b}d._=d.A-i;C=true;d:while(C===true){C=false;if(!(!c(d)?false:b(d,a.a_12,4)===0?false:!h(d)?false:true)){break d}break b}d._=d.A-i;n=true;d:while(n===true){n=false;if(!(!c(d)?false:b(d,a.a_13,4)===0?false:true)){break d}break b}d._=d.A-i;E=true;d:while(E===true){E=false;if(!(!c(d)?false:b(d,a.a_14,4)===0?false:!h(d)?false:true)){break d}break b}d._=d.A-i}if(!(!c(d)?false:b(d,a.a_22,4)===0?false:!h(d)?false:true)){break c}break a}d._=d.A-f;F=true;c:while(F===true){F=false;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){break c}d.B=d._;if(!e(d,'')){return false}Z=d.A-d._;G=true;d:while(G===true){G=false;d.C=d._;H=true;b:while(H===true){H=false;l=d.A-d._;I=true;e:while(I===true){I=false;if(!(!c(d)?false:b(d,a.a_18,8)===0?false:true)){break e}break b}d._=d.A-l;J=true;e:while(J===true){J=false;if(!(!c(d)?false:b(d,a.a_20,32)===0?false:!h(d)?false:true)){break e}break b}d._=d.A-l;K=true;e:while(K===true){K=false;if(!(b(d,a.a_21,8)===0?false:!h(d)?false:true)){break e}break b}d._=d.A-l;if(!(!c(d)?false:b(d,a.a_22,4)===0?false:!h(d)?false:true)){d._=d.A-Z;break d}}}d.B_continue_stemming_noun_suffixes=false;break a}d._=d.A-f;L=true;b:while(L===true){L=false;if(!(!c(d)?false:b(d,a.a_17,4)===0?false:true)){break b}M=true;c:while(M===true){M=false;Y=d.A-d._;N=true;d:while(N===true){N=false;if(!(!c(d)?false:b(d,a.a_20,32)===0?false:!h(d)?false:true)){break d}break c}d._=d.A-Y;if(!(b(d,a.a_21,8)===0?false:!h(d)?false:true)){break b}}break a}d._=d.A-f;O=true;c:while(O===true){O=false;P=true;b:while(P===true){P=false;m=d.A-d._;Q=true;d:while(Q===true){Q=false;if(!(b(d,a.a_15,4)===0?false:true)){break d}break b}d._=d.A-m;R=true;d:while(R===true){R=false;if(!(!c(d)?false:b(d,a.a_14,4)===0?false:!h(d)?false:true)){break d}break b}d._=d.A-m;S=true;d:while(S===true){S=false;if(!(!c(d)?false:b(d,a.a_13,4)===0?false:true)){break d}break b}d._=d.A-m;if(!(!c(d)?false:b(d,a.a_12,4)===0?false:!h(d)?false:true)){break c}}d.B=d._;if(!e(d,'')){return false}X=d.A-d._;T=true;b:while(T===true){T=false;d.C=d._;if(!(!c(d)?false:b(d,a.a_22,4)===0?false:!h(d)?false:true)){d._=d.A-X;break b}}break a}d._=d.A-f;if(!(!c(d)?false:b(d,a.a_18,8)===0?false:true)){return false}d.B=d._;if(!e(d,'')){return false}W=d.A-d._;U=true;d:while(U===true){U=false;d.C=d._;V=true;b:while(V===true){V=false;j=d.A-d._;q=true;c:while(q===true){q=false;if(!(b(d,a.a_15,4)===0?false:true)){break c}break b}d._=d.A-j;p=true;c:while(p===true){p=false;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){break c}break b}d._=d.A-j;D=true;c:while(D===true){D=false;if(!(!c(d)?false:b(d,a.a_12,4)===0?false:!h(d)?false:true)){break c}break b}d._=d.A-j;o=true;c:while(o===true){o=false;if(!(!c(d)?false:b(d,a.a_13,4)===0?false:true)){break c}break b}d._=d.A-j;r=true;c:while(r===true){r=false;if(!(!c(d)?false:b(d,a.a_14,4)===0?false:!h(d)?false:true)){break c}break b}d._=d.A-j}if(!(!c(d)?false:b(d,a.a_22,4)===0?false:!h(d)?false:true)){d._=d.A-W;break d}}}d.B=d._;return!e(d,'')?false:true};a.prototype.__=function(){var z;var N;var M;var L;var p;var K;var r;var J;var t;var u;var v;var w;var x;var y;var d;var A;var B;var C;var D;var E;var F;var G;var H;var I;var s;var q;var n;var m;var j;var h;this.C=this._;if(!(!g(this,2,'ki')?false:true)){return false}w=true;b:while(w===true){w=false;z=this.A-this._;x=true;c:while(x===true){x=false;if(!(!c(this)?false:b(this,a.a_6,4)===0?false:true)){break c}this.B=this._;if(!e(this,'')){return false}N=this.A-this._;y=true;f:while(y===true){y=false;this.C=this._;d=true;e:while(d===true){d=false;M=this.A-this._;A=true;d:while(A===true){A=false;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){break d}this.B=this._;if(!e(this,'')){return false}L=this.A-this._;B=true;a:while(B===true){B=false;if(!i(this)){this._=this.A-L;break a}}break e}this._=this.A-M;if(!(b(this,a.a_0,10)===0?false:!k(this)?false:true)){this._=this.A-N;break f}this.B=this._;if(!e(this,'')){return false}p=this.A-this._;C=true;a:while(C===true){C=false;this.C=this._;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){this._=this.A-p;break a}this.B=this._;if(!e(this,'')){return false}if(!i(this)){this._=this.A-p;break a}}}}break b}this._=this.A-z;D=true;d:while(D===true){D=false;if(!(!c(this)?false:b(this,a.a_3,4)===0?false:!o(this)?false:true)){break d}this.B=this._;if(!e(this,'')){return false}K=this.A-this._;E=true;e:while(E===true){E=false;this.C=this._;F=true;a:while(F===true){F=false;r=this.A-this._;G=true;c:while(G===true){G=false;if(!(b(this,a.a_1,2)===0?false:true)){break c}this.B=this._;if(!e(this,'')){return false}break a}this._=this.A-r;H=true;f:while(H===true){H=false;this.C=this._;I=true;g:while(I===true){I=false;J=this.A-this._;s=true;c:while(s===true){s=false;if(!(b(this,a.a_0,10)===0?false:!k(this)?false:true)){break c}break g}this._=this.A-J;if(!(!c(this)?false:!f(this,a.g_U,105,305)?false:!l(this)?false:true)){break f}}this.B=this._;if(!e(this,'')){return false}t=this.A-this._;q=true;c:while(q===true){q=false;this.C=this._;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){this._=this.A-t;break c}this.B=this._;if(!e(this,'')){return false}if(!i(this)){this._=this.A-t;break c}}break a}this._=this.A-r;if(!i(this)){this._=this.A-K;break e}}}break b}this._=this.A-z;if(!(!c(this)?false:b(this,a.a_7,2)===0?false:true)){return false}n=true;a:while(n===true){n=false;u=this.A-this._;m=true;c:while(m===true){m=false;if(!(b(this,a.a_1,2)===0?false:true)){break c}this.B=this._;if(!e(this,'')){return false}break a}this._=this.A-u;j=true;d:while(j===true){j=false;if(!(!c(this)?false:!f(this,a.g_U,105,305)?false:!l(this)?false:true)){break d}this.B=this._;if(!e(this,'')){return false}v=this.A-this._;h=true;c:while(h===true){h=false;this.C=this._;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){this._=this.A-v;break c}this.B=this._;if(!e(this,'')){return false}if(!i(this)){this._=this.A-v;break c}}break a}this._=this.A-u;if(!i(this)){return false}}}return true};a.prototype.r_stem_suffix_chain_before_ki=a.prototype.__;function i(d){var j;var O;var N;var M;var q;var L;var s;var K;var u;var v;var w;var x;var y;var z;var h;var B;var C;var D;var E;var F;var G;var H;var I;var J;var t;var r;var p;var n;var m;var A;d.C=d._;if(!(!g(d,2,'ki')?false:true)){return false}x=true;b:while(x===true){x=false;j=d.A-d._;y=true;c:while(y===true){y=false;if(!(!c(d)?false:b(d,a.a_6,4)===0?false:true)){break c}d.B=d._;if(!e(d,'')){return false}O=d.A-d._;z=true;f:while(z===true){z=false;d.C=d._;h=true;e:while(h===true){h=false;N=d.A-d._;B=true;d:while(B===true){B=false;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){break d}d.B=d._;if(!e(d,'')){return false}M=d.A-d._;C=true;a:while(C===true){C=false;if(!i(d)){d._=d.A-M;break a}}break e}d._=d.A-N;if(!(b(d,a.a_0,10)===0?false:!k(d)?false:true)){d._=d.A-O;break f}d.B=d._;if(!e(d,'')){return false}q=d.A-d._;D=true;a:while(D===true){D=false;d.C=d._;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){d._=d.A-q;break a}d.B=d._;if(!e(d,'')){return false}if(!i(d)){d._=d.A-q;break a}}}}break b}d._=d.A-j;E=true;d:while(E===true){E=false;if(!(!c(d)?false:b(d,a.a_3,4)===0?false:!o(d)?false:true)){break d}d.B=d._;if(!e(d,'')){return false}L=d.A-d._;F=true;e:while(F===true){F=false;d.C=d._;G=true;a:while(G===true){G=false;s=d.A-d._;H=true;c:while(H===true){H=false;if(!(b(d,a.a_1,2)===0?false:true)){break c}d.B=d._;if(!e(d,'')){return false}break a}d._=d.A-s;I=true;f:while(I===true){I=false;d.C=d._;J=true;g:while(J===true){J=false;K=d.A-d._;t=true;c:while(t===true){t=false;if(!(b(d,a.a_0,10)===0?false:!k(d)?false:true)){break c}break g}d._=d.A-K;if(!(!c(d)?false:!f(d,a.g_U,105,305)?false:!l(d)?false:true)){break f}}d.B=d._;if(!e(d,'')){return false}u=d.A-d._;r=true;c:while(r===true){r=false;d.C=d._;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){d._=d.A-u;break c}d.B=d._;if(!e(d,'')){return false}if(!i(d)){d._=d.A-u;break c}}break a}d._=d.A-s;if(!i(d)){d._=d.A-L;break e}}}break b}d._=d.A-j;if(!(!c(d)?false:b(d,a.a_7,2)===0?false:true)){return false}p=true;a:while(p===true){p=false;v=d.A-d._;n=true;c:while(n===true){n=false;if(!(b(d,a.a_1,2)===0?false:true)){break c}d.B=d._;if(!e(d,'')){return false}break a}d._=d.A-v;m=true;d:while(m===true){m=false;if(!(!c(d)?false:!f(d,a.g_U,105,305)?false:!l(d)?false:true)){break d}d.B=d._;if(!e(d,'')){return false}w=d.A-d._;A=true;c:while(A===true){A=false;d.C=d._;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){d._=d.A-w;break c}d.B=d._;if(!e(d,'')){return false}if(!i(d)){d._=d.A-w;break c}}break a}d._=d.A-v;if(!i(d)){return false}}}return true};a.prototype.z=function(){var d;var ar;var S;var j;var av;var m;var aq;var n;var p;var ax;var ay;var q;var ap;var r;var s;var as;var at;var au;var t;var aw;var u;var v;var w;var aA;var aB;var ao;var x;var y;var z;var A;var B;var C;var D;var E;var F;var G;var H;var I;var J;var K;var L;var M;var N;var O;var P;var Q;var R;var g;var T;var U;var V;var W;var X;var Y;var Z;var _;var $;var a0;var a1;var a2;var a3;var a4;var a5;var a6;var a7;var a8;var a9;var aa;var ab;var ac;var ad;var ae;var af;var ag;var ah;var ai;var aj;var ak;var al;var am;var an;var aC;var az;y=true;a:while(y===true){y=false;d=this.A-this._;z=true;b:while(z===true){z=false;this.C=this._;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){break b}this.B=this._;if(!e(this,'')){return false}ar=this.A-this._;A=true;c:while(A===true){A=false;if(!i(this)){this._=this.A-ar;break c}}break a}this._=this.A-d;B=true;g:while(B===true){B=false;this.C=this._;if(!(!c(this)?false:b(this,a.a_11,2)===0?false:!o(this)?false:true)){break g}this.B=this._;if(!e(this,'')){return false}S=this.A-this._;C=true;b:while(C===true){C=false;D=true;c:while(D===true){D=false;j=this.A-this._;E=true;d:while(E===true){E=false;this.C=this._;if(!(b(this,a.a_1,2)===0?false:true)){break d}this.B=this._;if(!e(this,'')){return false}break c}this._=this.A-j;F=true;f:while(F===true){F=false;this.C=this._;G=true;d:while(G===true){G=false;av=this.A-this._;H=true;e:while(H===true){H=false;if(!(b(this,a.a_0,10)===0?false:!k(this)?false:true)){break e}break d}this._=this.A-av;if(!(!c(this)?false:!f(this,a.g_U,105,305)?false:!l(this)?false:true)){break f}}this.B=this._;if(!e(this,'')){return false}m=this.A-this._;I=true;d:while(I===true){I=false;this.C=this._;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){this._=this.A-m;break d}this.B=this._;if(!e(this,'')){return false}if(!i(this)){this._=this.A-m;break d}}break c}aC=this._=this.A-j;this.C=aC;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){this._=this.A-S;break b}this.B=this._;if(!e(this,'')){return false}if(!i(this)){this._=this.A-S;break b}}}break a}this._=this.A-d;J=true;b:while(J===true){J=false;this.C=this._;K=true;d:while(K===true){K=false;aq=this.A-this._;L=true;c:while(L===true){L=false;if(!(!c(this)?false:b(this,a.a_7,2)===0?false:true)){break c}break d}this._=this.A-aq;if(!(!c(this)?false:b(this,a.a_5,2)===0?false:true)){break b}}M=true;c:while(M===true){M=false;n=this.A-this._;N=true;d:while(N===true){N=false;if(!(b(this,a.a_1,2)===0?false:true)){break d}this.B=this._;if(!e(this,'')){return false}break c}this._=this.A-n;O=true;e:while(O===true){O=false;if(!(!c(this)?false:!f(this,a.g_U,105,305)?false:!l(this)?false:true)){break e}this.B=this._;if(!e(this,'')){return false}p=this.A-this._;P=true;d:while(P===true){P=false;this.C=this._;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){this._=this.A-p;break d}this.B=this._;if(!e(this,'')){return false}if(!i(this)){this._=this.A-p;break d}}break c}this._=this.A-n;if(!i(this)){break b}}break a}this._=this.A-d;Q=true;c:while(Q===true){Q=false;this.C=this._;R=true;b:while(R===true){R=false;ax=this.A-this._;g=true;d:while(g===true){g=false;if(!(!c(this)?false:b(this,a.a_9,2)===0?false:true)){break d}break b}this._=this.A-ax;if(!(!c(this)?false:b(this,a.a_2,4)===0?false:true)){break c}}T=true;d:while(T===true){T=false;ay=this.A-this._;U=true;e:while(U===true){U=false;if(!(!c(this)?false:!f(this,a.g_U,105,305)?false:!l(this)?false:true)){break e}this.B=this._;if(!e(this,'')){return false}q=this.A-this._;V=true;b:while(V===true){V=false;this.C=this._;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){this._=this.A-q;break b}this.B=this._;if(!e(this,'')){return false}if(!i(this)){this._=this.A-q;break b}}break d}this._=this.A-ay;if(!(b(this,a.a_1,2)===0?false:true)){break c}}break a}this._=this.A-d;W=true;d:while(W===true){W=false;this.C=this._;if(!(!c(this)?false:b(this,a.a_8,4)===0?false:true)){break d}this.B=this._;if(!e(this,'')){return false}ap=this.A-this._;X=true;e:while(X===true){X=false;this.C=this._;Y=true;c:while(Y===true){Y=false;r=this.A-this._;Z=true;f:while(Z===true){Z=false;if(!(b(this,a.a_0,10)===0?false:!k(this)?false:true)){break f}this.B=this._;if(!e(this,'')){return false}s=this.A-this._;_=true;b:while(_===true){_=false;this.C=this._;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){this._=this.A-s;break b}this.B=this._;if(!e(this,'')){return false}if(!i(this)){this._=this.A-s;break b}}break c}this._=this.A-r;$=true;b:while($===true){$=false;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){break b}this.B=this._;if(!e(this,'')){return false}as=this.A-this._;a0=true;f:while(a0===true){a0=false;if(!i(this)){this._=this.A-as;break f}}break c}this._=this.A-r;if(!i(this)){this._=this.A-ap;break e}}}break a}this._=this.A-d;a1=true;d:while(a1===true){a1=false;this.C=this._;a2=true;b:while(a2===true){a2=false;at=this.A-this._;a3=true;c:while(a3===true){a3=false;if(!(!c(this)?false:b(this,a.a_3,4)===0?false:!o(this)?false:true)){break c}break b}this._=this.A-at;if(!(!c(this)?false:b(this,a.a_10,2)===0?false:!h(this)?false:true)){break d}}this.B=this._;if(!e(this,'')){return false}au=this.A-this._;a4=true;e:while(a4===true){a4=false;a5=true;c:while(a5===true){a5=false;t=this.A-this._;a6=true;b:while(a6===true){a6=false;this.C=this._;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){break b}this.B=this._;if(!e(this,'')){return false}if(!i(this)){break b}break c}this._=this.A-t;a7=true;f:while(a7===true){a7=false;this.C=this._;a8=true;b:while(a8===true){a8=false;aw=this.A-this._;a9=true;g:while(a9===true){a9=false;if(!(b(this,a.a_0,10)===0?false:!k(this)?false:true)){break g}break b}this._=this.A-aw;if(!(!c(this)?false:!f(this,a.g_U,105,305)?false:!l(this)?false:true)){break f}}this.B=this._;if(!e(this,'')){return false}u=this.A-this._;aa=true;b:while(aa===true){aa=false;this.C=this._;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){this._=this.A-u;break b}this.B=this._;if(!e(this,'')){return false}if(!i(this)){this._=this.A-u;break b}}break c}this._=this.A-t;if(!i(this)){this._=this.A-au;break e}}}break a}this._=this.A-d;ab=true;b:while(ab===true){ab=false;this.C=this._;if(!(b(this,a.a_1,2)===0?false:true)){break b}this.B=this._;if(!e(this,'')){return false}break a}this._=this.A-d;ac=true;b:while(ac===true){ac=false;if(!i(this)){break b}break a}this._=this.A-d;ad=true;c:while(ad===true){ad=false;this.C=this._;ae=true;b:while(ae===true){ae=false;v=this.A-this._;af=true;d:while(af===true){af=false;if(!(!c(this)?false:b(this,a.a_6,4)===0?false:true)){break d}break b}this._=this.A-v;ag=true;d:while(ag===true){ag=false;if(!(!c(this)?false:!f(this,a.g_U,105,305)?false:!h(this)?false:true)){break d}break b}this._=this.A-v;if(!(!c(this)?false:b(this,a.a_4,2)===0?false:!h(this)?false:true)){break c}}this.B=this._;if(!e(this,'')){return false}w=this.A-this._;ah=true;b:while(ah===true){ah=false;this.C=this._;ai=true;d:while(ai===true){ai=false;aA=this.A-this._;aj=true;e:while(aj===true){aj=false;if(!(b(this,a.a_0,10)===0?false:!k(this)?false:true)){break e}this.B=this._;if(!e(this,'')){return false}aB=this.A-this._;ak=true;f:while(ak===true){ak=false;this.C=this._;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){this._=this.A-aB;break f}}break d}this._=this.A-aA;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){this._=this.A-w;break b}}this.B=this._;if(!e(this,'')){return false}this.C=this._;if(!i(this)){this._=this.A-w;break b}}break a}az=this._=this.A-d;this.C=az;al=true;b:while(al===true){al=false;ao=this.A-this._;am=true;c:while(am===true){am=false;if(!(b(this,a.a_0,10)===0?false:!k(this)?false:true)){break c}break b}this._=this.A-ao;if(!(!c(this)?false:!f(this,a.g_U,105,305)?false:!l(this)?false:true)){return false}}this.B=this._;if(!e(this,'')){return false}x=this.A-this._;an=true;b:while(an===true){an=false;this.C=this._;if(!(!c(this)?false:b(this,a.a_16,2)===0?false:true)){this._=this.A-x;break b}this.B=this._;if(!e(this,'')){return false}if(!i(this)){this._=this.A-x;break b}}}return true};a.prototype.r_stem_noun_suffixes=a.prototype.z;function L(d){var g;var as;var S;var m;var aw;var n;var ar;var p;var q;var ay;var az;var r;var aq;var s;var t;var at;var au;var av;var u;var ax;var v;var w;var x;var aB;var aC;var ap;var y;var z;var A;var B;var C;var D;var E;var F;var G;var H;var I;var J;var K;var L;var M;var N;var O;var P;var Q;var R;var j;var T;var U;var V;var W;var X;var Y;var Z;var _;var $;var a0;var a1;var a2;var a3;var a4;var a5;var a6;var a7;var a8;var a9;var aa;var ab;var ac;var ad;var ae;var af;var ag;var ah;var ai;var aj;var ak;var al;var am;var an;var ao;var aD;var aA;z=true;a:while(z===true){z=false;g=d.A-d._;A=true;b:while(A===true){A=false;d.C=d._;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){break b}d.B=d._;if(!e(d,'')){return false}as=d.A-d._;B=true;c:while(B===true){B=false;if(!i(d)){d._=d.A-as;break c}}break a}d._=d.A-g;C=true;g:while(C===true){C=false;d.C=d._;if(!(!c(d)?false:b(d,a.a_11,2)===0?false:!o(d)?false:true)){break g}d.B=d._;if(!e(d,'')){return false}S=d.A-d._;D=true;b:while(D===true){D=false;E=true;c:while(E===true){E=false;m=d.A-d._;F=true;d:while(F===true){F=false;d.C=d._;if(!(b(d,a.a_1,2)===0?false:true)){break d}d.B=d._;if(!e(d,'')){return false}break c}d._=d.A-m;G=true;f:while(G===true){G=false;d.C=d._;H=true;d:while(H===true){H=false;aw=d.A-d._;I=true;e:while(I===true){I=false;if(!(b(d,a.a_0,10)===0?false:!k(d)?false:true)){break e}break d}d._=d.A-aw;if(!(!c(d)?false:!f(d,a.g_U,105,305)?false:!l(d)?false:true)){break f}}d.B=d._;if(!e(d,'')){return false}n=d.A-d._;J=true;d:while(J===true){J=false;d.C=d._;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){d._=d.A-n;break d}d.B=d._;if(!e(d,'')){return false}if(!i(d)){d._=d.A-n;break d}}break c}aD=d._=d.A-m;d.C=aD;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){d._=d.A-S;break b}d.B=d._;if(!e(d,'')){return false}if(!i(d)){d._=d.A-S;break b}}}break a}d._=d.A-g;K=true;b:while(K===true){K=false;d.C=d._;L=true;d:while(L===true){L=false;ar=d.A-d._;M=true;c:while(M===true){M=false;if(!(!c(d)?false:b(d,a.a_7,2)===0?false:true)){break c}break d}d._=d.A-ar;if(!(!c(d)?false:b(d,a.a_5,2)===0?false:true)){break b}}N=true;c:while(N===true){N=false;p=d.A-d._;O=true;d:while(O===true){O=false;if(!(b(d,a.a_1,2)===0?false:true)){break d}d.B=d._;if(!e(d,'')){return false}break c}d._=d.A-p;P=true;e:while(P===true){P=false;if(!(!c(d)?false:!f(d,a.g_U,105,305)?false:!l(d)?false:true)){break e}d.B=d._;if(!e(d,'')){return false}q=d.A-d._;Q=true;d:while(Q===true){Q=false;d.C=d._;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){d._=d.A-q;break d}d.B=d._;if(!e(d,'')){return false}if(!i(d)){d._=d.A-q;break d}}break c}d._=d.A-p;if(!i(d)){break b}}break a}d._=d.A-g;R=true;c:while(R===true){R=false;d.C=d._;j=true;b:while(j===true){j=false;ay=d.A-d._;T=true;d:while(T===true){T=false;if(!(!c(d)?false:b(d,a.a_9,2)===0?false:true)){break d}break b}d._=d.A-ay;if(!(!c(d)?false:b(d,a.a_2,4)===0?false:true)){break c}}U=true;d:while(U===true){U=false;az=d.A-d._;V=true;e:while(V===true){V=false;if(!(!c(d)?false:!f(d,a.g_U,105,305)?false:!l(d)?false:true)){break e}d.B=d._;if(!e(d,'')){return false}r=d.A-d._;W=true;b:while(W===true){W=false;d.C=d._;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){d._=d.A-r;break b}d.B=d._;if(!e(d,'')){return false}if(!i(d)){d._=d.A-r;break b}}break d}d._=d.A-az;if(!(b(d,a.a_1,2)===0?false:true)){break c}}break a}d._=d.A-g;X=true;d:while(X===true){X=false;d.C=d._;if(!(!c(d)?false:b(d,a.a_8,4)===0?false:true)){break d}d.B=d._;if(!e(d,'')){return false}aq=d.A-d._;Y=true;e:while(Y===true){Y=false;d.C=d._;Z=true;c:while(Z===true){Z=false;s=d.A-d._;_=true;f:while(_===true){_=false;if(!(b(d,a.a_0,10)===0?false:!k(d)?false:true)){break f}d.B=d._;if(!e(d,'')){return false}t=d.A-d._;$=true;b:while($===true){$=false;d.C=d._;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){d._=d.A-t;break b}d.B=d._;if(!e(d,'')){return false}if(!i(d)){d._=d.A-t;break b}}break c}d._=d.A-s;a0=true;b:while(a0===true){a0=false;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){break b}d.B=d._;if(!e(d,'')){return false}at=d.A-d._;a1=true;f:while(a1===true){a1=false;if(!i(d)){d._=d.A-at;break f}}break c}d._=d.A-s;if(!i(d)){d._=d.A-aq;break e}}}break a}d._=d.A-g;a2=true;d:while(a2===true){a2=false;d.C=d._;a3=true;b:while(a3===true){a3=false;au=d.A-d._;a4=true;c:while(a4===true){a4=false;if(!(!c(d)?false:b(d,a.a_3,4)===0?false:!o(d)?false:true)){break c}break b}d._=d.A-au;if(!(!c(d)?false:b(d,a.a_10,2)===0?false:!h(d)?false:true)){break d}}d.B=d._;if(!e(d,'')){return false}av=d.A-d._;a5=true;e:while(a5===true){a5=false;a6=true;c:while(a6===true){a6=false;u=d.A-d._;a7=true;b:while(a7===true){a7=false;d.C=d._;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){break b}d.B=d._;if(!e(d,'')){return false}if(!i(d)){break b}break c}d._=d.A-u;a8=true;f:while(a8===true){a8=false;d.C=d._;a9=true;b:while(a9===true){a9=false;ax=d.A-d._;aa=true;g:while(aa===true){aa=false;if(!(b(d,a.a_0,10)===0?false:!k(d)?false:true)){break g}break b}d._=d.A-ax;if(!(!c(d)?false:!f(d,a.g_U,105,305)?false:!l(d)?false:true)){break f}}d.B=d._;if(!e(d,'')){return false}v=d.A-d._;ab=true;b:while(ab===true){ab=false;d.C=d._;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){d._=d.A-v;break b}d.B=d._;if(!e(d,'')){return false}if(!i(d)){d._=d.A-v;break b}}break c}d._=d.A-u;if(!i(d)){d._=d.A-av;break e}}}break a}d._=d.A-g;ac=true;b:while(ac===true){ac=false;d.C=d._;if(!(b(d,a.a_1,2)===0?false:true)){break b}d.B=d._;if(!e(d,'')){return false}break a}d._=d.A-g;ad=true;b:while(ad===true){ad=false;if(!i(d)){break b}break a}d._=d.A-g;ae=true;c:while(ae===true){ae=false;d.C=d._;af=true;b:while(af===true){af=false;w=d.A-d._;ag=true;d:while(ag===true){ag=false;if(!(!c(d)?false:b(d,a.a_6,4)===0?false:true)){break d}break b}d._=d.A-w;ah=true;d:while(ah===true){ah=false;if(!(!c(d)?false:!f(d,a.g_U,105,305)?false:!h(d)?false:true)){break d}break b}d._=d.A-w;if(!(!c(d)?false:b(d,a.a_4,2)===0?false:!h(d)?false:true)){break c}}d.B=d._;if(!e(d,'')){return false}x=d.A-d._;ai=true;b:while(ai===true){ai=false;d.C=d._;aj=true;d:while(aj===true){aj=false;aB=d.A-d._;ak=true;e:while(ak===true){ak=false;if(!(b(d,a.a_0,10)===0?false:!k(d)?false:true)){break e}d.B=d._;if(!e(d,'')){return false}aC=d.A-d._;al=true;f:while(al===true){al=false;d.C=d._;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){d._=d.A-aC;break f}}break d}d._=d.A-aB;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){d._=d.A-x;break b}}d.B=d._;if(!e(d,'')){return false}d.C=d._;if(!i(d)){d._=d.A-x;break b}}break a}aA=d._=d.A-g;d.C=aA;am=true;b:while(am===true){am=false;ap=d.A-d._;an=true;c:while(an===true){an=false;if(!(b(d,a.a_0,10)===0?false:!k(d)?false:true)){break c}break b}d._=d.A-ap;if(!(!c(d)?false:!f(d,a.g_U,105,305)?false:!l(d)?false:true)){return false}}d.B=d._;if(!e(d,'')){return false}y=d.A-d._;ao=true;b:while(ao===true){ao=false;d.C=d._;if(!(!c(d)?false:b(d,a.a_16,2)===0?false:true)){d._=d.A-y;break b}d.B=d._;if(!e(d,'')){return false}if(!i(d)){d._=d.A-y;break b}}}return true};a.prototype.w=function(){var c;this.C=this._;c=b(this,a.a_23,4);if(c===0){return false}this.B=this._;switch(c){case 0:return false;case 1:if(!e(this,'p')){return false}break;case 2:if(!e(this,'ç')){return false}break;case 3:if(!e(this,'t')){return false}break;case 4:if(!e(this,'k')){return false}break}return true};a.prototype.r_post_process_last_consonants=a.prototype.w;function w(c){var d;c.C=c._;d=b(c,a.a_23,4);if(d===0){return false}c.B=c._;switch(d){case 0:return false;case 1:if(!e(c,'p')){return false}break;case 2:if(!e(c,'ç')){return false}break;case 3:if(!e(c,'t')){return false}break;case 4:if(!e(c,'k')){return false}break}return true};a.prototype.N=function(){var L;var _;var i;var Y;var B;var W;var K;var l;var S;var Q;var p;var O;var M;var s;var U;var u;var v;var w;var x;var y;var z;var A;var b;var C;var D;var j;var F;var G;var H;var I;var J;var E;var t;var r;var N;var q;var P;var o;var R;var m;var T;var k;var V;var h;var X;var e;var Z;var d;var $;var a0;var a1;var c;L=this.A-this._;u=true;a:while(u===true){u=false;_=this.A-this._;v=true;b:while(v===true){v=false;if(!g(this,1,'d')){break b}break a}this._=this.A-_;if(!g(this,1,'g')){return false}}this._=this.A-L;w=true;a:while(w===true){w=false;i=this.A-this._;x=true;b:while(x===true){x=false;Y=this.A-this._;d:while(true){B=this.A-this._;y=true;c:while(y===true){y=false;if(!f(this,a.g_vowel,97,305)){break c}this._=this.A-B;break d}V=this._=this.A-B;if(V<=this.D){break b}this._--}z=true;c:while(z===true){z=false;W=this.A-this._;A=true;d:while(A===true){A=false;if(!g(this,1,'a')){break d}break c}this._=this.A-W;if(!g(this,1,'ı')){break b}}h=this._=this.A-Y;b=h;N=h;q=n(this,h,h,'ı');if(h<=this.B){this.B+=q|0}if(N<=this.C){this.C+=q|0}this._=b;break a}this._=this.A-i;C=true;b:while(C===true){C=false;K=this.A-this._;c:while(true){l=this.A-this._;D=true;d:while(D===true){D=false;if(!f(this,a.g_vowel,97,305)){break d}this._=this.A-l;break c}X=this._=this.A-l;if(X<=this.D){break b}this._--}j=true;c:while(j===true){j=false;S=this.A-this._;F=true;d:while(F===true){F=false;if(!g(this,1,'e')){break d}break c}this._=this.A-S;if(!g(this,1,'i')){break b}}e=this._=this.A-K;b=e;P=e;o=n(this,e,e,'i');if(e<=this.B){this.B+=o|0}if(P<=this.C){this.C+=o|0}this._=b;break a}this._=this.A-i;G=true;b:while(G===true){G=false;Q=this.A-this._;c:while(true){p=this.A-this._;H=true;d:while(H===true){H=false;if(!f(this,a.g_vowel,97,305)){break d}this._=this.A-p;break c}Z=this._=this.A-p;if(Z<=this.D){break b}this._--}I=true;c:while(I===true){I=false;O=this.A-this._;J=true;d:while(J===true){J=false;if(!g(this,1,'o')){break d}break c}this._=this.A-O;if(!g(this,1,'u')){break b}}d=this._=this.A-Q;b=d;R=d;m=n(this,d,d,'u');if(d<=this.B){this.B+=m|0}if(R<=this.C){this.C+=m|0}this._=b;break a}a1=this._=(a0=this.A)-i;M=a0-a1;b:while(true){s=this.A-this._;E=true;c:while(E===true){E=false;if(!f(this,a.g_vowel,97,305)){break c}this._=this.A-s;break b}$=this._=this.A-s;if($<=this.D){return false}this._--}t=true;b:while(t===true){t=false;U=this.A-this._;r=true;c:while(r===true){r=false;if(!g(this,1,'ö')){break c}break b}this._=this.A-U;if(!g(this,1,'ü')){return false}}c=this._=this.A-M;b=c;T=c;k=n(this,c,c,'ü');if(c<=this.B){this.B+=k|0}if(T<=this.C){this.C+=k|0}this._=b}return true};a.prototype.r_append_U_to_stems_ending_with_d_or_g=a.prototype.N;function z(b){var $;var Z;var j;var X;var F;var L;var T;var m;var R;var P;var q;var N;var V;var t;var M;var v;var w;var x;var y;var z;var A;var B;var c;var D;var E;var C;var G;var H;var I;var J;var K;var u;var s;var r;var O;var p;var Q;var o;var S;var l;var U;var k;var W;var i;var Y;var h;var _;var e;var a0;var a1;var a2;var d;$=b.A-b._;v=true;a:while(v===true){v=false;Z=b.A-b._;w=true;b:while(w===true){w=false;if(!g(b,1,'d')){break b}break a}b._=b.A-Z;if(!g(b,1,'g')){return false}}b._=b.A-$;x=true;a:while(x===true){x=false;j=b.A-b._;y=true;b:while(y===true){y=false;X=b.A-b._;d:while(true){F=b.A-b._;z=true;c:while(z===true){z=false;if(!f(b,a.g_vowel,97,305)){break c}b._=b.A-F;break d}W=b._=b.A-F;if(W<=b.D){break b}b._--}A=true;c:while(A===true){A=false;L=b.A-b._;B=true;d:while(B===true){B=false;if(!g(b,1,'a')){break d}break c}b._=b.A-L;if(!g(b,1,'ı')){break b}}i=b._=b.A-X;c=i;O=i;p=n(b,i,i,'ı');if(i<=b.B){b.B+=p|0}if(O<=b.C){b.C+=p|0}b._=c;break a}b._=b.A-j;D=true;b:while(D===true){D=false;T=b.A-b._;c:while(true){m=b.A-b._;E=true;d:while(E===true){E=false;if(!f(b,a.g_vowel,97,305)){break d}b._=b.A-m;break c}Y=b._=b.A-m;if(Y<=b.D){break b}b._--}C=true;c:while(C===true){C=false;R=b.A-b._;G=true;d:while(G===true){G=false;if(!g(b,1,'e')){break d}break c}b._=b.A-R;if(!g(b,1,'i')){break b}}h=b._=b.A-T;c=h;Q=h;o=n(b,h,h,'i');if(h<=b.B){b.B+=o|0}if(Q<=b.C){b.C+=o|0}b._=c;break a}b._=b.A-j;H=true;b:while(H===true){H=false;P=b.A-b._;c:while(true){q=b.A-b._;I=true;d:while(I===true){I=false;if(!f(b,a.g_vowel,97,305)){break d}b._=b.A-q;break c}_=b._=b.A-q;if(_<=b.D){break b}b._--}J=true;c:while(J===true){J=false;N=b.A-b._;K=true;d:while(K===true){K=false;if(!g(b,1,'o')){break d}break c}b._=b.A-N;if(!g(b,1,'u')){break b}}e=b._=b.A-P;c=e;S=e;l=n(b,e,e,'u');if(e<=b.B){b.B+=l|0}if(S<=b.C){b.C+=l|0}b._=c;break a}a2=b._=(a1=b.A)-j;V=a1-a2;b:while(true){t=b.A-b._;u=true;c:while(u===true){u=false;if(!f(b,a.g_vowel,97,305)){break c}b._=b.A-t;break b}a0=b._=b.A-t;if(a0<=b.D){return false}b._--}s=true;b:while(s===true){s=false;M=b.A-b._;r=true;c:while(r===true){r=false;if(!g(b,1,'ö')){break c}break b}b._=b.A-M;if(!g(b,1,'ü')){return false}}d=b._=b.A-V;c=d;U=d;k=n(b,d,d,'ü');if(d<=b.B){b.B+=k|0}if(U<=b.C){b.C+=k|0}b._=c}return true};a.prototype.v=function(){var e;var f;var b;var c;var d;e=this._;b=2;a:while(true){f=this._;c=true;b:while(c===true){c=false;c:while(true){d=true;d:while(d===true){d=false;if(!v(this,a.g_vowel,97,305)){break d}break c}if(this._>=this.A){break b}this._++}b--;continue a}this._=f;break a}if(b>0){return false}this._=e;return true};a.prototype.r_more_than_one_syllable_word=a.prototype.v;function N(b){var f;var g;var c;var d;var e;f=b._;c=2;a:while(true){g=b._;d=true;b:while(d===true){d=false;c:while(true){e=true;d:while(e===true){e=false;if(!v(b,a.g_vowel,97,305)){break d}break c}if(b._>=b.A){break b}b._++}c--;continue a}b._=g;break a}if(c>0){return false}b._=f;return true};a.prototype.P=function(){var f;var g;var h;var b;var a;var c;var d;var i;var j;var e;b=true;b:while(b===true){b=false;f=this._;a=true;a:while(a===true){a=false;g=this._;c:while(true){c=true;d:while(c===true){c=false;if(!s(this,2,'ad')){break d}break c}if(this._>=this.A){break a}this._++}i=this.I_strlen=2;if(!(i===this.A)){break a}this._=g;break b}j=this._=f;h=j;a:while(true){d=true;c:while(d===true){d=false;if(!s(this,5,'soyad')){break c}break a}if(this._>=this.A){return false}this._++}e=this.I_strlen=5;if(!(e===this.A)){return false}this._=h}return true};a.prototype.r_is_reserved_word=a.prototype.P;function x(a){var g;var h;var i;var c;var b;var d;var e;var j;var k;var f;c=true;b:while(c===true){c=false;g=a._;b=true;a:while(b===true){b=false;h=a._;c:while(true){d=true;d:while(d===true){d=false;if(!s(a,2,'ad')){break d}break c}if(a._>=a.A){break a}a._++}j=a.I_strlen=2;if(!(j===a.A)){break a}a._=h;break b}k=a._=g;i=k;a:while(true){e=true;c:while(e===true){e=false;if(!s(a,5,'soyad')){break c}break a}if(a._>=a.A){return false}a._++}f=a.I_strlen=5;if(!(f===a.A)){return false}a._=i}return true};a.prototype.x=function(){var d;var e;var a;var b;var c;var f;var g;var h;d=this._;a=true;a:while(a===true){a=false;if(!x(this)){break a}return false}f=this._=d;this.D=f;h=this._=g=this.A;e=g-h;b=true;a:while(b===true){b=false;if(!z(this)){break a}}this._=this.A-e;c=true;a:while(c===true){c=false;if(!w(this)){break a}}this._=this.D;return true};a.prototype.r_postlude=a.prototype.x;function O(a){var e;var f;var b;var c;var d;var g;var h;var i;e=a._;b=true;a:while(b===true){b=false;if(!x(a)){break a}return false}g=a._=e;a.D=g;i=a._=h=a.A;f=h-i;c=true;a:while(c===true){c=false;if(!z(a)){break a}}a._=a.A-f;d=true;a:while(d===true){d=false;if(!w(a)){break a}}a._=a.D;return true};a.prototype.H=function(){var c;var a;var b;var d;var e;if(!N(this)){return false}this.D=this._;e=this._=d=this.A;c=d-e;a=true;a:while(a===true){a=false;if(!J(this)){break a}}this._=this.A-c;if(!this.B_continue_stemming_noun_suffixes){return false}b=true;a:while(b===true){b=false;if(!L(this)){break a}}this._=this.D;return!O(this)?false:true};a.prototype.stem=a.prototype.H;a.prototype.L=function(b){return b instanceof a};a.prototype.equals=a.prototype.L;a.prototype.M=function(){var c;var a;var b;var d;c='TurkishStemmer';a=0;for(b=0;b<c.length;b++){d=c.charCodeAt(b);a=(a<<5)-a+d;a=a&a}return a|0};a.prototype.hashCode=a.prototype.M;a.serialVersionUID=1;j(a,'methodObject',function(){return new a});j(a,'a_0',function(){return[new d('m',-1,-1),new d('n',-1,-1),new d('miz',-1,-1),new d('niz',-1,-1),new d('muz',-1,-1),new d('nuz',-1,-1),new d('müz',-1,-1),new d('nüz',-1,-1),new d('mız',-1,-1),new d('nız',-1,-1)]});j(a,'a_1',function(){return[new d('leri',-1,-1),new d('ları',-1,-1)]});j(a,'a_2',function(){return[new d('ni',-1,-1),new d('nu',-1,-1),new d('nü',-1,-1),new d('nı',-1,-1)]});j(a,'a_3',function(){return[new d('in',-1,-1),new d('un',-1,-1),new d('ün',-1,-1),new d('ın',-1,-1)]});j(a,'a_4',function(){return[new d('a',-1,-1),new d('e',-1,-1)]});j(a,'a_5',function(){return[new d('na',-1,-1),new d('ne',-1,-1)]});j(a,'a_6',function(){return[new d('da',-1,-1),new d('ta',-1,-1),new d('de',-1,-1),new d('te',-1,-1)]});j(a,'a_7',function(){return[new d('nda',-1,-1),new d('nde',-1,-1)]});j(a,'a_8',function(){return[new d('dan',-1,-1),new d('tan',-1,-1),new d('den',-1,-1),new d('ten',-1,-1)]});j(a,'a_9',function(){return[new d('ndan',-1,-1),new d('nden',-1,-1)]});j(a,'a_10',function(){return[new d('la',-1,-1),new d('le',-1,-1)]});j(a,'a_11',function(){return[new d('ca',-1,-1),new d('ce',-1,-1)]});j(a,'a_12',function(){return[new d('im',-1,-1),new d('um',-1,-1),new d('üm',-1,-1),new d('ım',-1,-1)]});j(a,'a_13',function(){return[new d('sin',-1,-1),new d('sun',-1,-1),new d('sün',-1,-1),new d('sın',-1,-1)]});j(a,'a_14',function(){return[new d('iz',-1,-1),new d('uz',-1,-1),new d('üz',-1,-1),new d('ız',-1,-1)]});j(a,'a_15',function(){return[new d('siniz',-1,-1),new d('sunuz',-1,-1),new d('sünüz',-1,-1),new d('sınız',-1,-1)]});j(a,'a_16',function(){return[new d('lar',-1,-1),new d('ler',-1,-1)]});j(a,'a_17',function(){return[new d('niz',-1,-1),new d('nuz',-1,-1),new d('nüz',-1,-1),new d('nız',-1,-1)]});j(a,'a_18',function(){return[new d('dir',-1,-1),new d('tir',-1,-1),new d('dur',-1,-1),new d('tur',-1,-1),new d('dür',-1,-1),new d('tür',-1,-1),new d('dır',-1,-1),new d('tır',-1,-1)]});j(a,'a_19',function(){return[new d('casına',-1,-1),new d('cesine',-1,-1)]});j(a,'a_20',function(){return[new d('di',-1,-1),new d('ti',-1,-1),new d('dik',-1,-1),new d('tik',-1,-1),new d('duk',-1,-1),new d('tuk',-1,-1),new d('dük',-1,-1),new d('tük',-1,-1),new d('dık',-1,-1),new d('tık',-1,-1),new d('dim',-1,-1),new d('tim',-1,-1),new d('dum',-1,-1),new d('tum',-1,-1),new d('düm',-1,-1),new d('tüm',-1,-1),new d('dım',-1,-1),new d('tım',-1,-1),new d('din',-1,-1),new d('tin',-1,-1),new d('dun',-1,-1),new d('tun',-1,-1),new d('dün',-1,-1),new d('tün',-1,-1),new d('dın',-1,-1),new d('tın',-1,-1),new d('du',-1,-1),new d('tu',-1,-1),new d('dü',-1,-1),new d('tü',-1,-1),new d('dı',-1,-1),new d('tı',-1,-1)]});j(a,'a_21',function(){return[new d('sa',-1,-1),new d('se',-1,-1),new d('sak',-1,-1),new d('sek',-1,-1),new d('sam',-1,-1),new d('sem',-1,-1),new d('san',-1,-1),new d('sen',-1,-1)]});j(a,'a_22',function(){return[new d('miş',-1,-1),new d('muş',-1,-1),new d('müş',-1,-1),new d('mış',-1,-1)]});j(a,'a_23',function(){return[new d('b',-1,1),new d('c',-1,2),new d('d',-1,3),new d('ğ',-1,4)]});j(a,'g_vowel',function(){return[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,8,0,0,0,0,0,0,1]});j(a,'g_U',function(){return[1,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,1]});j(a,'g_vowel1',function(){return[1,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]});j(a,'g_vowel2',function(){return[17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,130]});j(a,'g_vowel3',function(){return[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]});j(a,'g_vowel4',function(){return[17]});j(a,'g_vowel5',function(){return[65]});j(a,'g_vowel6',function(){return[65]});var y={'src/stemmer.jsx':{Stemmer:u},'src/turkish-stemmer.jsx':{TurkishStemmer:a}}}(JSX))
+var Stemmer = JSX.require("src/turkish-stemmer.jsx").TurkishStemmer;
+"""
+
+
+class SearchTurkish(SearchLanguage):
+    lang = 'tr'
+    language_name = 'Turkish'
+    js_stemmer_code = js_stemmer
+    stopwords = []
+
+    def init(self, options):
+        self.stemmer = snowballstemmer.stemmer('turkish')
+
+    def stem(self, word):
+        return self.stemmer.stemWord(word)
diff --git a/sphinx/setup_command.py b/sphinx/setup_command.py
index a487b2a..22f2727 100644
--- a/sphinx/setup_command.py
+++ b/sphinx/setup_command.py
@@ -11,14 +11,15 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
+from __future__ import print_function
 
 import sys
 import os
-import types
-from StringIO import StringIO
 from distutils.cmd import Command
 from distutils.errors import DistutilsOptionError, DistutilsExecError
 
+from six import StringIO, string_types
+
 from sphinx.application import Sphinx
 from sphinx.util.console import darkred, nocolor, color_terminal
 from sphinx.util.osutil import abspath
@@ -108,7 +109,7 @@
         if val is None:
             setattr(self, option, default)
             return default
-        elif not isinstance(val, types.StringTypes):
+        elif not isinstance(val, string_types):
             raise DistutilsOptionError("'%s' must be a %s (got `%s`)"
                                        % (option, what, val))
         return val
@@ -137,7 +138,6 @@
 
     def run(self):
         if not color_terminal():
-            # Windows' poor cmd box doesn't understand ANSI sequences
             nocolor()
         if not self.verbose:
             status_stream = StringIO()
@@ -162,12 +162,12 @@
             if app.statuscode:
                 raise DistutilsExecError(
                     'caused by %s builder.' % app.builder.name)
-        except Exception, err:
+        except Exception as err:
             from docutils.utils import SystemMessage
             if isinstance(err, SystemMessage):
-                print >>sys.stderr, darkred('reST markup error:')
-                print >>sys.stderr, err.args[0].encode('ascii',
-                                                       'backslashreplace')
+                print(darkred('reST markup error:'), file=sys.stderr)
+                print(err.args[0].encode('ascii', 'backslashreplace'),
+                      file=sys.stderr)
             else:
                 raise
 
diff --git a/sphinx/texinputs/Makefile b/sphinx/texinputs/Makefile
index 6b87ad8..5e6030c 100644
--- a/sphinx/texinputs/Makefile
+++ b/sphinx/texinputs/Makefile
@@ -9,6 +9,10 @@
 # Additional LaTeX options
 LATEXOPTS =
 
+LATEX = latex
+PDFLATEX = pdflatex
+MAKEINDEX = makeindex
+
 all: $(ALLPDF)
 all-pdf: $(ALLPDF)
 all-dvi: $(ALLDVI)
@@ -43,20 +47,20 @@
 # The number of LaTeX runs is quite conservative, but I don't expect it
 # to get run often, so the little extra time won't hurt.
 %.dvi: %.tex
-	latex $(LATEXOPTS) '$<'
-	latex $(LATEXOPTS) '$<'
-	latex $(LATEXOPTS) '$<'
-	-makeindex -s python.ist '$(basename $<).idx'
-	latex $(LATEXOPTS) '$<'
-	latex $(LATEXOPTS) '$<'
+	$(LATEX) $(LATEXOPTS) '$<'
+	$(LATEX) $(LATEXOPTS) '$<'
+	$(LATEX) $(LATEXOPTS) '$<'
+	-$(MAKEINDEX) -s python.ist '$(basename $<).idx'
+	$(LATEX) $(LATEXOPTS) '$<'
+	$(LATEX) $(LATEXOPTS) '$<'
 
 %.pdf: %.tex
-	pdflatex $(LATEXOPTS) '$<'
-	pdflatex $(LATEXOPTS) '$<'
-	pdflatex $(LATEXOPTS) '$<'
-	-makeindex -s python.ist '$(basename $<).idx'
-	pdflatex $(LATEXOPTS) '$<'
-	pdflatex $(LATEXOPTS) '$<'
+	$(PDFLATEX) $(LATEXOPTS) '$<'
+	$(PDFLATEX) $(LATEXOPTS) '$<'
+	$(PDFLATEX) $(LATEXOPTS) '$<'
+	-$(MAKEINDEX) -s python.ist '$(basename $<).idx'
+	$(PDFLATEX) $(LATEXOPTS) '$<'
+	$(PDFLATEX) $(LATEXOPTS) '$<'
 
 clean:
 	rm -f *.dvi *.log *.ind *.aux *.toc *.syn *.idx *.out *.ilg *.pla
diff --git a/sphinx/themes/agogo/layout.html b/sphinx/themes/agogo/layout.html
index c6960fb..a29299b 100644
--- a/sphinx/themes/agogo/layout.html
+++ b/sphinx/themes/agogo/layout.html
@@ -11,7 +11,7 @@
 {%- extends "basic/layout.html" %}
 
 {% block header %}
-    <div class="header-wrapper">
+    <div class="header-wrapper" role="banner">
       <div class="header">
         {%- if logo %}
           <p class="logo"><a href="{{ pathto(master_doc) }}">
@@ -22,7 +22,7 @@
         <div class="headertitle"><a
           href="{{ pathto(master_doc) }}">{{ shorttitle|e }}</a></div>
         {%- endblock %}
-        <div class="rel">
+        <div class="rel" role="navigation" aria-label="related navigation">
           {%- for rellink in rellinks|reverse %}
           <a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags|e }}"
              {{ accesskey(rellink[2]) }}>{{ rellink[3] }}</a>
@@ -47,16 +47,18 @@
           {{ toctree() }}
           {%- endblock %}
           {%- block sidebarsearch %}
-          <h3 style="margin-top: 1.5em;">{{ _('Search') }}</h3>
-          <form class="search" action="{{ pathto('search') }}" method="get">
-            <input type="text" name="q" />
-            <input type="submit" value="{{ _('Go') }}" />
-            <input type="hidden" name="check_keywords" value="yes" />
-            <input type="hidden" name="area" value="default" />
-          </form>
-          <p class="searchtip" style="font-size: 90%">
-            {{ _('Enter search terms or a module, class or function name.') }}
-          </p>
+          <div role="search">
+            <h3 style="margin-top: 1.5em;">{{ _('Search') }}</h3>
+            <form class="search" action="{{ pathto('search') }}" method="get">
+                <input type="text" name="q" />
+                <input type="submit" value="{{ _('Go') }}" />
+                <input type="hidden" name="check_keywords" value="yes" />
+                <input type="hidden" name="area" value="default" />
+            </form>
+            <p class="searchtip" style="font-size: 90%">
+                {{ _('Enter search terms or a module, class or function name.') }}
+            </p>
+          </div>
           {%- endblock %}
         </div>
         <div class="clearer"></div>
@@ -68,16 +70,20 @@
     <div class="footer-wrapper">
       <div class="footer">
         <div class="left">
-          {%- for rellink in rellinks|reverse %}
-          <a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags|e }}"
-             {{ accesskey(rellink[2]) }}>{{ rellink[3] }}</a>
-          {%- if not loop.last %}{{ reldelim2 }}{% endif %}
-          {%- endfor %}
-          {%- if show_source and has_source and sourcename %}
-            <br/>
-            <a href="{{ pathto('_sources/' + sourcename, true)|e }}"
-               rel="nofollow">{{ _('Show Source') }}</a>
-          {%- endif %}
+          <div role="navigation" aria-label="related navigaton">
+            {%- for rellink in rellinks|reverse %}
+            <a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags|e }}"
+              {{ accesskey(rellink[2]) }}>{{ rellink[3] }}</a>
+            {%- if not loop.last %}{{ reldelim2 }}{% endif %}
+            {%- endfor %}
+          </div>
+          <div role="note" aria-label="source link">
+            {%- if show_source and has_source and sourcename %}
+              <br/>
+              <a href="{{ pathto('_sources/' + sourcename, true)|e }}"
+                rel="nofollow">{{ _('Show Source') }}</a>
+            {%- endif %}
+          </div>
         </div>
 
         <div class="right">
diff --git a/sphinx/themes/agogo/static/agogo.css_t b/sphinx/themes/agogo/static/agogo.css_t
index 1ec2147..db4a621 100644
--- a/sphinx/themes/agogo/static/agogo.css_t
+++ b/sphinx/themes/agogo/static/agogo.css_t
@@ -223,6 +223,10 @@
   font-weight: bold;
 }
 
+div.document .sig-paren {
+    font-size: larger;
+}
+
 div.document .docutils.literal {
   background-color: #eeeeec;
   padding: 1px;
@@ -462,3 +466,10 @@
     border-top: 1px solid #ac9;
     border-bottom: 1px solid #ac9;
 }
+
+div.code-block-caption {
+    background-color: #ddd;
+    color: #333;
+    padding: 2px 5px;
+    font-size: small;
+}
diff --git a/sphinx/themes/basic/domainindex.html b/sphinx/themes/basic/domainindex.html
index ac5aed9..4ee62d5 100644
--- a/sphinx/themes/basic/domainindex.html
+++ b/sphinx/themes/basic/domainindex.html
@@ -44,7 +44,7 @@
            {%- endif %}</td>
        <td>{% if grouptype == 2 %}&nbsp;&nbsp;&nbsp;{% endif %}
        {% if page %}<a href="{{ pathto(page) }}#{{ anchor }}">{% endif -%}
-       <tt class="xref">{{ name|e }}</tt>
+       <code class="xref">{{ name|e }}</code>
        {%- if page %}</a>{% endif %}
      {%- if extra %} <em>({{ extra|e }})</em>{% endif -%}
      </td><td>{% if qualifier %}<strong>{{ qualifier|e }}:</strong>{% endif %}
diff --git a/sphinx/themes/basic/layout.html b/sphinx/themes/basic/layout.html
index f01c3aa..f33b7cb 100644
--- a/sphinx/themes/basic/layout.html
+++ b/sphinx/themes/basic/layout.html
@@ -25,7 +25,7 @@
 {%- endif %}
 
 {%- macro relbar() %}
-    <div class="related">
+    <div class="related" role="navigation" aria-label="related navigation">
       <h3>{{ _('Navigation') }}</h3>
       <ul>
         {%- for rellink in rellinks %}
@@ -47,7 +47,7 @@
 
 {%- macro sidebar() %}
       {%- if render_sidebar %}
-      <div class="sphinxsidebar">
+      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
         <div class="sphinxsidebarwrapper">
           {%- block sidebarlogo %}
           {%- if logo %}
@@ -152,7 +152,7 @@
 {%- endblock %}
 {%- block extrahead %} {% endblock %}
   </head>
-  <body>
+  <body role="document">
 {%- block header %}{% endblock %}
 
 {%- block relbar1 %}{{ relbar() }}{% endblock %}
@@ -166,7 +166,7 @@
       {%- if render_sidebar %}
         <div class="bodywrapper">
       {%- endif %}
-          <div class="body">
+          <div class="body" role="main">
             {% block body %} {% endblock %}
           </div>
       {%- if render_sidebar %}
@@ -183,7 +183,7 @@
 {%- block relbar2 %}{{ relbar() }}{% endblock %}
 
 {%- block footer %}
-    <div class="footer">
+    <div class="footer" role="contentinfo">
     {%- if show_copyright %}
       {%- if hasdoc('copyright') %}
         {% trans path=pathto('copyright'), copyright=copyright|e %}&copy; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
diff --git a/sphinx/themes/basic/searchbox.html b/sphinx/themes/basic/searchbox.html
index 0a746f5..ffcce73 100644
--- a/sphinx/themes/basic/searchbox.html
+++ b/sphinx/themes/basic/searchbox.html
@@ -8,7 +8,7 @@
     :license: BSD, see LICENSE for details.
 #}
 {%- if pagename != "search" and builder != "singlehtml" %}
-<div id="searchbox" style="display: none">
+<div id="searchbox" style="display: none" role="search">
   <h3>{{ _('Quick search') }}</h3>
     <form class="search" action="{{ pathto('search') }}" method="get">
       <input type="text" name="q" />
diff --git a/sphinx/themes/basic/sourcelink.html b/sphinx/themes/basic/sourcelink.html
index f3cb71f..abd6a97 100644
--- a/sphinx/themes/basic/sourcelink.html
+++ b/sphinx/themes/basic/sourcelink.html
@@ -8,9 +8,11 @@
     :license: BSD, see LICENSE for details.
 #}
 {%- if show_source and has_source and sourcename %}
-  <h3>{{ _('This Page') }}</h3>
-  <ul class="this-page-menu">
-    <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}"
-           rel="nofollow">{{ _('Show Source') }}</a></li>
-  </ul>
+  <div role="note" aria-label="source link">
+    <h3>{{ _('This Page') }}</h3>
+    <ul class="this-page-menu">
+      <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}"
+            rel="nofollow">{{ _('Show Source') }}</a></li>
+    </ul>
+   </div>
 {%- endif %}
diff --git a/sphinx/themes/basic/static/basic.css_t b/sphinx/themes/basic/static/basic.css_t
index 7ffa466..17547d0 100644
--- a/sphinx/themes/basic/static/basic.css_t
+++ b/sphinx/themes/basic/static/basic.css_t
@@ -406,6 +406,10 @@
     font-size: 1.3em;
 }
 
+.sig-paren {
+    font-size: larger;
+}
+
 .versionmodified {
     font-style: italic;
 }
@@ -471,22 +475,36 @@
     padding: 0 0.5em 0 0.5em;
 }
 
-tt.descname {
+div.code-block-caption {
+    padding: 2px 5px;
+    font-size: small;
+}
+
+div.code-block-filename code {
+    background-color: transparent;
+}
+
+div.code-block-caption + pre,
+div.code-block-caption + div.highlight > pre {
+    margin-top: 0;
+}
+
+code.descname {
     background-color: transparent;
     font-weight: bold;
     font-size: 1.2em;
 }
 
-tt.descclassname {
+code.descclassname {
     background-color: transparent;
 }
 
-tt.xref, a tt {
+code.xref, a code {
     background-color: transparent;
     font-weight: bold;
 }
 
-h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
     background-color: transparent;
 }
 
diff --git a/sphinx/themes/basic/static/down-pressed.png b/sphinx/themes/basic/static/down-pressed.png
index 6f7ad78..7c30d00 100644
--- a/sphinx/themes/basic/static/down-pressed.png
+++ b/sphinx/themes/basic/static/down-pressed.png
Binary files differ
diff --git a/sphinx/themes/basic/static/down.png b/sphinx/themes/basic/static/down.png
index 3003a88..f48098a 100644
--- a/sphinx/themes/basic/static/down.png
+++ b/sphinx/themes/basic/static/down.png
Binary files differ
diff --git a/sphinx/themes/basic/static/file.png b/sphinx/themes/basic/static/file.png
index d18082e..254c60b 100644
--- a/sphinx/themes/basic/static/file.png
+++ b/sphinx/themes/basic/static/file.png
Binary files differ
diff --git a/sphinx/themes/basic/static/jquery-1.8.3.js b/sphinx/themes/basic/static/jquery-1.8.3.js
new file mode 100644
index 0000000..8c24ffc
--- /dev/null
+++ b/sphinx/themes/basic/static/jquery-1.8.3.js
@@ -0,0 +1,9472 @@
+/*!
+ * jQuery JavaScript Library v1.8.3
+ * http://jquery.com/
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ *
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time)
+ */
+(function( window, undefined ) {
+var
+	// A central reference to the root jQuery(document)
+	rootjQuery,
+
+	// The deferred used on DOM ready
+	readyList,
+
+	// Use the correct document accordingly with window argument (sandbox)
+	document = window.document,
+	location = window.location,
+	navigator = window.navigator,
+
+	// Map over jQuery in case of overwrite
+	_jQuery = window.jQuery,
+
+	// Map over the $ in case of overwrite
+	_$ = window.$,
+
+	// Save a reference to some core methods
+	core_push = Array.prototype.push,
+	core_slice = Array.prototype.slice,
+	core_indexOf = Array.prototype.indexOf,
+	core_toString = Object.prototype.toString,
+	core_hasOwn = Object.prototype.hasOwnProperty,
+	core_trim = String.prototype.trim,
+
+	// Define a local copy of jQuery
+	jQuery = function( selector, context ) {
+		// The jQuery object is actually just the init constructor 'enhanced'
+		return new jQuery.fn.init( selector, context, rootjQuery );
+	},
+
+	// Used for matching numbers
+	core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,
+
+	// Used for detecting and trimming whitespace
+	core_rnotwhite = /\S/,
+	core_rspace = /\s+/,
+
+	// Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
+	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+
+	// A simple way to check for HTML strings
+	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+	rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
+
+	// Match a standalone tag
+	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
+
+	// JSON RegExp
+	rvalidchars = /^[\],:{}\s]*$/,
+	rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+	rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,
+	rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,
+
+	// Matches dashed string for camelizing
+	rmsPrefix = /^-ms-/,
+	rdashAlpha = /-([\da-z])/gi,
+
+	// Used by jQuery.camelCase as callback to replace()
+	fcamelCase = function( all, letter ) {
+		return ( letter + "" ).toUpperCase();
+	},
+
+	// The ready event handler and self cleanup method
+	DOMContentLoaded = function() {
+		if ( document.addEventListener ) {
+			document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+			jQuery.ready();
+		} else if ( document.readyState === "complete" ) {
+			// we're here because readyState === "complete" in oldIE
+			// which is good enough for us to call the dom ready!
+			document.detachEvent( "onreadystatechange", DOMContentLoaded );
+			jQuery.ready();
+		}
+	},
+
+	// [[Class]] -> type pairs
+	class2type = {};
+
+jQuery.fn = jQuery.prototype = {
+	constructor: jQuery,
+	init: function( selector, context, rootjQuery ) {
+		var match, elem, ret, doc;
+
+		// Handle $(""), $(null), $(undefined), $(false)
+		if ( !selector ) {
+			return this;
+		}
+
+		// Handle $(DOMElement)
+		if ( selector.nodeType ) {
+			this.context = this[0] = selector;
+			this.length = 1;
+			return this;
+		}
+
+		// Handle HTML strings
+		if ( typeof selector === "string" ) {
+			if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
+				// Assume that strings that start and end with <> are HTML and skip the regex check
+				match = [ null, selector, null ];
+
+			} else {
+				match = rquickExpr.exec( selector );
+			}
+
+			// Match html or make sure no context is specified for #id
+			if ( match && (match[1] || !context) ) {
+
+				// HANDLE: $(html) -> $(array)
+				if ( match[1] ) {
+					context = context instanceof jQuery ? context[0] : context;
+					doc = ( context && context.nodeType ? context.ownerDocument || context : document );
+
+					// scripts is true for back-compat
+					selector = jQuery.parseHTML( match[1], doc, true );
+					if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
+						this.attr.call( selector, context, true );
+					}
+
+					return jQuery.merge( this, selector );
+
+				// HANDLE: $(#id)
+				} else {
+					elem = document.getElementById( match[2] );
+
+					// Check parentNode to catch when Blackberry 4.6 returns
+					// nodes that are no longer in the document #6963
+					if ( elem && elem.parentNode ) {
+						// Handle the case where IE and Opera return items
+						// by name instead of ID
+						if ( elem.id !== match[2] ) {
+							return rootjQuery.find( selector );
+						}
+
+						// Otherwise, we inject the element directly into the jQuery object
+						this.length = 1;
+						this[0] = elem;
+					}
+
+					this.context = document;
+					this.selector = selector;
+					return this;
+				}
+
+			// HANDLE: $(expr, $(...))
+			} else if ( !context || context.jquery ) {
+				return ( context || rootjQuery ).find( selector );
+
+			// HANDLE: $(expr, context)
+			// (which is just equivalent to: $(context).find(expr)
+			} else {
+				return this.constructor( context ).find( selector );
+			}
+
+		// HANDLE: $(function)
+		// Shortcut for document ready
+		} else if ( jQuery.isFunction( selector ) ) {
+			return rootjQuery.ready( selector );
+		}
+
+		if ( selector.selector !== undefined ) {
+			this.selector = selector.selector;
+			this.context = selector.context;
+		}
+
+		return jQuery.makeArray( selector, this );
+	},
+
+	// Start with an empty selector
+	selector: "",
+
+	// The current version of jQuery being used
+	jquery: "1.8.3",
+
+	// The default length of a jQuery object is 0
+	length: 0,
+
+	// The number of elements contained in the matched element set
+	size: function() {
+		return this.length;
+	},
+
+	toArray: function() {
+		return core_slice.call( this );
+	},
+
+	// Get the Nth element in the matched element set OR
+	// Get the whole matched element set as a clean array
+	get: function( num ) {
+		return num == null ?
+
+			// Return a 'clean' array
+			this.toArray() :
+
+			// Return just the object
+			( num < 0 ? this[ this.length + num ] : this[ num ] );
+	},
+
+	// Take an array of elements and push it onto the stack
+	// (returning the new matched element set)
+	pushStack: function( elems, name, selector ) {
+
+		// Build a new jQuery matched element set
+		var ret = jQuery.merge( this.constructor(), elems );
+
+		// Add the old object onto the stack (as a reference)
+		ret.prevObject = this;
+
+		ret.context = this.context;
+
+		if ( name === "find" ) {
+			ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;
+		} else if ( name ) {
+			ret.selector = this.selector + "." + name + "(" + selector + ")";
+		}
+
+		// Return the newly-formed element set
+		return ret;
+	},
+
+	// Execute a callback for every element in the matched set.
+	// (You can seed the arguments with an array of args, but this is
+	// only used internally.)
+	each: function( callback, args ) {
+		return jQuery.each( this, callback, args );
+	},
+
+	ready: function( fn ) {
+		// Add the callback
+		jQuery.ready.promise().done( fn );
+
+		return this;
+	},
+
+	eq: function( i ) {
+		i = +i;
+		return i === -1 ?
+			this.slice( i ) :
+			this.slice( i, i + 1 );
+	},
+
+	first: function() {
+		return this.eq( 0 );
+	},
+
+	last: function() {
+		return this.eq( -1 );
+	},
+
+	slice: function() {
+		return this.pushStack( core_slice.apply( this, arguments ),
+			"slice", core_slice.call(arguments).join(",") );
+	},
+
+	map: function( callback ) {
+		return this.pushStack( jQuery.map(this, function( elem, i ) {
+			return callback.call( elem, i, elem );
+		}));
+	},
+
+	end: function() {
+		return this.prevObject || this.constructor(null);
+	},
+
+	// For internal use only.
+	// Behaves like an Array's method, not like a jQuery method.
+	push: core_push,
+	sort: [].sort,
+	splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+	var options, name, src, copy, copyIsArray, clone,
+		target = arguments[0] || {},
+		i = 1,
+		length = arguments.length,
+		deep = false;
+
+	// Handle a deep copy situation
+	if ( typeof target === "boolean" ) {
+		deep = target;
+		target = arguments[1] || {};
+		// skip the boolean and the target
+		i = 2;
+	}
+
+	// Handle case when target is a string or something (possible in deep copy)
+	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+		target = {};
+	}
+
+	// extend jQuery itself if only one argument is passed
+	if ( length === i ) {
+		target = this;
+		--i;
+	}
+
+	for ( ; i < length; i++ ) {
+		// Only deal with non-null/undefined values
+		if ( (options = arguments[ i ]) != null ) {
+			// Extend the base object
+			for ( name in options ) {
+				src = target[ name ];
+				copy = options[ name ];
+
+				// Prevent never-ending loop
+				if ( target === copy ) {
+					continue;
+				}
+
+				// Recurse if we're merging plain objects or arrays
+				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+					if ( copyIsArray ) {
+						copyIsArray = false;
+						clone = src && jQuery.isArray(src) ? src : [];
+
+					} else {
+						clone = src && jQuery.isPlainObject(src) ? src : {};
+					}
+
+					// Never move original objects, clone them
+					target[ name ] = jQuery.extend( deep, clone, copy );
+
+				// Don't bring in undefined values
+				} else if ( copy !== undefined ) {
+					target[ name ] = copy;
+				}
+			}
+		}
+	}
+
+	// Return the modified object
+	return target;
+};
+
+jQuery.extend({
+	noConflict: function( deep ) {
+		if ( window.$ === jQuery ) {
+			window.$ = _$;
+		}
+
+		if ( deep && window.jQuery === jQuery ) {
+			window.jQuery = _jQuery;
+		}
+
+		return jQuery;
+	},
+
+	// Is the DOM ready to be used? Set to true once it occurs.
+	isReady: false,
+
+	// A counter to track how many items to wait for before
+	// the ready event fires. See #6781
+	readyWait: 1,
+
+	// Hold (or release) the ready event
+	holdReady: function( hold ) {
+		if ( hold ) {
+			jQuery.readyWait++;
+		} else {
+			jQuery.ready( true );
+		}
+	},
+
+	// Handle when the DOM is ready
+	ready: function( wait ) {
+
+		// Abort if there are pending holds or we're already ready
+		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+			return;
+		}
+
+		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+		if ( !document.body ) {
+			return setTimeout( jQuery.ready, 1 );
+		}
+
+		// Remember that the DOM is ready
+		jQuery.isReady = true;
+
+		// If a normal DOM Ready event fired, decrement, and wait if need be
+		if ( wait !== true && --jQuery.readyWait > 0 ) {
+			return;
+		}
+
+		// If there are functions bound, to execute
+		readyList.resolveWith( document, [ jQuery ] );
+
+		// Trigger any bound ready events
+		if ( jQuery.fn.trigger ) {
+			jQuery( document ).trigger("ready").off("ready");
+		}
+	},
+
+	// See test/unit/core.js for details concerning isFunction.
+	// Since version 1.3, DOM methods and functions like alert
+	// aren't supported. They return false on IE (#2968).
+	isFunction: function( obj ) {
+		return jQuery.type(obj) === "function";
+	},
+
+	isArray: Array.isArray || function( obj ) {
+		return jQuery.type(obj) === "array";
+	},
+
+	isWindow: function( obj ) {
+		return obj != null && obj == obj.window;
+	},
+
+	isNumeric: function( obj ) {
+		return !isNaN( parseFloat(obj) ) && isFinite( obj );
+	},
+
+	type: function( obj ) {
+		return obj == null ?
+			String( obj ) :
+			class2type[ core_toString.call(obj) ] || "object";
+	},
+
+	isPlainObject: function( obj ) {
+		// Must be an Object.
+		// Because of IE, we also have to check the presence of the constructor property.
+		// Make sure that DOM nodes and window objects don't pass through, as well
+		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+			return false;
+		}
+
+		try {
+			// Not own constructor property must be Object
+			if ( obj.constructor &&
+				!core_hasOwn.call(obj, "constructor") &&
+				!core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+				return false;
+			}
+		} catch ( e ) {
+			// IE8,9 Will throw exceptions on certain host objects #9897
+			return false;
+		}
+
+		// Own properties are enumerated firstly, so to speed up,
+		// if last one is own, then all properties are own.
+
+		var key;
+		for ( key in obj ) {}
+
+		return key === undefined || core_hasOwn.call( obj, key );
+	},
+
+	isEmptyObject: function( obj ) {
+		var name;
+		for ( name in obj ) {
+			return false;
+		}
+		return true;
+	},
+
+	error: function( msg ) {
+		throw new Error( msg );
+	},
+
+	// data: string of html
+	// context (optional): If specified, the fragment will be created in this context, defaults to document
+	// scripts (optional): If true, will include scripts passed in the html string
+	parseHTML: function( data, context, scripts ) {
+		var parsed;
+		if ( !data || typeof data !== "string" ) {
+			return null;
+		}
+		if ( typeof context === "boolean" ) {
+			scripts = context;
+			context = 0;
+		}
+		context = context || document;
+
+		// Single tag
+		if ( (parsed = rsingleTag.exec( data )) ) {
+			return [ context.createElement( parsed[1] ) ];
+		}
+
+		parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] );
+		return jQuery.merge( [],
+			(parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes );
+	},
+
+	parseJSON: function( data ) {
+		if ( !data || typeof data !== "string") {
+			return null;
+		}
+
+		// Make sure leading/trailing whitespace is removed (IE can't handle it)
+		data = jQuery.trim( data );
+
+		// Attempt to parse using the native JSON parser first
+		if ( window.JSON && window.JSON.parse ) {
+			return window.JSON.parse( data );
+		}
+
+		// Make sure the incoming data is actual JSON
+		// Logic borrowed from http://json.org/json2.js
+		if ( rvalidchars.test( data.replace( rvalidescape, "@" )
+			.replace( rvalidtokens, "]" )
+			.replace( rvalidbraces, "")) ) {
+
+			return ( new Function( "return " + data ) )();
+
+		}
+		jQuery.error( "Invalid JSON: " + data );
+	},
+
+	// Cross-browser xml parsing
+	parseXML: function( data ) {
+		var xml, tmp;
+		if ( !data || typeof data !== "string" ) {
+			return null;
+		}
+		try {
+			if ( window.DOMParser ) { // Standard
+				tmp = new DOMParser();
+				xml = tmp.parseFromString( data , "text/xml" );
+			} else { // IE
+				xml = new ActiveXObject( "Microsoft.XMLDOM" );
+				xml.async = "false";
+				xml.loadXML( data );
+			}
+		} catch( e ) {
+			xml = undefined;
+		}
+		if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
+			jQuery.error( "Invalid XML: " + data );
+		}
+		return xml;
+	},
+
+	noop: function() {},
+
+	// Evaluates a script in a global context
+	// Workarounds based on findings by Jim Driscoll
+	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+	globalEval: function( data ) {
+		if ( data && core_rnotwhite.test( data ) ) {
+			// We use execScript on Internet Explorer
+			// We use an anonymous function so that context is window
+			// rather than jQuery in Firefox
+			( window.execScript || function( data ) {
+				window[ "eval" ].call( window, data );
+			} )( data );
+		}
+	},
+
+	// Convert dashed to camelCase; used by the css and data modules
+	// Microsoft forgot to hump their vendor prefix (#9572)
+	camelCase: function( string ) {
+		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+	},
+
+	nodeName: function( elem, name ) {
+		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+	},
+
+	// args is for internal usage only
+	each: function( obj, callback, args ) {
+		var name,
+			i = 0,
+			length = obj.length,
+			isObj = length === undefined || jQuery.isFunction( obj );
+
+		if ( args ) {
+			if ( isObj ) {
+				for ( name in obj ) {
+					if ( callback.apply( obj[ name ], args ) === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( ; i < length; ) {
+					if ( callback.apply( obj[ i++ ], args ) === false ) {
+						break;
+					}
+				}
+			}
+
+		// A special, fast, case for the most common use of each
+		} else {
+			if ( isObj ) {
+				for ( name in obj ) {
+					if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( ; i < length; ) {
+					if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) {
+						break;
+					}
+				}
+			}
+		}
+
+		return obj;
+	},
+
+	// Use native String.trim function wherever possible
+	trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
+		function( text ) {
+			return text == null ?
+				"" :
+				core_trim.call( text );
+		} :
+
+		// Otherwise use our own trimming functionality
+		function( text ) {
+			return text == null ?
+				"" :
+				( text + "" ).replace( rtrim, "" );
+		},
+
+	// results is for internal usage only
+	makeArray: function( arr, results ) {
+		var type,
+			ret = results || [];
+
+		if ( arr != null ) {
+			// The window, strings (and functions) also have 'length'
+			// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
+			type = jQuery.type( arr );
+
+			if ( arr.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( arr ) ) {
+				core_push.call( ret, arr );
+			} else {
+				jQuery.merge( ret, arr );
+			}
+		}
+
+		return ret;
+	},
+
+	inArray: function( elem, arr, i ) {
+		var len;
+
+		if ( arr ) {
+			if ( core_indexOf ) {
+				return core_indexOf.call( arr, elem, i );
+			}
+
+			len = arr.length;
+			i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
+
+			for ( ; i < len; i++ ) {
+				// Skip accessing in sparse arrays
+				if ( i in arr && arr[ i ] === elem ) {
+					return i;
+				}
+			}
+		}
+
+		return -1;
+	},
+
+	merge: function( first, second ) {
+		var l = second.length,
+			i = first.length,
+			j = 0;
+
+		if ( typeof l === "number" ) {
+			for ( ; j < l; j++ ) {
+				first[ i++ ] = second[ j ];
+			}
+
+		} else {
+			while ( second[j] !== undefined ) {
+				first[ i++ ] = second[ j++ ];
+			}
+		}
+
+		first.length = i;
+
+		return first;
+	},
+
+	grep: function( elems, callback, inv ) {
+		var retVal,
+			ret = [],
+			i = 0,
+			length = elems.length;
+		inv = !!inv;
+
+		// Go through the array, only saving the items
+		// that pass the validator function
+		for ( ; i < length; i++ ) {
+			retVal = !!callback( elems[ i ], i );
+			if ( inv !== retVal ) {
+				ret.push( elems[ i ] );
+			}
+		}
+
+		return ret;
+	},
+
+	// arg is for internal usage only
+	map: function( elems, callback, arg ) {
+		var value, key,
+			ret = [],
+			i = 0,
+			length = elems.length,
+			// jquery objects are treated as arrays
+			isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
+
+		// Go through the array, translating each of the items to their
+		if ( isArray ) {
+			for ( ; i < length; i++ ) {
+				value = callback( elems[ i ], i, arg );
+
+				if ( value != null ) {
+					ret[ ret.length ] = value;
+				}
+			}
+
+		// Go through every key on the object,
+		} else {
+			for ( key in elems ) {
+				value = callback( elems[ key ], key, arg );
+
+				if ( value != null ) {
+					ret[ ret.length ] = value;
+				}
+			}
+		}
+
+		// Flatten any nested arrays
+		return ret.concat.apply( [], ret );
+	},
+
+	// A global GUID counter for objects
+	guid: 1,
+
+	// Bind a function to a context, optionally partially applying any
+	// arguments.
+	proxy: function( fn, context ) {
+		var tmp, args, proxy;
+
+		if ( typeof context === "string" ) {
+			tmp = fn[ context ];
+			context = fn;
+			fn = tmp;
+		}
+
+		// Quick check to determine if target is callable, in the spec
+		// this throws a TypeError, but we will just return undefined.
+		if ( !jQuery.isFunction( fn ) ) {
+			return undefined;
+		}
+
+		// Simulated bind
+		args = core_slice.call( arguments, 2 );
+		proxy = function() {
+			return fn.apply( context, args.concat( core_slice.call( arguments ) ) );
+		};
+
+		// Set the guid of unique handler to the same of original handler, so it can be removed
+		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
+
+		return proxy;
+	},
+
+	// Multifunctional method to get and set values of a collection
+	// The value/s can optionally be executed if it's a function
+	access: function( elems, fn, key, value, chainable, emptyGet, pass ) {
+		var exec,
+			bulk = key == null,
+			i = 0,
+			length = elems.length;
+
+		// Sets many values
+		if ( key && typeof key === "object" ) {
+			for ( i in key ) {
+				jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );
+			}
+			chainable = 1;
+
+		// Sets one value
+		} else if ( value !== undefined ) {
+			// Optionally, function values get executed if exec is true
+			exec = pass === undefined && jQuery.isFunction( value );
+
+			if ( bulk ) {
+				// Bulk operations only iterate when executing function values
+				if ( exec ) {
+					exec = fn;
+					fn = function( elem, key, value ) {
+						return exec.call( jQuery( elem ), value );
+					};
+
+				// Otherwise they run against the entire set
+				} else {
+					fn.call( elems, value );
+					fn = null;
+				}
+			}
+
+			if ( fn ) {
+				for (; i < length; i++ ) {
+					fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+				}
+			}
+
+			chainable = 1;
+		}
+
+		return chainable ?
+			elems :
+
+			// Gets
+			bulk ?
+				fn.call( elems ) :
+				length ? fn( elems[0], key ) : emptyGet;
+	},
+
+	now: function() {
+		return ( new Date() ).getTime();
+	}
+});
+
+jQuery.ready.promise = function( obj ) {
+	if ( !readyList ) {
+
+		readyList = jQuery.Deferred();
+
+		// Catch cases where $(document).ready() is called after the browser event has already occurred.
+		// we once tried to use readyState "interactive" here, but it caused issues like the one
+		// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
+		if ( document.readyState === "complete" ) {
+			// Handle it asynchronously to allow scripts the opportunity to delay ready
+			setTimeout( jQuery.ready, 1 );
+
+		// Standards-based browsers support DOMContentLoaded
+		} else if ( document.addEventListener ) {
+			// Use the handy event callback
+			document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+
+			// A fallback to window.onload, that will always work
+			window.addEventListener( "load", jQuery.ready, false );
+
+		// If IE event model is used
+		} else {
+			// Ensure firing before onload, maybe late but safe also for iframes
+			document.attachEvent( "onreadystatechange", DOMContentLoaded );
+
+			// A fallback to window.onload, that will always work
+			window.attachEvent( "onload", jQuery.ready );
+
+			// If IE and not a frame
+			// continually check to see if the document is ready
+			var top = false;
+
+			try {
+				top = window.frameElement == null && document.documentElement;
+			} catch(e) {}
+
+			if ( top && top.doScroll ) {
+				(function doScrollCheck() {
+					if ( !jQuery.isReady ) {
+
+						try {
+							// Use the trick by Diego Perini
+							// http://javascript.nwbox.com/IEContentLoaded/
+							top.doScroll("left");
+						} catch(e) {
+							return setTimeout( doScrollCheck, 50 );
+						}
+
+						// and execute any waiting functions
+						jQuery.ready();
+					}
+				})();
+			}
+		}
+	}
+	return readyList.promise( obj );
+};
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
+	class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+// String to Object options format cache
+var optionsCache = {};
+
+// Convert String-formatted options into Object-formatted ones and store in cache
+function createOptions( options ) {
+	var object = optionsCache[ options ] = {};
+	jQuery.each( options.split( core_rspace ), function( _, flag ) {
+		object[ flag ] = true;
+	});
+	return object;
+}
+
+/*
+ * Create a callback list using the following parameters:
+ *
+ *	options: an optional list of space-separated options that will change how
+ *			the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ *	once:			will ensure the callback list can only be fired once (like a Deferred)
+ *
+ *	memory:			will keep track of previous values and will call any callback added
+ *					after the list has been fired right away with the latest "memorized"
+ *					values (like a Deferred)
+ *
+ *	unique:			will ensure a callback can only be added once (no duplicate in the list)
+ *
+ *	stopOnFalse:	interrupt callings when a callback returns false
+ *
+ */
+jQuery.Callbacks = function( options ) {
+
+	// Convert options from String-formatted to Object-formatted if needed
+	// (we check in cache first)
+	options = typeof options === "string" ?
+		( optionsCache[ options ] || createOptions( options ) ) :
+		jQuery.extend( {}, options );
+
+	var // Last fire value (for non-forgettable lists)
+		memory,
+		// Flag to know if list was already fired
+		fired,
+		// Flag to know if list is currently firing
+		firing,
+		// First callback to fire (used internally by add and fireWith)
+		firingStart,
+		// End of the loop when firing
+		firingLength,
+		// Index of currently firing callback (modified by remove if needed)
+		firingIndex,
+		// Actual callback list
+		list = [],
+		// Stack of fire calls for repeatable lists
+		stack = !options.once && [],
+		// Fire callbacks
+		fire = function( data ) {
+			memory = options.memory && data;
+			fired = true;
+			firingIndex = firingStart || 0;
+			firingStart = 0;
+			firingLength = list.length;
+			firing = true;
+			for ( ; list && firingIndex < firingLength; firingIndex++ ) {
+				if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
+					memory = false; // To prevent further calls using add
+					break;
+				}
+			}
+			firing = false;
+			if ( list ) {
+				if ( stack ) {
+					if ( stack.length ) {
+						fire( stack.shift() );
+					}
+				} else if ( memory ) {
+					list = [];
+				} else {
+					self.disable();
+				}
+			}
+		},
+		// Actual Callbacks object
+		self = {
+			// Add a callback or a collection of callbacks to the list
+			add: function() {
+				if ( list ) {
+					// First, we save the current length
+					var start = list.length;
+					(function add( args ) {
+						jQuery.each( args, function( _, arg ) {
+							var type = jQuery.type( arg );
+							if ( type === "function" ) {
+								if ( !options.unique || !self.has( arg ) ) {
+									list.push( arg );
+								}
+							} else if ( arg && arg.length && type !== "string" ) {
+								// Inspect recursively
+								add( arg );
+							}
+						});
+					})( arguments );
+					// Do we need to add the callbacks to the
+					// current firing batch?
+					if ( firing ) {
+						firingLength = list.length;
+					// With memory, if we're not firing then
+					// we should call right away
+					} else if ( memory ) {
+						firingStart = start;
+						fire( memory );
+					}
+				}
+				return this;
+			},
+			// Remove a callback from the list
+			remove: function() {
+				if ( list ) {
+					jQuery.each( arguments, function( _, arg ) {
+						var index;
+						while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+							list.splice( index, 1 );
+							// Handle firing indexes
+							if ( firing ) {
+								if ( index <= firingLength ) {
+									firingLength--;
+								}
+								if ( index <= firingIndex ) {
+									firingIndex--;
+								}
+							}
+						}
+					});
+				}
+				return this;
+			},
+			// Control if a given callback is in the list
+			has: function( fn ) {
+				return jQuery.inArray( fn, list ) > -1;
+			},
+			// Remove all callbacks from the list
+			empty: function() {
+				list = [];
+				return this;
+			},
+			// Have the list do nothing anymore
+			disable: function() {
+				list = stack = memory = undefined;
+				return this;
+			},
+			// Is it disabled?
+			disabled: function() {
+				return !list;
+			},
+			// Lock the list in its current state
+			lock: function() {
+				stack = undefined;
+				if ( !memory ) {
+					self.disable();
+				}
+				return this;
+			},
+			// Is it locked?
+			locked: function() {
+				return !stack;
+			},
+			// Call all callbacks with the given context and arguments
+			fireWith: function( context, args ) {
+				args = args || [];
+				args = [ context, args.slice ? args.slice() : args ];
+				if ( list && ( !fired || stack ) ) {
+					if ( firing ) {
+						stack.push( args );
+					} else {
+						fire( args );
+					}
+				}
+				return this;
+			},
+			// Call all the callbacks with the given arguments
+			fire: function() {
+				self.fireWith( this, arguments );
+				return this;
+			},
+			// To know if the callbacks have already been called at least once
+			fired: function() {
+				return !!fired;
+			}
+		};
+
+	return self;
+};
+jQuery.extend({
+
+	Deferred: function( func ) {
+		var tuples = [
+				// action, add listener, listener list, final state
+				[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
+				[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
+				[ "notify", "progress", jQuery.Callbacks("memory") ]
+			],
+			state = "pending",
+			promise = {
+				state: function() {
+					return state;
+				},
+				always: function() {
+					deferred.done( arguments ).fail( arguments );
+					return this;
+				},
+				then: function( /* fnDone, fnFail, fnProgress */ ) {
+					var fns = arguments;
+					return jQuery.Deferred(function( newDefer ) {
+						jQuery.each( tuples, function( i, tuple ) {
+							var action = tuple[ 0 ],
+								fn = fns[ i ];
+							// deferred[ done | fail | progress ] for forwarding actions to newDefer
+							deferred[ tuple[1] ]( jQuery.isFunction( fn ) ?
+								function() {
+									var returned = fn.apply( this, arguments );
+									if ( returned && jQuery.isFunction( returned.promise ) ) {
+										returned.promise()
+											.done( newDefer.resolve )
+											.fail( newDefer.reject )
+											.progress( newDefer.notify );
+									} else {
+										newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
+									}
+								} :
+								newDefer[ action ]
+							);
+						});
+						fns = null;
+					}).promise();
+				},
+				// Get a promise for this deferred
+				// If obj is provided, the promise aspect is added to the object
+				promise: function( obj ) {
+					return obj != null ? jQuery.extend( obj, promise ) : promise;
+				}
+			},
+			deferred = {};
+
+		// Keep pipe for back-compat
+		promise.pipe = promise.then;
+
+		// Add list-specific methods
+		jQuery.each( tuples, function( i, tuple ) {
+			var list = tuple[ 2 ],
+				stateString = tuple[ 3 ];
+
+			// promise[ done | fail | progress ] = list.add
+			promise[ tuple[1] ] = list.add;
+
+			// Handle state
+			if ( stateString ) {
+				list.add(function() {
+					// state = [ resolved | rejected ]
+					state = stateString;
+
+				// [ reject_list | resolve_list ].disable; progress_list.lock
+				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
+			}
+
+			// deferred[ resolve | reject | notify ] = list.fire
+			deferred[ tuple[0] ] = list.fire;
+			deferred[ tuple[0] + "With" ] = list.fireWith;
+		});
+
+		// Make the deferred a promise
+		promise.promise( deferred );
+
+		// Call given func if any
+		if ( func ) {
+			func.call( deferred, deferred );
+		}
+
+		// All done!
+		return deferred;
+	},
+
+	// Deferred helper
+	when: function( subordinate /* , ..., subordinateN */ ) {
+		var i = 0,
+			resolveValues = core_slice.call( arguments ),
+			length = resolveValues.length,
+
+			// the count of uncompleted subordinates
+			remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
+
+			// the master Deferred. If resolveValues consist of only a single Deferred, just use that.
+			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
+
+			// Update function for both resolve and progress values
+			updateFunc = function( i, contexts, values ) {
+				return function( value ) {
+					contexts[ i ] = this;
+					values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
+					if( values === progressValues ) {
+						deferred.notifyWith( contexts, values );
+					} else if ( !( --remaining ) ) {
+						deferred.resolveWith( contexts, values );
+					}
+				};
+			},
+
+			progressValues, progressContexts, resolveContexts;
+
+		// add listeners to Deferred subordinates; treat others as resolved
+		if ( length > 1 ) {
+			progressValues = new Array( length );
+			progressContexts = new Array( length );
+			resolveContexts = new Array( length );
+			for ( ; i < length; i++ ) {
+				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
+					resolveValues[ i ].promise()
+						.done( updateFunc( i, resolveContexts, resolveValues ) )
+						.fail( deferred.reject )
+						.progress( updateFunc( i, progressContexts, progressValues ) );
+				} else {
+					--remaining;
+				}
+			}
+		}
+
+		// if we're not waiting on anything, resolve the master
+		if ( !remaining ) {
+			deferred.resolveWith( resolveContexts, resolveValues );
+		}
+
+		return deferred.promise();
+	}
+});
+jQuery.support = (function() {
+
+	var support,
+		all,
+		a,
+		select,
+		opt,
+		input,
+		fragment,
+		eventName,
+		i,
+		isSupported,
+		clickFn,
+		div = document.createElement("div");
+
+	// Setup
+	div.setAttribute( "className", "t" );
+	div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
+
+	// Support tests won't run in some limited or non-browser environments
+	all = div.getElementsByTagName("*");
+	a = div.getElementsByTagName("a")[ 0 ];
+	if ( !all || !a || !all.length ) {
+		return {};
+	}
+
+	// First batch of tests
+	select = document.createElement("select");
+	opt = select.appendChild( document.createElement("option") );
+	input = div.getElementsByTagName("input")[ 0 ];
+
+	a.style.cssText = "top:1px;float:left;opacity:.5";
+	support = {
+		// IE strips leading whitespace when .innerHTML is used
+		leadingWhitespace: ( div.firstChild.nodeType === 3 ),
+
+		// Make sure that tbody elements aren't automatically inserted
+		// IE will insert them into empty tables
+		tbody: !div.getElementsByTagName("tbody").length,
+
+		// Make sure that link elements get serialized correctly by innerHTML
+		// This requires a wrapper element in IE
+		htmlSerialize: !!div.getElementsByTagName("link").length,
+
+		// Get the style information from getAttribute
+		// (IE uses .cssText instead)
+		style: /top/.test( a.getAttribute("style") ),
+
+		// Make sure that URLs aren't manipulated
+		// (IE normalizes it by default)
+		hrefNormalized: ( a.getAttribute("href") === "/a" ),
+
+		// Make sure that element opacity exists
+		// (IE uses filter instead)
+		// Use a regex to work around a WebKit issue. See #5145
+		opacity: /^0.5/.test( a.style.opacity ),
+
+		// Verify style float existence
+		// (IE uses styleFloat instead of cssFloat)
+		cssFloat: !!a.style.cssFloat,
+
+		// Make sure that if no value is specified for a checkbox
+		// that it defaults to "on".
+		// (WebKit defaults to "" instead)
+		checkOn: ( input.value === "on" ),
+
+		// Make sure that a selected-by-default option has a working selected property.
+		// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+		optSelected: opt.selected,
+
+		// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
+		getSetAttribute: div.className !== "t",
+
+		// Tests for enctype support on a form (#6743)
+		enctype: !!document.createElement("form").enctype,
+
+		// Makes sure cloning an html5 element does not cause problems
+		// Where outerHTML is undefined, this still works
+		html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",
+
+		// jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode
+		boxModel: ( document.compatMode === "CSS1Compat" ),
+
+		// Will be defined later
+		submitBubbles: true,
+		changeBubbles: true,
+		focusinBubbles: false,
+		deleteExpando: true,
+		noCloneEvent: true,
+		inlineBlockNeedsLayout: false,
+		shrinkWrapBlocks: false,
+		reliableMarginRight: true,
+		boxSizingReliable: true,
+		pixelPosition: false
+	};
+
+	// Make sure checked status is properly cloned
+	input.checked = true;
+	support.noCloneChecked = input.cloneNode( true ).checked;
+
+	// Make sure that the options inside disabled selects aren't marked as disabled
+	// (WebKit marks them as disabled)
+	select.disabled = true;
+	support.optDisabled = !opt.disabled;
+
+	// Test to see if it's possible to delete an expando from an element
+	// Fails in Internet Explorer
+	try {
+		delete div.test;
+	} catch( e ) {
+		support.deleteExpando = false;
+	}
+
+	if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
+		div.attachEvent( "onclick", clickFn = function() {
+			// Cloning a node shouldn't copy over any
+			// bound event handlers (IE does this)
+			support.noCloneEvent = false;
+		});
+		div.cloneNode( true ).fireEvent("onclick");
+		div.detachEvent( "onclick", clickFn );
+	}
+
+	// Check if a radio maintains its value
+	// after being appended to the DOM
+	input = document.createElement("input");
+	input.value = "t";
+	input.setAttribute( "type", "radio" );
+	support.radioValue = input.value === "t";
+
+	input.setAttribute( "checked", "checked" );
+
+	// #11217 - WebKit loses check when the name is after the checked attribute
+	input.setAttribute( "name", "t" );
+
+	div.appendChild( input );
+	fragment = document.createDocumentFragment();
+	fragment.appendChild( div.lastChild );
+
+	// WebKit doesn't clone checked state correctly in fragments
+	support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+	// Check if a disconnected checkbox will retain its checked
+	// value of true after appended to the DOM (IE6/7)
+	support.appendChecked = input.checked;
+
+	fragment.removeChild( input );
+	fragment.appendChild( div );
+
+	// Technique from Juriy Zaytsev
+	// http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
+	// We only care about the case where non-standard event systems
+	// are used, namely in IE. Short-circuiting here helps us to
+	// avoid an eval call (in setAttribute) which can cause CSP
+	// to go haywire. See: https://developer.mozilla.org/en/Security/CSP
+	if ( div.attachEvent ) {
+		for ( i in {
+			submit: true,
+			change: true,
+			focusin: true
+		}) {
+			eventName = "on" + i;
+			isSupported = ( eventName in div );
+			if ( !isSupported ) {
+				div.setAttribute( eventName, "return;" );
+				isSupported = ( typeof div[ eventName ] === "function" );
+			}
+			support[ i + "Bubbles" ] = isSupported;
+		}
+	}
+
+	// Run tests that need a body at doc ready
+	jQuery(function() {
+		var container, div, tds, marginDiv,
+			divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;",
+			body = document.getElementsByTagName("body")[0];
+
+		if ( !body ) {
+			// Return for frameset docs that don't have a body
+			return;
+		}
+
+		container = document.createElement("div");
+		container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px";
+		body.insertBefore( container, body.firstChild );
+
+		// Construct the test element
+		div = document.createElement("div");
+		container.appendChild( div );
+
+		// Check if table cells still have offsetWidth/Height when they are set
+		// to display:none and there are still other visible table cells in a
+		// table row; if so, offsetWidth/Height are not reliable for use when
+		// determining if an element has been hidden directly using
+		// display:none (it is still safe to use offsets if a parent element is
+		// hidden; don safety goggles and see bug #4512 for more information).
+		// (only IE 8 fails this test)
+		div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
+		tds = div.getElementsByTagName("td");
+		tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none";
+		isSupported = ( tds[ 0 ].offsetHeight === 0 );
+
+		tds[ 0 ].style.display = "";
+		tds[ 1 ].style.display = "none";
+
+		// Check if empty table cells still have offsetWidth/Height
+		// (IE <= 8 fail this test)
+		support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
+
+		// Check box-sizing and margin behavior
+		div.innerHTML = "";
+		div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";
+		support.boxSizing = ( div.offsetWidth === 4 );
+		support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );
+
+		// NOTE: To any future maintainer, we've window.getComputedStyle
+		// because jsdom on node.js will break without it.
+		if ( window.getComputedStyle ) {
+			support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
+			support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
+
+			// Check if div with explicit width and no margin-right incorrectly
+			// gets computed margin-right based on width of container. For more
+			// info see bug #3333
+			// Fails in WebKit before Feb 2011 nightlies
+			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+			marginDiv = document.createElement("div");
+			marginDiv.style.cssText = div.style.cssText = divReset;
+			marginDiv.style.marginRight = marginDiv.style.width = "0";
+			div.style.width = "1px";
+			div.appendChild( marginDiv );
+			support.reliableMarginRight =
+				!parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
+		}
+
+		if ( typeof div.style.zoom !== "undefined" ) {
+			// Check if natively block-level elements act like inline-block
+			// elements when setting their display to 'inline' and giving
+			// them layout
+			// (IE < 8 does this)
+			div.innerHTML = "";
+			div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1";
+			support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
+
+			// Check if elements with layout shrink-wrap their children
+			// (IE 6 does this)
+			div.style.display = "block";
+			div.style.overflow = "visible";
+			div.innerHTML = "<div></div>";
+			div.firstChild.style.width = "5px";
+			support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
+
+			container.style.zoom = 1;
+		}
+
+		// Null elements to avoid leaks in IE
+		body.removeChild( container );
+		container = div = tds = marginDiv = null;
+	});
+
+	// Null elements to avoid leaks in IE
+	fragment.removeChild( div );
+	all = a = select = opt = input = fragment = div = null;
+
+	return support;
+})();
+var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
+	rmultiDash = /([A-Z])/g;
+
+jQuery.extend({
+	cache: {},
+
+	deletedIds: [],
+
+	// Remove at next major release (1.9/2.0)
+	uuid: 0,
+
+	// Unique for each copy of jQuery on the page
+	// Non-digits removed to match rinlinejQuery
+	expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
+
+	// The following elements throw uncatchable exceptions if you
+	// attempt to add expando properties to them.
+	noData: {
+		"embed": true,
+		// Ban all objects except for Flash (which handle expandos)
+		"object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
+		"applet": true
+	},
+
+	hasData: function( elem ) {
+		elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
+		return !!elem && !isEmptyDataObject( elem );
+	},
+
+	data: function( elem, name, data, pvt /* Internal Use Only */ ) {
+		if ( !jQuery.acceptData( elem ) ) {
+			return;
+		}
+
+		var thisCache, ret,
+			internalKey = jQuery.expando,
+			getByName = typeof name === "string",
+
+			// We have to handle DOM nodes and JS objects differently because IE6-7
+			// can't GC object references properly across the DOM-JS boundary
+			isNode = elem.nodeType,
+
+			// Only DOM nodes need the global jQuery cache; JS object data is
+			// attached directly to the object so GC can occur automatically
+			cache = isNode ? jQuery.cache : elem,
+
+			// Only defining an ID for JS objects if its cache already exists allows
+			// the code to shortcut on the same path as a DOM node with no cache
+			id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
+
+		// Avoid doing any more work than we need to when trying to get data on an
+		// object that has no data at all
+		if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) {
+			return;
+		}
+
+		if ( !id ) {
+			// Only DOM nodes need a new unique ID for each element since their data
+			// ends up in the global cache
+			if ( isNode ) {
+				elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++;
+			} else {
+				id = internalKey;
+			}
+		}
+
+		if ( !cache[ id ] ) {
+			cache[ id ] = {};
+
+			// Avoids exposing jQuery metadata on plain JS objects when the object
+			// is serialized using JSON.stringify
+			if ( !isNode ) {
+				cache[ id ].toJSON = jQuery.noop;
+			}
+		}
+
+		// An object can be passed to jQuery.data instead of a key/value pair; this gets
+		// shallow copied over onto the existing cache
+		if ( typeof name === "object" || typeof name === "function" ) {
+			if ( pvt ) {
+				cache[ id ] = jQuery.extend( cache[ id ], name );
+			} else {
+				cache[ id ].data = jQuery.extend( cache[ id ].data, name );
+			}
+		}
+
+		thisCache = cache[ id ];
+
+		// jQuery data() is stored in a separate object inside the object's internal data
+		// cache in order to avoid key collisions between internal data and user-defined
+		// data.
+		if ( !pvt ) {
+			if ( !thisCache.data ) {
+				thisCache.data = {};
+			}
+
+			thisCache = thisCache.data;
+		}
+
+		if ( data !== undefined ) {
+			thisCache[ jQuery.camelCase( name ) ] = data;
+		}
+
+		// Check for both converted-to-camel and non-converted data property names
+		// If a data property was specified
+		if ( getByName ) {
+
+			// First Try to find as-is property data
+			ret = thisCache[ name ];
+
+			// Test for null|undefined property data
+			if ( ret == null ) {
+
+				// Try to find the camelCased property
+				ret = thisCache[ jQuery.camelCase( name ) ];
+			}
+		} else {
+			ret = thisCache;
+		}
+
+		return ret;
+	},
+
+	removeData: function( elem, name, pvt /* Internal Use Only */ ) {
+		if ( !jQuery.acceptData( elem ) ) {
+			return;
+		}
+
+		var thisCache, i, l,
+
+			isNode = elem.nodeType,
+
+			// See jQuery.data for more information
+			cache = isNode ? jQuery.cache : elem,
+			id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
+
+		// If there is already no cache entry for this object, there is no
+		// purpose in continuing
+		if ( !cache[ id ] ) {
+			return;
+		}
+
+		if ( name ) {
+
+			thisCache = pvt ? cache[ id ] : cache[ id ].data;
+
+			if ( thisCache ) {
+
+				// Support array or space separated string names for data keys
+				if ( !jQuery.isArray( name ) ) {
+
+					// try the string as a key before any manipulation
+					if ( name in thisCache ) {
+						name = [ name ];
+					} else {
+
+						// split the camel cased version by spaces unless a key with the spaces exists
+						name = jQuery.camelCase( name );
+						if ( name in thisCache ) {
+							name = [ name ];
+						} else {
+							name = name.split(" ");
+						}
+					}
+				}
+
+				for ( i = 0, l = name.length; i < l; i++ ) {
+					delete thisCache[ name[i] ];
+				}
+
+				// If there is no data left in the cache, we want to continue
+				// and let the cache object itself get destroyed
+				if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
+					return;
+				}
+			}
+		}
+
+		// See jQuery.data for more information
+		if ( !pvt ) {
+			delete cache[ id ].data;
+
+			// Don't destroy the parent cache unless the internal data object
+			// had been the only thing left in it
+			if ( !isEmptyDataObject( cache[ id ] ) ) {
+				return;
+			}
+		}
+
+		// Destroy the cache
+		if ( isNode ) {
+			jQuery.cleanData( [ elem ], true );
+
+		// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
+		} else if ( jQuery.support.deleteExpando || cache != cache.window ) {
+			delete cache[ id ];
+
+		// When all else fails, null
+		} else {
+			cache[ id ] = null;
+		}
+	},
+
+	// For internal use only.
+	_data: function( elem, name, data ) {
+		return jQuery.data( elem, name, data, true );
+	},
+
+	// A method for determining if a DOM node can handle the data expando
+	acceptData: function( elem ) {
+		var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
+
+		// nodes accept data unless otherwise specified; rejection can be conditional
+		return !noData || noData !== true && elem.getAttribute("classid") === noData;
+	}
+});
+
+jQuery.fn.extend({
+	data: function( key, value ) {
+		var parts, part, attr, name, l,
+			elem = this[0],
+			i = 0,
+			data = null;
+
+		// Gets all values
+		if ( key === undefined ) {
+			if ( this.length ) {
+				data = jQuery.data( elem );
+
+				if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
+					attr = elem.attributes;
+					for ( l = attr.length; i < l; i++ ) {
+						name = attr[i].name;
+
+						if ( !name.indexOf( "data-" ) ) {
+							name = jQuery.camelCase( name.substring(5) );
+
+							dataAttr( elem, name, data[ name ] );
+						}
+					}
+					jQuery._data( elem, "parsedAttrs", true );
+				}
+			}
+
+			return data;
+		}
+
+		// Sets multiple values
+		if ( typeof key === "object" ) {
+			return this.each(function() {
+				jQuery.data( this, key );
+			});
+		}
+
+		parts = key.split( ".", 2 );
+		parts[1] = parts[1] ? "." + parts[1] : "";
+		part = parts[1] + "!";
+
+		return jQuery.access( this, function( value ) {
+
+			if ( value === undefined ) {
+				data = this.triggerHandler( "getData" + part, [ parts[0] ] );
+
+				// Try to fetch any internally stored data first
+				if ( data === undefined && elem ) {
+					data = jQuery.data( elem, key );
+					data = dataAttr( elem, key, data );
+				}
+
+				return data === undefined && parts[1] ?
+					this.data( parts[0] ) :
+					data;
+			}
+
+			parts[1] = value;
+			this.each(function() {
+				var self = jQuery( this );
+
+				self.triggerHandler( "setData" + part, parts );
+				jQuery.data( this, key, value );
+				self.triggerHandler( "changeData" + part, parts );
+			});
+		}, null, value, arguments.length > 1, null, false );
+	},
+
+	removeData: function( key ) {
+		return this.each(function() {
+			jQuery.removeData( this, key );
+		});
+	}
+});
+
+function dataAttr( elem, key, data ) {
+	// If nothing was found internally, try to fetch any
+	// data from the HTML5 data-* attribute
+	if ( data === undefined && elem.nodeType === 1 ) {
+
+		var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
+
+		data = elem.getAttribute( name );
+
+		if ( typeof data === "string" ) {
+			try {
+				data = data === "true" ? true :
+				data === "false" ? false :
+				data === "null" ? null :
+				// Only convert to a number if it doesn't change the string
+				+data + "" === data ? +data :
+				rbrace.test( data ) ? jQuery.parseJSON( data ) :
+					data;
+			} catch( e ) {}
+
+			// Make sure we set the data so it isn't changed later
+			jQuery.data( elem, key, data );
+
+		} else {
+			data = undefined;
+		}
+	}
+
+	return data;
+}
+
+// checks a cache object for emptiness
+function isEmptyDataObject( obj ) {
+	var name;
+	for ( name in obj ) {
+
+		// if the public data object is empty, the private is still empty
+		if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
+			continue;
+		}
+		if ( name !== "toJSON" ) {
+			return false;
+		}
+	}
+
+	return true;
+}
+jQuery.extend({
+	queue: function( elem, type, data ) {
+		var queue;
+
+		if ( elem ) {
+			type = ( type || "fx" ) + "queue";
+			queue = jQuery._data( elem, type );
+
+			// Speed up dequeue by getting out quickly if this is just a lookup
+			if ( data ) {
+				if ( !queue || jQuery.isArray(data) ) {
+					queue = jQuery._data( elem, type, jQuery.makeArray(data) );
+				} else {
+					queue.push( data );
+				}
+			}
+			return queue || [];
+		}
+	},
+
+	dequeue: function( elem, type ) {
+		type = type || "fx";
+
+		var queue = jQuery.queue( elem, type ),
+			startLength = queue.length,
+			fn = queue.shift(),
+			hooks = jQuery._queueHooks( elem, type ),
+			next = function() {
+				jQuery.dequeue( elem, type );
+			};
+
+		// If the fx queue is dequeued, always remove the progress sentinel
+		if ( fn === "inprogress" ) {
+			fn = queue.shift();
+			startLength--;
+		}
+
+		if ( fn ) {
+
+			// Add a progress sentinel to prevent the fx queue from being
+			// automatically dequeued
+			if ( type === "fx" ) {
+				queue.unshift( "inprogress" );
+			}
+
+			// clear up the last queue stop function
+			delete hooks.stop;
+			fn.call( elem, next, hooks );
+		}
+
+		if ( !startLength && hooks ) {
+			hooks.empty.fire();
+		}
+	},
+
+	// not intended for public consumption - generates a queueHooks object, or returns the current one
+	_queueHooks: function( elem, type ) {
+		var key = type + "queueHooks";
+		return jQuery._data( elem, key ) || jQuery._data( elem, key, {
+			empty: jQuery.Callbacks("once memory").add(function() {
+				jQuery.removeData( elem, type + "queue", true );
+				jQuery.removeData( elem, key, true );
+			})
+		});
+	}
+});
+
+jQuery.fn.extend({
+	queue: function( type, data ) {
+		var setter = 2;
+
+		if ( typeof type !== "string" ) {
+			data = type;
+			type = "fx";
+			setter--;
+		}
+
+		if ( arguments.length < setter ) {
+			return jQuery.queue( this[0], type );
+		}
+
+		return data === undefined ?
+			this :
+			this.each(function() {
+				var queue = jQuery.queue( this, type, data );
+
+				// ensure a hooks for this queue
+				jQuery._queueHooks( this, type );
+
+				if ( type === "fx" && queue[0] !== "inprogress" ) {
+					jQuery.dequeue( this, type );
+				}
+			});
+	},
+	dequeue: function( type ) {
+		return this.each(function() {
+			jQuery.dequeue( this, type );
+		});
+	},
+	// Based off of the plugin by Clint Helfers, with permission.
+	// http://blindsignals.com/index.php/2009/07/jquery-delay/
+	delay: function( time, type ) {
+		time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
+		type = type || "fx";
+
+		return this.queue( type, function( next, hooks ) {
+			var timeout = setTimeout( next, time );
+			hooks.stop = function() {
+				clearTimeout( timeout );
+			};
+		});
+	},
+	clearQueue: function( type ) {
+		return this.queue( type || "fx", [] );
+	},
+	// Get a promise resolved when queues of a certain type
+	// are emptied (fx is the type by default)
+	promise: function( type, obj ) {
+		var tmp,
+			count = 1,
+			defer = jQuery.Deferred(),
+			elements = this,
+			i = this.length,
+			resolve = function() {
+				if ( !( --count ) ) {
+					defer.resolveWith( elements, [ elements ] );
+				}
+			};
+
+		if ( typeof type !== "string" ) {
+			obj = type;
+			type = undefined;
+		}
+		type = type || "fx";
+
+		while( i-- ) {
+			tmp = jQuery._data( elements[ i ], type + "queueHooks" );
+			if ( tmp && tmp.empty ) {
+				count++;
+				tmp.empty.add( resolve );
+			}
+		}
+		resolve();
+		return defer.promise( obj );
+	}
+});
+var nodeHook, boolHook, fixSpecified,
+	rclass = /[\t\r\n]/g,
+	rreturn = /\r/g,
+	rtype = /^(?:button|input)$/i,
+	rfocusable = /^(?:button|input|object|select|textarea)$/i,
+	rclickable = /^a(?:rea|)$/i,
+	rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
+	getSetAttribute = jQuery.support.getSetAttribute;
+
+jQuery.fn.extend({
+	attr: function( name, value ) {
+		return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
+	},
+
+	removeAttr: function( name ) {
+		return this.each(function() {
+			jQuery.removeAttr( this, name );
+		});
+	},
+
+	prop: function( name, value ) {
+		return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
+	},
+
+	removeProp: function( name ) {
+		name = jQuery.propFix[ name ] || name;
+		return this.each(function() {
+			// try/catch handles cases where IE balks (such as removing a property on window)
+			try {
+				this[ name ] = undefined;
+				delete this[ name ];
+			} catch( e ) {}
+		});
+	},
+
+	addClass: function( value ) {
+		var classNames, i, l, elem,
+			setClass, c, cl;
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function( j ) {
+				jQuery( this ).addClass( value.call(this, j, this.className) );
+			});
+		}
+
+		if ( value && typeof value === "string" ) {
+			classNames = value.split( core_rspace );
+
+			for ( i = 0, l = this.length; i < l; i++ ) {
+				elem = this[ i ];
+
+				if ( elem.nodeType === 1 ) {
+					if ( !elem.className && classNames.length === 1 ) {
+						elem.className = value;
+
+					} else {
+						setClass = " " + elem.className + " ";
+
+						for ( c = 0, cl = classNames.length; c < cl; c++ ) {
+							if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) {
+								setClass += classNames[ c ] + " ";
+							}
+						}
+						elem.className = jQuery.trim( setClass );
+					}
+				}
+			}
+		}
+
+		return this;
+	},
+
+	removeClass: function( value ) {
+		var removes, className, elem, c, cl, i, l;
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function( j ) {
+				jQuery( this ).removeClass( value.call(this, j, this.className) );
+			});
+		}
+		if ( (value && typeof value === "string") || value === undefined ) {
+			removes = ( value || "" ).split( core_rspace );
+
+			for ( i = 0, l = this.length; i < l; i++ ) {
+				elem = this[ i ];
+				if ( elem.nodeType === 1 && elem.className ) {
+
+					className = (" " + elem.className + " ").replace( rclass, " " );
+
+					// loop over each item in the removal list
+					for ( c = 0, cl = removes.length; c < cl; c++ ) {
+						// Remove until there is nothing to remove,
+						while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) {
+							className = className.replace( " " + removes[ c ] + " " , " " );
+						}
+					}
+					elem.className = value ? jQuery.trim( className ) : "";
+				}
+			}
+		}
+
+		return this;
+	},
+
+	toggleClass: function( value, stateVal ) {
+		var type = typeof value,
+			isBool = typeof stateVal === "boolean";
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function( i ) {
+				jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
+			});
+		}
+
+		return this.each(function() {
+			if ( type === "string" ) {
+				// toggle individual class names
+				var className,
+					i = 0,
+					self = jQuery( this ),
+					state = stateVal,
+					classNames = value.split( core_rspace );
+
+				while ( (className = classNames[ i++ ]) ) {
+					// check each className given, space separated list
+					state = isBool ? state : !self.hasClass( className );
+					self[ state ? "addClass" : "removeClass" ]( className );
+				}
+
+			} else if ( type === "undefined" || type === "boolean" ) {
+				if ( this.className ) {
+					// store className if set
+					jQuery._data( this, "__className__", this.className );
+				}
+
+				// toggle whole className
+				this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
+			}
+		});
+	},
+
+	hasClass: function( selector ) {
+		var className = " " + selector + " ",
+			i = 0,
+			l = this.length;
+		for ( ; i < l; i++ ) {
+			if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
+				return true;
+			}
+		}
+
+		return false;
+	},
+
+	val: function( value ) {
+		var hooks, ret, isFunction,
+			elem = this[0];
+
+		if ( !arguments.length ) {
+			if ( elem ) {
+				hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
+
+				if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
+					return ret;
+				}
+
+				ret = elem.value;
+
+				return typeof ret === "string" ?
+					// handle most common string cases
+					ret.replace(rreturn, "") :
+					// handle cases where value is null/undef or number
+					ret == null ? "" : ret;
+			}
+
+			return;
+		}
+
+		isFunction = jQuery.isFunction( value );
+
+		return this.each(function( i ) {
+			var val,
+				self = jQuery(this);
+
+			if ( this.nodeType !== 1 ) {
+				return;
+			}
+
+			if ( isFunction ) {
+				val = value.call( this, i, self.val() );
+			} else {
+				val = value;
+			}
+
+			// Treat null/undefined as ""; convert numbers to string
+			if ( val == null ) {
+				val = "";
+			} else if ( typeof val === "number" ) {
+				val += "";
+			} else if ( jQuery.isArray( val ) ) {
+				val = jQuery.map(val, function ( value ) {
+					return value == null ? "" : value + "";
+				});
+			}
+
+			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
+
+			// If set returns undefined, fall back to normal setting
+			if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
+				this.value = val;
+			}
+		});
+	}
+});
+
+jQuery.extend({
+	valHooks: {
+		option: {
+			get: function( elem ) {
+				// attributes.value is undefined in Blackberry 4.7 but
+				// uses .value. See #6932
+				var val = elem.attributes.value;
+				return !val || val.specified ? elem.value : elem.text;
+			}
+		},
+		select: {
+			get: function( elem ) {
+				var value, option,
+					options = elem.options,
+					index = elem.selectedIndex,
+					one = elem.type === "select-one" || index < 0,
+					values = one ? null : [],
+					max = one ? index + 1 : options.length,
+					i = index < 0 ?
+						max :
+						one ? index : 0;
+
+				// Loop through all the selected options
+				for ( ; i < max; i++ ) {
+					option = options[ i ];
+
+					// oldIE doesn't update selected after form reset (#2551)
+					if ( ( option.selected || i === index ) &&
+							// Don't return options that are disabled or in a disabled optgroup
+							( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
+							( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
+
+						// Get the specific value for the option
+						value = jQuery( option ).val();
+
+						// We don't need an array for one selects
+						if ( one ) {
+							return value;
+						}
+
+						// Multi-Selects return an array
+						values.push( value );
+					}
+				}
+
+				return values;
+			},
+
+			set: function( elem, value ) {
+				var values = jQuery.makeArray( value );
+
+				jQuery(elem).find("option").each(function() {
+					this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+				});
+
+				if ( !values.length ) {
+					elem.selectedIndex = -1;
+				}
+				return values;
+			}
+		}
+	},
+
+	// Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9
+	attrFn: {},
+
+	attr: function( elem, name, value, pass ) {
+		var ret, hooks, notxml,
+			nType = elem.nodeType;
+
+		// don't get/set attributes on text, comment and attribute nodes
+		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+			return;
+		}
+
+		if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) {
+			return jQuery( elem )[ name ]( value );
+		}
+
+		// Fallback to prop when attributes are not supported
+		if ( typeof elem.getAttribute === "undefined" ) {
+			return jQuery.prop( elem, name, value );
+		}
+
+		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+		// All attributes are lowercase
+		// Grab necessary hook if one is defined
+		if ( notxml ) {
+			name = name.toLowerCase();
+			hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
+		}
+
+		if ( value !== undefined ) {
+
+			if ( value === null ) {
+				jQuery.removeAttr( elem, name );
+				return;
+
+			} else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
+				return ret;
+
+			} else {
+				elem.setAttribute( name, value + "" );
+				return value;
+			}
+
+		} else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
+			return ret;
+
+		} else {
+
+			ret = elem.getAttribute( name );
+
+			// Non-existent attributes return null, we normalize to undefined
+			return ret === null ?
+				undefined :
+				ret;
+		}
+	},
+
+	removeAttr: function( elem, value ) {
+		var propName, attrNames, name, isBool,
+			i = 0;
+
+		if ( value && elem.nodeType === 1 ) {
+
+			attrNames = value.split( core_rspace );
+
+			for ( ; i < attrNames.length; i++ ) {
+				name = attrNames[ i ];
+
+				if ( name ) {
+					propName = jQuery.propFix[ name ] || name;
+					isBool = rboolean.test( name );
+
+					// See #9699 for explanation of this approach (setting first, then removal)
+					// Do not do this for boolean attributes (see #10870)
+					if ( !isBool ) {
+						jQuery.attr( elem, name, "" );
+					}
+					elem.removeAttribute( getSetAttribute ? name : propName );
+
+					// Set corresponding property to false for boolean attributes
+					if ( isBool && propName in elem ) {
+						elem[ propName ] = false;
+					}
+				}
+			}
+		}
+	},
+
+	attrHooks: {
+		type: {
+			set: function( elem, value ) {
+				// We can't allow the type property to be changed (since it causes problems in IE)
+				if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
+					jQuery.error( "type property can't be changed" );
+				} else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
+					// Setting the type on a radio button after the value resets the value in IE6-9
+					// Reset value to it's default in case type is set after value
+					// This is for element creation
+					var val = elem.value;
+					elem.setAttribute( "type", value );
+					if ( val ) {
+						elem.value = val;
+					}
+					return value;
+				}
+			}
+		},
+		// Use the value property for back compat
+		// Use the nodeHook for button elements in IE6/7 (#1954)
+		value: {
+			get: function( elem, name ) {
+				if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
+					return nodeHook.get( elem, name );
+				}
+				return name in elem ?
+					elem.value :
+					null;
+			},
+			set: function( elem, value, name ) {
+				if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
+					return nodeHook.set( elem, value, name );
+				}
+				// Does not return so that setAttribute is also used
+				elem.value = value;
+			}
+		}
+	},
+
+	propFix: {
+		tabindex: "tabIndex",
+		readonly: "readOnly",
+		"for": "htmlFor",
+		"class": "className",
+		maxlength: "maxLength",
+		cellspacing: "cellSpacing",
+		cellpadding: "cellPadding",
+		rowspan: "rowSpan",
+		colspan: "colSpan",
+		usemap: "useMap",
+		frameborder: "frameBorder",
+		contenteditable: "contentEditable"
+	},
+
+	prop: function( elem, name, value ) {
+		var ret, hooks, notxml,
+			nType = elem.nodeType;
+
+		// don't get/set properties on text, comment and attribute nodes
+		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+			return;
+		}
+
+		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+		if ( notxml ) {
+			// Fix name and attach hooks
+			name = jQuery.propFix[ name ] || name;
+			hooks = jQuery.propHooks[ name ];
+		}
+
+		if ( value !== undefined ) {
+			if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+				return ret;
+
+			} else {
+				return ( elem[ name ] = value );
+			}
+
+		} else {
+			if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
+				return ret;
+
+			} else {
+				return elem[ name ];
+			}
+		}
+	},
+
+	propHooks: {
+		tabIndex: {
+			get: function( elem ) {
+				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+				var attributeNode = elem.getAttributeNode("tabindex");
+
+				return attributeNode && attributeNode.specified ?
+					parseInt( attributeNode.value, 10 ) :
+					rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+						0 :
+						undefined;
+			}
+		}
+	}
+});
+
+// Hook for boolean attributes
+boolHook = {
+	get: function( elem, name ) {
+		// Align boolean attributes with corresponding properties
+		// Fall back to attribute presence where some booleans are not supported
+		var attrNode,
+			property = jQuery.prop( elem, name );
+		return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
+			name.toLowerCase() :
+			undefined;
+	},
+	set: function( elem, value, name ) {
+		var propName;
+		if ( value === false ) {
+			// Remove boolean attributes when set to false
+			jQuery.removeAttr( elem, name );
+		} else {
+			// value is true since we know at this point it's type boolean and not false
+			// Set boolean attributes to the same name and set the DOM property
+			propName = jQuery.propFix[ name ] || name;
+			if ( propName in elem ) {
+				// Only set the IDL specifically if it already exists on the element
+				elem[ propName ] = true;
+			}
+
+			elem.setAttribute( name, name.toLowerCase() );
+		}
+		return name;
+	}
+};
+
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
+if ( !getSetAttribute ) {
+
+	fixSpecified = {
+		name: true,
+		id: true,
+		coords: true
+	};
+
+	// Use this for any attribute in IE6/7
+	// This fixes almost every IE6/7 issue
+	nodeHook = jQuery.valHooks.button = {
+		get: function( elem, name ) {
+			var ret;
+			ret = elem.getAttributeNode( name );
+			return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ?
+				ret.value :
+				undefined;
+		},
+		set: function( elem, value, name ) {
+			// Set the existing or create a new attribute node
+			var ret = elem.getAttributeNode( name );
+			if ( !ret ) {
+				ret = document.createAttribute( name );
+				elem.setAttributeNode( ret );
+			}
+			return ( ret.value = value + "" );
+		}
+	};
+
+	// Set width and height to auto instead of 0 on empty string( Bug #8150 )
+	// This is for removals
+	jQuery.each([ "width", "height" ], function( i, name ) {
+		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+			set: function( elem, value ) {
+				if ( value === "" ) {
+					elem.setAttribute( name, "auto" );
+					return value;
+				}
+			}
+		});
+	});
+
+	// Set contenteditable to false on removals(#10429)
+	// Setting to empty string throws an error as an invalid value
+	jQuery.attrHooks.contenteditable = {
+		get: nodeHook.get,
+		set: function( elem, value, name ) {
+			if ( value === "" ) {
+				value = "false";
+			}
+			nodeHook.set( elem, value, name );
+		}
+	};
+}
+
+
+// Some attributes require a special call on IE
+if ( !jQuery.support.hrefNormalized ) {
+	jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
+		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+			get: function( elem ) {
+				var ret = elem.getAttribute( name, 2 );
+				return ret === null ? undefined : ret;
+			}
+		});
+	});
+}
+
+if ( !jQuery.support.style ) {
+	jQuery.attrHooks.style = {
+		get: function( elem ) {
+			// Return undefined in the case of empty string
+			// Normalize to lowercase since IE uppercases css property names
+			return elem.style.cssText.toLowerCase() || undefined;
+		},
+		set: function( elem, value ) {
+			return ( elem.style.cssText = value + "" );
+		}
+	};
+}
+
+// Safari mis-reports the default selected property of an option
+// Accessing the parent's selectedIndex property fixes it
+if ( !jQuery.support.optSelected ) {
+	jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
+		get: function( elem ) {
+			var parent = elem.parentNode;
+
+			if ( parent ) {
+				parent.selectedIndex;
+
+				// Make sure that it also works with optgroups, see #5701
+				if ( parent.parentNode ) {
+					parent.parentNode.selectedIndex;
+				}
+			}
+			return null;
+		}
+	});
+}
+
+// IE6/7 call enctype encoding
+if ( !jQuery.support.enctype ) {
+	jQuery.propFix.enctype = "encoding";
+}
+
+// Radios and checkboxes getter/setter
+if ( !jQuery.support.checkOn ) {
+	jQuery.each([ "radio", "checkbox" ], function() {
+		jQuery.valHooks[ this ] = {
+			get: function( elem ) {
+				// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+				return elem.getAttribute("value") === null ? "on" : elem.value;
+			}
+		};
+	});
+}
+jQuery.each([ "radio", "checkbox" ], function() {
+	jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
+		set: function( elem, value ) {
+			if ( jQuery.isArray( value ) ) {
+				return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
+			}
+		}
+	});
+});
+var rformElems = /^(?:textarea|input|select)$/i,
+	rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/,
+	rhoverHack = /(?:^|\s)hover(\.\S+|)\b/,
+	rkeyEvent = /^key/,
+	rmouseEvent = /^(?:mouse|contextmenu)|click/,
+	rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
+	hoverHack = function( events ) {
+		return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
+	};
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
+
+	add: function( elem, types, handler, data, selector ) {
+
+		var elemData, eventHandle, events,
+			t, tns, type, namespaces, handleObj,
+			handleObjIn, handlers, special;
+
+		// Don't attach events to noData or text/comment nodes (allow plain objects tho)
+		if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {
+			return;
+		}
+
+		// Caller can pass in an object of custom data in lieu of the handler
+		if ( handler.handler ) {
+			handleObjIn = handler;
+			handler = handleObjIn.handler;
+			selector = handleObjIn.selector;
+		}
+
+		// Make sure that the handler has a unique ID, used to find/remove it later
+		if ( !handler.guid ) {
+			handler.guid = jQuery.guid++;
+		}
+
+		// Init the element's event structure and main handler, if this is the first
+		events = elemData.events;
+		if ( !events ) {
+			elemData.events = events = {};
+		}
+		eventHandle = elemData.handle;
+		if ( !eventHandle ) {
+			elemData.handle = eventHandle = function( e ) {
+				// Discard the second event of a jQuery.event.trigger() and
+				// when an event is called after a page has unloaded
+				return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
+					jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
+					undefined;
+			};
+			// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
+			eventHandle.elem = elem;
+		}
+
+		// Handle multiple events separated by a space
+		// jQuery(...).bind("mouseover mouseout", fn);
+		types = jQuery.trim( hoverHack(types) ).split( " " );
+		for ( t = 0; t < types.length; t++ ) {
+
+			tns = rtypenamespace.exec( types[t] ) || [];
+			type = tns[1];
+			namespaces = ( tns[2] || "" ).split( "." ).sort();
+
+			// If event changes its type, use the special event handlers for the changed type
+			special = jQuery.event.special[ type ] || {};
+
+			// If selector defined, determine special event api type, otherwise given type
+			type = ( selector ? special.delegateType : special.bindType ) || type;
+
+			// Update special based on newly reset type
+			special = jQuery.event.special[ type ] || {};
+
+			// handleObj is passed to all event handlers
+			handleObj = jQuery.extend({
+				type: type,
+				origType: tns[1],
+				data: data,
+				handler: handler,
+				guid: handler.guid,
+				selector: selector,
+				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
+				namespace: namespaces.join(".")
+			}, handleObjIn );
+
+			// Init the event handler queue if we're the first
+			handlers = events[ type ];
+			if ( !handlers ) {
+				handlers = events[ type ] = [];
+				handlers.delegateCount = 0;
+
+				// Only use addEventListener/attachEvent if the special events handler returns false
+				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+					// Bind the global event handler to the element
+					if ( elem.addEventListener ) {
+						elem.addEventListener( type, eventHandle, false );
+
+					} else if ( elem.attachEvent ) {
+						elem.attachEvent( "on" + type, eventHandle );
+					}
+				}
+			}
+
+			if ( special.add ) {
+				special.add.call( elem, handleObj );
+
+				if ( !handleObj.handler.guid ) {
+					handleObj.handler.guid = handler.guid;
+				}
+			}
+
+			// Add to the element's handler list, delegates in front
+			if ( selector ) {
+				handlers.splice( handlers.delegateCount++, 0, handleObj );
+			} else {
+				handlers.push( handleObj );
+			}
+
+			// Keep track of which events have ever been used, for event optimization
+			jQuery.event.global[ type ] = true;
+		}
+
+		// Nullify elem to prevent memory leaks in IE
+		elem = null;
+	},
+
+	global: {},
+
+	// Detach an event or set of events from an element
+	remove: function( elem, types, handler, selector, mappedTypes ) {
+
+		var t, tns, type, origType, namespaces, origCount,
+			j, events, special, eventType, handleObj,
+			elemData = jQuery.hasData( elem ) && jQuery._data( elem );
+
+		if ( !elemData || !(events = elemData.events) ) {
+			return;
+		}
+
+		// Once for each type.namespace in types; type may be omitted
+		types = jQuery.trim( hoverHack( types || "" ) ).split(" ");
+		for ( t = 0; t < types.length; t++ ) {
+			tns = rtypenamespace.exec( types[t] ) || [];
+			type = origType = tns[1];
+			namespaces = tns[2];
+
+			// Unbind all events (on this namespace, if provided) for the element
+			if ( !type ) {
+				for ( type in events ) {
+					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
+				}
+				continue;
+			}
+
+			special = jQuery.event.special[ type ] || {};
+			type = ( selector? special.delegateType : special.bindType ) || type;
+			eventType = events[ type ] || [];
+			origCount = eventType.length;
+			namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null;
+
+			// Remove matching events
+			for ( j = 0; j < eventType.length; j++ ) {
+				handleObj = eventType[ j ];
+
+				if ( ( mappedTypes || origType === handleObj.origType ) &&
+					 ( !handler || handler.guid === handleObj.guid ) &&
+					 ( !namespaces || namespaces.test( handleObj.namespace ) ) &&
+					 ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
+					eventType.splice( j--, 1 );
+
+					if ( handleObj.selector ) {
+						eventType.delegateCount--;
+					}
+					if ( special.remove ) {
+						special.remove.call( elem, handleObj );
+					}
+				}
+			}
+
+			// Remove generic event handler if we removed something and no more handlers exist
+			// (avoids potential for endless recursion during removal of special event handlers)
+			if ( eventType.length === 0 && origCount !== eventType.length ) {
+				if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+					jQuery.removeEvent( elem, type, elemData.handle );
+				}
+
+				delete events[ type ];
+			}
+		}
+
+		// Remove the expando if it's no longer used
+		if ( jQuery.isEmptyObject( events ) ) {
+			delete elemData.handle;
+
+			// removeData also checks for emptiness and clears the expando if empty
+			// so use it instead of delete
+			jQuery.removeData( elem, "events", true );
+		}
+	},
+
+	// Events that are safe to short-circuit if no handlers are attached.
+	// Native DOM events should not be added, they may have inline handlers.
+	customEvent: {
+		"getData": true,
+		"setData": true,
+		"changeData": true
+	},
+
+	trigger: function( event, data, elem, onlyHandlers ) {
+		// Don't do events on text and comment nodes
+		if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {
+			return;
+		}
+
+		// Event object or event type
+		var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType,
+			type = event.type || event,
+			namespaces = [];
+
+		// focus/blur morphs to focusin/out; ensure we're not firing them right now
+		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
+			return;
+		}
+
+		if ( type.indexOf( "!" ) >= 0 ) {
+			// Exclusive events trigger only for the exact event (no namespaces)
+			type = type.slice(0, -1);
+			exclusive = true;
+		}
+
+		if ( type.indexOf( "." ) >= 0 ) {
+			// Namespaced trigger; create a regexp to match event type in handle()
+			namespaces = type.split(".");
+			type = namespaces.shift();
+			namespaces.sort();
+		}
+
+		if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
+			// No jQuery handlers for this event type, and it can't have inline handlers
+			return;
+		}
+
+		// Caller can pass in an Event, Object, or just an event type string
+		event = typeof event === "object" ?
+			// jQuery.Event object
+			event[ jQuery.expando ] ? event :
+			// Object literal
+			new jQuery.Event( type, event ) :
+			// Just the event type (string)
+			new jQuery.Event( type );
+
+		event.type = type;
+		event.isTrigger = true;
+		event.exclusive = exclusive;
+		event.namespace = namespaces.join( "." );
+		event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null;
+		ontype = type.indexOf( ":" ) < 0 ? "on" + type : "";
+
+		// Handle a global trigger
+		if ( !elem ) {
+
+			// TODO: Stop taunting the data cache; remove global events and always attach to document
+			cache = jQuery.cache;
+			for ( i in cache ) {
+				if ( cache[ i ].events && cache[ i ].events[ type ] ) {
+					jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );
+				}
+			}
+			return;
+		}
+
+		// Clean up the event in case it is being reused
+		event.result = undefined;
+		if ( !event.target ) {
+			event.target = elem;
+		}
+
+		// Clone any incoming data and prepend the event, creating the handler arg list
+		data = data != null ? jQuery.makeArray( data ) : [];
+		data.unshift( event );
+
+		// Allow special events to draw outside the lines
+		special = jQuery.event.special[ type ] || {};
+		if ( special.trigger && special.trigger.apply( elem, data ) === false ) {
+			return;
+		}
+
+		// Determine event propagation path in advance, per W3C events spec (#9951)
+		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
+		eventPath = [[ elem, special.bindType || type ]];
+		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
+
+			bubbleType = special.delegateType || type;
+			cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;
+			for ( old = elem; cur; cur = cur.parentNode ) {
+				eventPath.push([ cur, bubbleType ]);
+				old = cur;
+			}
+
+			// Only add window if we got to document (e.g., not plain obj or detached DOM)
+			if ( old === (elem.ownerDocument || document) ) {
+				eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);
+			}
+		}
+
+		// Fire handlers on the event path
+		for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {
+
+			cur = eventPath[i][0];
+			event.type = eventPath[i][1];
+
+			handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
+			if ( handle ) {
+				handle.apply( cur, data );
+			}
+			// Note that this is a bare JS function and not a jQuery handler
+			handle = ontype && cur[ ontype ];
+			if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
+				event.preventDefault();
+			}
+		}
+		event.type = type;
+
+		// If nobody prevented the default action, do it now
+		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
+
+			if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&
+				!(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
+
+				// Call a native DOM method on the target with the same name name as the event.
+				// Can't use an .isFunction() check here because IE6/7 fails that test.
+				// Don't do default actions on window, that's where global variables be (#6170)
+				// IE<9 dies on focus/blur to hidden element (#1486)
+				if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {
+
+					// Don't re-trigger an onFOO event when we call its FOO() method
+					old = elem[ ontype ];
+
+					if ( old ) {
+						elem[ ontype ] = null;
+					}
+
+					// Prevent re-triggering of the same event, since we already bubbled it above
+					jQuery.event.triggered = type;
+					elem[ type ]();
+					jQuery.event.triggered = undefined;
+
+					if ( old ) {
+						elem[ ontype ] = old;
+					}
+				}
+			}
+		}
+
+		return event.result;
+	},
+
+	dispatch: function( event ) {
+
+		// Make a writable jQuery.Event from the native event object
+		event = jQuery.event.fix( event || window.event );
+
+		var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related,
+			handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),
+			delegateCount = handlers.delegateCount,
+			args = core_slice.call( arguments ),
+			run_all = !event.exclusive && !event.namespace,
+			special = jQuery.event.special[ event.type ] || {},
+			handlerQueue = [];
+
+		// Use the fix-ed jQuery.Event rather than the (read-only) native event
+		args[0] = event;
+		event.delegateTarget = this;
+
+		// Call the preDispatch hook for the mapped type, and let it bail if desired
+		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
+			return;
+		}
+
+		// Determine handlers that should run if there are delegated events
+		// Avoid non-left-click bubbling in Firefox (#3861)
+		if ( delegateCount && !(event.button && event.type === "click") ) {
+
+			for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {
+
+				// Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764)
+				if ( cur.disabled !== true || event.type !== "click" ) {
+					selMatch = {};
+					matches = [];
+					for ( i = 0; i < delegateCount; i++ ) {
+						handleObj = handlers[ i ];
+						sel = handleObj.selector;
+
+						if ( selMatch[ sel ] === undefined ) {
+							selMatch[ sel ] = handleObj.needsContext ?
+								jQuery( sel, this ).index( cur ) >= 0 :
+								jQuery.find( sel, this, null, [ cur ] ).length;
+						}
+						if ( selMatch[ sel ] ) {
+							matches.push( handleObj );
+						}
+					}
+					if ( matches.length ) {
+						handlerQueue.push({ elem: cur, matches: matches });
+					}
+				}
+			}
+		}
+
+		// Add the remaining (directly-bound) handlers
+		if ( handlers.length > delegateCount ) {
+			handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });
+		}
+
+		// Run delegates first; they may want to stop propagation beneath us
+		for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {
+			matched = handlerQueue[ i ];
+			event.currentTarget = matched.elem;
+
+			for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {
+				handleObj = matched.matches[ j ];
+
+				// Triggered event must either 1) be non-exclusive and have no namespace, or
+				// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
+				if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {
+
+					event.data = handleObj.data;
+					event.handleObj = handleObj;
+
+					ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
+							.apply( matched.elem, args );
+
+					if ( ret !== undefined ) {
+						event.result = ret;
+						if ( ret === false ) {
+							event.preventDefault();
+							event.stopPropagation();
+						}
+					}
+				}
+			}
+		}
+
+		// Call the postDispatch hook for the mapped type
+		if ( special.postDispatch ) {
+			special.postDispatch.call( this, event );
+		}
+
+		return event.result;
+	},
+
+	// Includes some event props shared by KeyEvent and MouseEvent
+	// *** attrChange attrName relatedNode srcElement  are not normalized, non-W3C, deprecated, will be removed in 1.8 ***
+	props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
+
+	fixHooks: {},
+
+	keyHooks: {
+		props: "char charCode key keyCode".split(" "),
+		filter: function( event, original ) {
+
+			// Add which for key events
+			if ( event.which == null ) {
+				event.which = original.charCode != null ? original.charCode : original.keyCode;
+			}
+
+			return event;
+		}
+	},
+
+	mouseHooks: {
+		props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
+		filter: function( event, original ) {
+			var eventDoc, doc, body,
+				button = original.button,
+				fromElement = original.fromElement;
+
+			// Calculate pageX/Y if missing and clientX/Y available
+			if ( event.pageX == null && original.clientX != null ) {
+				eventDoc = event.target.ownerDocument || document;
+				doc = eventDoc.documentElement;
+				body = eventDoc.body;
+
+				event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
+				event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
+			}
+
+			// Add relatedTarget, if necessary
+			if ( !event.relatedTarget && fromElement ) {
+				event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
+			}
+
+			// Add which for click: 1 === left; 2 === middle; 3 === right
+			// Note: button is not normalized, so don't use it
+			if ( !event.which && button !== undefined ) {
+				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
+			}
+
+			return event;
+		}
+	},
+
+	fix: function( event ) {
+		if ( event[ jQuery.expando ] ) {
+			return event;
+		}
+
+		// Create a writable copy of the event object and normalize some properties
+		var i, prop,
+			originalEvent = event,
+			fixHook = jQuery.event.fixHooks[ event.type ] || {},
+			copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
+
+		event = jQuery.Event( originalEvent );
+
+		for ( i = copy.length; i; ) {
+			prop = copy[ --i ];
+			event[ prop ] = originalEvent[ prop ];
+		}
+
+		// Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)
+		if ( !event.target ) {
+			event.target = originalEvent.srcElement || document;
+		}
+
+		// Target should not be a text node (#504, Safari)
+		if ( event.target.nodeType === 3 ) {
+			event.target = event.target.parentNode;
+		}
+
+		// For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8)
+		event.metaKey = !!event.metaKey;
+
+		return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
+	},
+
+	special: {
+		load: {
+			// Prevent triggered image.load events from bubbling to window.load
+			noBubble: true
+		},
+
+		focus: {
+			delegateType: "focusin"
+		},
+		blur: {
+			delegateType: "focusout"
+		},
+
+		beforeunload: {
+			setup: function( data, namespaces, eventHandle ) {
+				// We only want to do this special case on windows
+				if ( jQuery.isWindow( this ) ) {
+					this.onbeforeunload = eventHandle;
+				}
+			},
+
+			teardown: function( namespaces, eventHandle ) {
+				if ( this.onbeforeunload === eventHandle ) {
+					this.onbeforeunload = null;
+				}
+			}
+		}
+	},
+
+	simulate: function( type, elem, event, bubble ) {
+		// Piggyback on a donor event to simulate a different one.
+		// Fake originalEvent to avoid donor's stopPropagation, but if the
+		// simulated event prevents default then we do the same on the donor.
+		var e = jQuery.extend(
+			new jQuery.Event(),
+			event,
+			{ type: type,
+				isSimulated: true,
+				originalEvent: {}
+			}
+		);
+		if ( bubble ) {
+			jQuery.event.trigger( e, null, elem );
+		} else {
+			jQuery.event.dispatch.call( elem, e );
+		}
+		if ( e.isDefaultPrevented() ) {
+			event.preventDefault();
+		}
+	}
+};
+
+// Some plugins are using, but it's undocumented/deprecated and will be removed.
+// The 1.7 special event interface should provide all the hooks needed now.
+jQuery.event.handle = jQuery.event.dispatch;
+
+jQuery.removeEvent = document.removeEventListener ?
+	function( elem, type, handle ) {
+		if ( elem.removeEventListener ) {
+			elem.removeEventListener( type, handle, false );
+		}
+	} :
+	function( elem, type, handle ) {
+		var name = "on" + type;
+
+		if ( elem.detachEvent ) {
+
+			// #8545, #7054, preventing memory leaks for custom events in IE6-8
+			// detachEvent needed property on element, by name of that event, to properly expose it to GC
+			if ( typeof elem[ name ] === "undefined" ) {
+				elem[ name ] = null;
+			}
+
+			elem.detachEvent( name, handle );
+		}
+	};
+
+jQuery.Event = function( src, props ) {
+	// Allow instantiation without the 'new' keyword
+	if ( !(this instanceof jQuery.Event) ) {
+		return new jQuery.Event( src, props );
+	}
+
+	// Event object
+	if ( src && src.type ) {
+		this.originalEvent = src;
+		this.type = src.type;
+
+		// Events bubbling up the document may have been marked as prevented
+		// by a handler lower down the tree; reflect the correct value.
+		this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
+			src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
+
+	// Event type
+	} else {
+		this.type = src;
+	}
+
+	// Put explicitly provided properties onto the event object
+	if ( props ) {
+		jQuery.extend( this, props );
+	}
+
+	// Create a timestamp if incoming event doesn't have one
+	this.timeStamp = src && src.timeStamp || jQuery.now();
+
+	// Mark it as fixed
+	this[ jQuery.expando ] = true;
+};
+
+function returnFalse() {
+	return false;
+}
+function returnTrue() {
+	return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+	preventDefault: function() {
+		this.isDefaultPrevented = returnTrue;
+
+		var e = this.originalEvent;
+		if ( !e ) {
+			return;
+		}
+
+		// if preventDefault exists run it on the original event
+		if ( e.preventDefault ) {
+			e.preventDefault();
+
+		// otherwise set the returnValue property of the original event to false (IE)
+		} else {
+			e.returnValue = false;
+		}
+	},
+	stopPropagation: function() {
+		this.isPropagationStopped = returnTrue;
+
+		var e = this.originalEvent;
+		if ( !e ) {
+			return;
+		}
+		// if stopPropagation exists run it on the original event
+		if ( e.stopPropagation ) {
+			e.stopPropagation();
+		}
+		// otherwise set the cancelBubble property of the original event to true (IE)
+		e.cancelBubble = true;
+	},
+	stopImmediatePropagation: function() {
+		this.isImmediatePropagationStopped = returnTrue;
+		this.stopPropagation();
+	},
+	isDefaultPrevented: returnFalse,
+	isPropagationStopped: returnFalse,
+	isImmediatePropagationStopped: returnFalse
+};
+
+// Create mouseenter/leave events using mouseover/out and event-time checks
+jQuery.each({
+	mouseenter: "mouseover",
+	mouseleave: "mouseout"
+}, function( orig, fix ) {
+	jQuery.event.special[ orig ] = {
+		delegateType: fix,
+		bindType: fix,
+
+		handle: function( event ) {
+			var ret,
+				target = this,
+				related = event.relatedTarget,
+				handleObj = event.handleObj,
+				selector = handleObj.selector;
+
+			// For mousenter/leave call the handler if related is outside the target.
+			// NB: No relatedTarget if the mouse left/entered the browser window
+			if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
+				event.type = handleObj.origType;
+				ret = handleObj.handler.apply( this, arguments );
+				event.type = fix;
+			}
+			return ret;
+		}
+	};
+});
+
+// IE submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+	jQuery.event.special.submit = {
+		setup: function() {
+			// Only need this for delegated form submit events
+			if ( jQuery.nodeName( this, "form" ) ) {
+				return false;
+			}
+
+			// Lazy-add a submit handler when a descendant form may potentially be submitted
+			jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
+				// Node name check avoids a VML-related crash in IE (#9807)
+				var elem = e.target,
+					form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
+				if ( form && !jQuery._data( form, "_submit_attached" ) ) {
+					jQuery.event.add( form, "submit._submit", function( event ) {
+						event._submit_bubble = true;
+					});
+					jQuery._data( form, "_submit_attached", true );
+				}
+			});
+			// return undefined since we don't need an event listener
+		},
+
+		postDispatch: function( event ) {
+			// If form was submitted by the user, bubble the event up the tree
+			if ( event._submit_bubble ) {
+				delete event._submit_bubble;
+				if ( this.parentNode && !event.isTrigger ) {
+					jQuery.event.simulate( "submit", this.parentNode, event, true );
+				}
+			}
+		},
+
+		teardown: function() {
+			// Only need this for delegated form submit events
+			if ( jQuery.nodeName( this, "form" ) ) {
+				return false;
+			}
+
+			// Remove delegated handlers; cleanData eventually reaps submit handlers attached above
+			jQuery.event.remove( this, "._submit" );
+		}
+	};
+}
+
+// IE change delegation and checkbox/radio fix
+if ( !jQuery.support.changeBubbles ) {
+
+	jQuery.event.special.change = {
+
+		setup: function() {
+
+			if ( rformElems.test( this.nodeName ) ) {
+				// IE doesn't fire change on a check/radio until blur; trigger it on click
+				// after a propertychange. Eat the blur-change in special.change.handle.
+				// This still fires onchange a second time for check/radio after blur.
+				if ( this.type === "checkbox" || this.type === "radio" ) {
+					jQuery.event.add( this, "propertychange._change", function( event ) {
+						if ( event.originalEvent.propertyName === "checked" ) {
+							this._just_changed = true;
+						}
+					});
+					jQuery.event.add( this, "click._change", function( event ) {
+						if ( this._just_changed && !event.isTrigger ) {
+							this._just_changed = false;
+						}
+						// Allow triggered, simulated change events (#11500)
+						jQuery.event.simulate( "change", this, event, true );
+					});
+				}
+				return false;
+			}
+			// Delegated event; lazy-add a change handler on descendant inputs
+			jQuery.event.add( this, "beforeactivate._change", function( e ) {
+				var elem = e.target;
+
+				if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) {
+					jQuery.event.add( elem, "change._change", function( event ) {
+						if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
+							jQuery.event.simulate( "change", this.parentNode, event, true );
+						}
+					});
+					jQuery._data( elem, "_change_attached", true );
+				}
+			});
+		},
+
+		handle: function( event ) {
+			var elem = event.target;
+
+			// Swallow native change events from checkbox/radio, we already triggered them above
+			if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
+				return event.handleObj.handler.apply( this, arguments );
+			}
+		},
+
+		teardown: function() {
+			jQuery.event.remove( this, "._change" );
+
+			return !rformElems.test( this.nodeName );
+		}
+	};
+}
+
+// Create "bubbling" focus and blur events
+if ( !jQuery.support.focusinBubbles ) {
+	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+		// Attach a single capturing handler while someone wants focusin/focusout
+		var attaches = 0,
+			handler = function( event ) {
+				jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
+			};
+
+		jQuery.event.special[ fix ] = {
+			setup: function() {
+				if ( attaches++ === 0 ) {
+					document.addEventListener( orig, handler, true );
+				}
+			},
+			teardown: function() {
+				if ( --attaches === 0 ) {
+					document.removeEventListener( orig, handler, true );
+				}
+			}
+		};
+	});
+}
+
+jQuery.fn.extend({
+
+	on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
+		var origFn, type;
+
+		// Types can be a map of types/handlers
+		if ( typeof types === "object" ) {
+			// ( types-Object, selector, data )
+			if ( typeof selector !== "string" ) { // && selector != null
+				// ( types-Object, data )
+				data = data || selector;
+				selector = undefined;
+			}
+			for ( type in types ) {
+				this.on( type, selector, data, types[ type ], one );
+			}
+			return this;
+		}
+
+		if ( data == null && fn == null ) {
+			// ( types, fn )
+			fn = selector;
+			data = selector = undefined;
+		} else if ( fn == null ) {
+			if ( typeof selector === "string" ) {
+				// ( types, selector, fn )
+				fn = data;
+				data = undefined;
+			} else {
+				// ( types, data, fn )
+				fn = data;
+				data = selector;
+				selector = undefined;
+			}
+		}
+		if ( fn === false ) {
+			fn = returnFalse;
+		} else if ( !fn ) {
+			return this;
+		}
+
+		if ( one === 1 ) {
+			origFn = fn;
+			fn = function( event ) {
+				// Can use an empty set, since event contains the info
+				jQuery().off( event );
+				return origFn.apply( this, arguments );
+			};
+			// Use same guid so caller can remove using origFn
+			fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+		}
+		return this.each( function() {
+			jQuery.event.add( this, types, fn, data, selector );
+		});
+	},
+	one: function( types, selector, data, fn ) {
+		return this.on( types, selector, data, fn, 1 );
+	},
+	off: function( types, selector, fn ) {
+		var handleObj, type;
+		if ( types && types.preventDefault && types.handleObj ) {
+			// ( event )  dispatched jQuery.Event
+			handleObj = types.handleObj;
+			jQuery( types.delegateTarget ).off(
+				handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
+				handleObj.selector,
+				handleObj.handler
+			);
+			return this;
+		}
+		if ( typeof types === "object" ) {
+			// ( types-object [, selector] )
+			for ( type in types ) {
+				this.off( type, selector, types[ type ] );
+			}
+			return this;
+		}
+		if ( selector === false || typeof selector === "function" ) {
+			// ( types [, fn] )
+			fn = selector;
+			selector = undefined;
+		}
+		if ( fn === false ) {
+			fn = returnFalse;
+		}
+		return this.each(function() {
+			jQuery.event.remove( this, types, fn, selector );
+		});
+	},
+
+	bind: function( types, data, fn ) {
+		return this.on( types, null, data, fn );
+	},
+	unbind: function( types, fn ) {
+		return this.off( types, null, fn );
+	},
+
+	live: function( types, data, fn ) {
+		jQuery( this.context ).on( types, this.selector, data, fn );
+		return this;
+	},
+	die: function( types, fn ) {
+		jQuery( this.context ).off( types, this.selector || "**", fn );
+		return this;
+	},
+
+	delegate: function( selector, types, data, fn ) {
+		return this.on( types, selector, data, fn );
+	},
+	undelegate: function( selector, types, fn ) {
+		// ( namespace ) or ( selector, types [, fn] )
+		return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
+	},
+
+	trigger: function( type, data ) {
+		return this.each(function() {
+			jQuery.event.trigger( type, data, this );
+		});
+	},
+	triggerHandler: function( type, data ) {
+		if ( this[0] ) {
+			return jQuery.event.trigger( type, data, this[0], true );
+		}
+	},
+
+	toggle: function( fn ) {
+		// Save reference to arguments for access in closure
+		var args = arguments,
+			guid = fn.guid || jQuery.guid++,
+			i = 0,
+			toggler = function( event ) {
+				// Figure out which function to execute
+				var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+				jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+				// Make sure that clicks stop
+				event.preventDefault();
+
+				// and execute the function
+				return args[ lastToggle ].apply( this, arguments ) || false;
+			};
+
+		// link all the functions, so any of them can unbind this click handler
+		toggler.guid = guid;
+		while ( i < args.length ) {
+			args[ i++ ].guid = guid;
+		}
+
+		return this.click( toggler );
+	},
+
+	hover: function( fnOver, fnOut ) {
+		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+	}
+});
+
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+	"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
+
+	// Handle event binding
+	jQuery.fn[ name ] = function( data, fn ) {
+		if ( fn == null ) {
+			fn = data;
+			data = null;
+		}
+
+		return arguments.length > 0 ?
+			this.on( name, null, data, fn ) :
+			this.trigger( name );
+	};
+
+	if ( rkeyEvent.test( name ) ) {
+		jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;
+	}
+
+	if ( rmouseEvent.test( name ) ) {
+		jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
+	}
+});
+/*!
+ * Sizzle CSS Selector Engine
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://sizzlejs.com/
+ */
+(function( window, undefined ) {
+
+var cachedruns,
+	assertGetIdNotName,
+	Expr,
+	getText,
+	isXML,
+	contains,
+	compile,
+	sortOrder,
+	hasDuplicate,
+	outermostContext,
+
+	baseHasDuplicate = true,
+	strundefined = "undefined",
+
+	expando = ( "sizcache" + Math.random() ).replace( ".", "" ),
+
+	Token = String,
+	document = window.document,
+	docElem = document.documentElement,
+	dirruns = 0,
+	done = 0,
+	pop = [].pop,
+	push = [].push,
+	slice = [].slice,
+	// Use a stripped-down indexOf if a native one is unavailable
+	indexOf = [].indexOf || function( elem ) {
+		var i = 0,
+			len = this.length;
+		for ( ; i < len; i++ ) {
+			if ( this[i] === elem ) {
+				return i;
+			}
+		}
+		return -1;
+	},
+
+	// Augment a function for special use by Sizzle
+	markFunction = function( fn, value ) {
+		fn[ expando ] = value == null || value;
+		return fn;
+	},
+
+	createCache = function() {
+		var cache = {},
+			keys = [];
+
+		return markFunction(function( key, value ) {
+			// Only keep the most recent entries
+			if ( keys.push( key ) > Expr.cacheLength ) {
+				delete cache[ keys.shift() ];
+			}
+
+			// Retrieve with (key + " ") to avoid collision with native Object.prototype properties (see Issue #157)
+			return (cache[ key + " " ] = value);
+		}, cache );
+	},
+
+	classCache = createCache(),
+	tokenCache = createCache(),
+	compilerCache = createCache(),
+
+	// Regex
+
+	// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
+	whitespace = "[\\x20\\t\\r\\n\\f]",
+	// http://www.w3.org/TR/css3-syntax/#characters
+	characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",
+
+	// Loosely modeled on CSS identifier characters
+	// An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)
+	// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+	identifier = characterEncoding.replace( "w", "w#" ),
+
+	// Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
+	operators = "([*^$|!~]?=)",
+	attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
+		"*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
+
+	// Prefer arguments not in parens/brackets,
+	//   then attribute selectors and non-pseudos (denoted by :),
+	//   then anything else
+	// These preferences are here to reduce the number of selectors
+	//   needing tokenize in the PSEUDO preFilter
+	pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)",
+
+	// For matchExpr.POS and matchExpr.needsContext
+	pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
+		"*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)",
+
+	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+	rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ),
+	rpseudo = new RegExp( pseudos ),
+
+	// Easily-parseable/retrievable ID or TAG or CLASS selectors
+	rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,
+
+	rnot = /^:not/,
+	rsibling = /[\x20\t\r\n\f]*[+~]/,
+	rendsWithNot = /:not\($/,
+
+	rheader = /h\d/i,
+	rinputs = /input|select|textarea|button/i,
+
+	rbackslash = /\\(?!\\)/g,
+
+	matchExpr = {
+		"ID": new RegExp( "^#(" + characterEncoding + ")" ),
+		"CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
+		"NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),
+		"TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
+		"ATTR": new RegExp( "^" + attributes ),
+		"PSEUDO": new RegExp( "^" + pseudos ),
+		"POS": new RegExp( pos, "i" ),
+		"CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace +
+			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+		// For use in libraries implementing .is()
+		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )
+	},
+
+	// Support
+
+	// Used for testing something on an element
+	assert = function( fn ) {
+		var div = document.createElement("div");
+
+		try {
+			return fn( div );
+		} catch (e) {
+			return false;
+		} finally {
+			// release memory in IE
+			div = null;
+		}
+	},
+
+	// Check if getElementsByTagName("*") returns only elements
+	assertTagNameNoComments = assert(function( div ) {
+		div.appendChild( document.createComment("") );
+		return !div.getElementsByTagName("*").length;
+	}),
+
+	// Check if getAttribute returns normalized href attributes
+	assertHrefNotNormalized = assert(function( div ) {
+		div.innerHTML = "<a href='#'></a>";
+		return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
+			div.firstChild.getAttribute("href") === "#";
+	}),
+
+	// Check if attributes should be retrieved by attribute nodes
+	assertAttributes = assert(function( div ) {
+		div.innerHTML = "<select></select>";
+		var type = typeof div.lastChild.getAttribute("multiple");
+		// IE8 returns a string for some attributes even when not present
+		return type !== "boolean" && type !== "string";
+	}),
+
+	// Check if getElementsByClassName can be trusted
+	assertUsableClassName = assert(function( div ) {
+		// Opera can't find a second classname (in 9.6)
+		div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
+		if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) {
+			return false;
+		}
+
+		// Safari 3.2 caches class attributes and doesn't catch changes
+		div.lastChild.className = "e";
+		return div.getElementsByClassName("e").length === 2;
+	}),
+
+	// Check if getElementById returns elements by name
+	// Check if getElementsByName privileges form controls or returns elements by ID
+	assertUsableName = assert(function( div ) {
+		// Inject content
+		div.id = expando + 0;
+		div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
+		docElem.insertBefore( div, docElem.firstChild );
+
+		// Test
+		var pass = document.getElementsByName &&
+			// buggy browsers will return fewer than the correct 2
+			document.getElementsByName( expando ).length === 2 +
+			// buggy browsers will return more than the correct 0
+			document.getElementsByName( expando + 0 ).length;
+		assertGetIdNotName = !document.getElementById( expando );
+
+		// Cleanup
+		docElem.removeChild( div );
+
+		return pass;
+	});
+
+// If slice is not available, provide a backup
+try {
+	slice.call( docElem.childNodes, 0 )[0].nodeType;
+} catch ( e ) {
+	slice = function( i ) {
+		var elem,
+			results = [];
+		for ( ; (elem = this[i]); i++ ) {
+			results.push( elem );
+		}
+		return results;
+	};
+}
+
+function Sizzle( selector, context, results, seed ) {
+	results = results || [];
+	context = context || document;
+	var match, elem, xml, m,
+		nodeType = context.nodeType;
+
+	if ( !selector || typeof selector !== "string" ) {
+		return results;
+	}
+
+	if ( nodeType !== 1 && nodeType !== 9 ) {
+		return [];
+	}
+
+	xml = isXML( context );
+
+	if ( !xml && !seed ) {
+		if ( (match = rquickExpr.exec( selector )) ) {
+			// Speed-up: Sizzle("#ID")
+			if ( (m = match[1]) ) {
+				if ( nodeType === 9 ) {
+					elem = context.getElementById( m );
+					// Check parentNode to catch when Blackberry 4.6 returns
+					// nodes that are no longer in the document #6963
+					if ( elem && elem.parentNode ) {
+						// Handle the case where IE, Opera, and Webkit return items
+						// by name instead of ID
+						if ( elem.id === m ) {
+							results.push( elem );
+							return results;
+						}
+					} else {
+						return results;
+					}
+				} else {
+					// Context is not a document
+					if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
+						contains( context, elem ) && elem.id === m ) {
+						results.push( elem );
+						return results;
+					}
+				}
+
+			// Speed-up: Sizzle("TAG")
+			} else if ( match[2] ) {
+				push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
+				return results;
+
+			// Speed-up: Sizzle(".CLASS")
+			} else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {
+				push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
+				return results;
+			}
+		}
+	}
+
+	// All others
+	return select( selector.replace( rtrim, "$1" ), context, results, seed, xml );
+}
+
+Sizzle.matches = function( expr, elements ) {
+	return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+	return Sizzle( expr, null, null, [ elem ] ).length > 0;
+};
+
+// Returns a function to use in pseudos for input types
+function createInputPseudo( type ) {
+	return function( elem ) {
+		var name = elem.nodeName.toLowerCase();
+		return name === "input" && elem.type === type;
+	};
+}
+
+// Returns a function to use in pseudos for buttons
+function createButtonPseudo( type ) {
+	return function( elem ) {
+		var name = elem.nodeName.toLowerCase();
+		return (name === "input" || name === "button") && elem.type === type;
+	};
+}
+
+// Returns a function to use in pseudos for positionals
+function createPositionalPseudo( fn ) {
+	return markFunction(function( argument ) {
+		argument = +argument;
+		return markFunction(function( seed, matches ) {
+			var j,
+				matchIndexes = fn( [], seed.length, argument ),
+				i = matchIndexes.length;
+
+			// Match elements found at the specified indexes
+			while ( i-- ) {
+				if ( seed[ (j = matchIndexes[i]) ] ) {
+					seed[j] = !(matches[j] = seed[j]);
+				}
+			}
+		});
+	});
+}
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+	var node,
+		ret = "",
+		i = 0,
+		nodeType = elem.nodeType;
+
+	if ( nodeType ) {
+		if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+			// Use textContent for elements
+			// innerText usage removed for consistency of new lines (see #11153)
+			if ( typeof elem.textContent === "string" ) {
+				return elem.textContent;
+			} else {
+				// Traverse its children
+				for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+					ret += getText( elem );
+				}
+			}
+		} else if ( nodeType === 3 || nodeType === 4 ) {
+			return elem.nodeValue;
+		}
+		// Do not include comment or processing instruction nodes
+	} else {
+
+		// If no nodeType, this is expected to be an array
+		for ( ; (node = elem[i]); i++ ) {
+			// Do not traverse comment nodes
+			ret += getText( node );
+		}
+	}
+	return ret;
+};
+
+isXML = Sizzle.isXML = function( elem ) {
+	// documentElement is verified for cases where it doesn't yet exist
+	// (such as loading iframes in IE - #4833)
+	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+	return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+// Element contains another
+contains = Sizzle.contains = docElem.contains ?
+	function( a, b ) {
+		var adown = a.nodeType === 9 ? a.documentElement : a,
+			bup = b && b.parentNode;
+		return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );
+	} :
+	docElem.compareDocumentPosition ?
+	function( a, b ) {
+		return b && !!( a.compareDocumentPosition( b ) & 16 );
+	} :
+	function( a, b ) {
+		while ( (b = b.parentNode) ) {
+			if ( b === a ) {
+				return true;
+			}
+		}
+		return false;
+	};
+
+Sizzle.attr = function( elem, name ) {
+	var val,
+		xml = isXML( elem );
+
+	if ( !xml ) {
+		name = name.toLowerCase();
+	}
+	if ( (val = Expr.attrHandle[ name ]) ) {
+		return val( elem );
+	}
+	if ( xml || assertAttributes ) {
+		return elem.getAttribute( name );
+	}
+	val = elem.getAttributeNode( name );
+	return val ?
+		typeof elem[ name ] === "boolean" ?
+			elem[ name ] ? name : null :
+			val.specified ? val.value : null :
+		null;
+};
+
+Expr = Sizzle.selectors = {
+
+	// Can be adjusted by the user
+	cacheLength: 50,
+
+	createPseudo: markFunction,
+
+	match: matchExpr,
+
+	// IE6/7 return a modified href
+	attrHandle: assertHrefNotNormalized ?
+		{} :
+		{
+			"href": function( elem ) {
+				return elem.getAttribute( "href", 2 );
+			},
+			"type": function( elem ) {
+				return elem.getAttribute("type");
+			}
+		},
+
+	find: {
+		"ID": assertGetIdNotName ?
+			function( id, context, xml ) {
+				if ( typeof context.getElementById !== strundefined && !xml ) {
+					var m = context.getElementById( id );
+					// Check parentNode to catch when Blackberry 4.6 returns
+					// nodes that are no longer in the document #6963
+					return m && m.parentNode ? [m] : [];
+				}
+			} :
+			function( id, context, xml ) {
+				if ( typeof context.getElementById !== strundefined && !xml ) {
+					var m = context.getElementById( id );
+
+					return m ?
+						m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ?
+							[m] :
+							undefined :
+						[];
+				}
+			},
+
+		"TAG": assertTagNameNoComments ?
+			function( tag, context ) {
+				if ( typeof context.getElementsByTagName !== strundefined ) {
+					return context.getElementsByTagName( tag );
+				}
+			} :
+			function( tag, context ) {
+				var results = context.getElementsByTagName( tag );
+
+				// Filter out possible comments
+				if ( tag === "*" ) {
+					var elem,
+						tmp = [],
+						i = 0;
+
+					for ( ; (elem = results[i]); i++ ) {
+						if ( elem.nodeType === 1 ) {
+							tmp.push( elem );
+						}
+					}
+
+					return tmp;
+				}
+				return results;
+			},
+
+		"NAME": assertUsableName && function( tag, context ) {
+			if ( typeof context.getElementsByName !== strundefined ) {
+				return context.getElementsByName( name );
+			}
+		},
+
+		"CLASS": assertUsableClassName && function( className, context, xml ) {
+			if ( typeof context.getElementsByClassName !== strundefined && !xml ) {
+				return context.getElementsByClassName( className );
+			}
+		}
+	},
+
+	relative: {
+		">": { dir: "parentNode", first: true },
+		" ": { dir: "parentNode" },
+		"+": { dir: "previousSibling", first: true },
+		"~": { dir: "previousSibling" }
+	},
+
+	preFilter: {
+		"ATTR": function( match ) {
+			match[1] = match[1].replace( rbackslash, "" );
+
+			// Move the given value to match[3] whether quoted or unquoted
+			match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" );
+
+			if ( match[2] === "~=" ) {
+				match[3] = " " + match[3] + " ";
+			}
+
+			return match.slice( 0, 4 );
+		},
+
+		"CHILD": function( match ) {
+			/* matches from matchExpr["CHILD"]
+				1 type (only|nth|...)
+				2 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+				3 xn-component of xn+y argument ([+-]?\d*n|)
+				4 sign of xn-component
+				5 x of xn-component
+				6 sign of y-component
+				7 y of y-component
+			*/
+			match[1] = match[1].toLowerCase();
+
+			if ( match[1] === "nth" ) {
+				// nth-child requires argument
+				if ( !match[2] ) {
+					Sizzle.error( match[0] );
+				}
+
+				// numeric x and y parameters for Expr.filter.CHILD
+				// remember that false/true cast respectively to 0/1
+				match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) );
+				match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" );
+
+			// other types prohibit arguments
+			} else if ( match[2] ) {
+				Sizzle.error( match[0] );
+			}
+
+			return match;
+		},
+
+		"PSEUDO": function( match ) {
+			var unquoted, excess;
+			if ( matchExpr["CHILD"].test( match[0] ) ) {
+				return null;
+			}
+
+			if ( match[3] ) {
+				match[2] = match[3];
+			} else if ( (unquoted = match[4]) ) {
+				// Only check arguments that contain a pseudo
+				if ( rpseudo.test(unquoted) &&
+					// Get excess from tokenize (recursively)
+					(excess = tokenize( unquoted, true )) &&
+					// advance to the next closing parenthesis
+					(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+					// excess is a negative index
+					unquoted = unquoted.slice( 0, excess );
+					match[0] = match[0].slice( 0, excess );
+				}
+				match[2] = unquoted;
+			}
+
+			// Return only captures needed by the pseudo filter method (type and argument)
+			return match.slice( 0, 3 );
+		}
+	},
+
+	filter: {
+		"ID": assertGetIdNotName ?
+			function( id ) {
+				id = id.replace( rbackslash, "" );
+				return function( elem ) {
+					return elem.getAttribute("id") === id;
+				};
+			} :
+			function( id ) {
+				id = id.replace( rbackslash, "" );
+				return function( elem ) {
+					var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
+					return node && node.value === id;
+				};
+			},
+
+		"TAG": function( nodeName ) {
+			if ( nodeName === "*" ) {
+				return function() { return true; };
+			}
+			nodeName = nodeName.replace( rbackslash, "" ).toLowerCase();
+
+			return function( elem ) {
+				return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+			};
+		},
+
+		"CLASS": function( className ) {
+			var pattern = classCache[ expando ][ className + " " ];
+
+			return pattern ||
+				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
+				classCache( className, function( elem ) {
+					return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );
+				});
+		},
+
+		"ATTR": function( name, operator, check ) {
+			return function( elem, context ) {
+				var result = Sizzle.attr( elem, name );
+
+				if ( result == null ) {
+					return operator === "!=";
+				}
+				if ( !operator ) {
+					return true;
+				}
+
+				result += "";
+
+				return operator === "=" ? result === check :
+					operator === "!=" ? result !== check :
+					operator === "^=" ? check && result.indexOf( check ) === 0 :
+					operator === "*=" ? check && result.indexOf( check ) > -1 :
+					operator === "$=" ? check && result.substr( result.length - check.length ) === check :
+					operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
+					operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" :
+					false;
+			};
+		},
+
+		"CHILD": function( type, argument, first, last ) {
+
+			if ( type === "nth" ) {
+				return function( elem ) {
+					var node, diff,
+						parent = elem.parentNode;
+
+					if ( first === 1 && last === 0 ) {
+						return true;
+					}
+
+					if ( parent ) {
+						diff = 0;
+						for ( node = parent.firstChild; node; node = node.nextSibling ) {
+							if ( node.nodeType === 1 ) {
+								diff++;
+								if ( elem === node ) {
+									break;
+								}
+							}
+						}
+					}
+
+					// Incorporate the offset (or cast to NaN), then check against cycle size
+					diff -= last;
+					return diff === first || ( diff % first === 0 && diff / first >= 0 );
+				};
+			}
+
+			return function( elem ) {
+				var node = elem;
+
+				switch ( type ) {
+					case "only":
+					case "first":
+						while ( (node = node.previousSibling) ) {
+							if ( node.nodeType === 1 ) {
+								return false;
+							}
+						}
+
+						if ( type === "first" ) {
+							return true;
+						}
+
+						node = elem;
+
+						/* falls through */
+					case "last":
+						while ( (node = node.nextSibling) ) {
+							if ( node.nodeType === 1 ) {
+								return false;
+							}
+						}
+
+						return true;
+				}
+			};
+		},
+
+		"PSEUDO": function( pseudo, argument ) {
+			// pseudo-class names are case-insensitive
+			// http://www.w3.org/TR/selectors/#pseudo-classes
+			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+			// Remember that setFilters inherits from pseudos
+			var args,
+				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+					Sizzle.error( "unsupported pseudo: " + pseudo );
+
+			// The user may use createPseudo to indicate that
+			// arguments are needed to create the filter function
+			// just as Sizzle does
+			if ( fn[ expando ] ) {
+				return fn( argument );
+			}
+
+			// But maintain support for old signatures
+			if ( fn.length > 1 ) {
+				args = [ pseudo, pseudo, "", argument ];
+				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+					markFunction(function( seed, matches ) {
+						var idx,
+							matched = fn( seed, argument ),
+							i = matched.length;
+						while ( i-- ) {
+							idx = indexOf.call( seed, matched[i] );
+							seed[ idx ] = !( matches[ idx ] = matched[i] );
+						}
+					}) :
+					function( elem ) {
+						return fn( elem, 0, args );
+					};
+			}
+
+			return fn;
+		}
+	},
+
+	pseudos: {
+		"not": markFunction(function( selector ) {
+			// Trim the selector passed to compile
+			// to avoid treating leading and trailing
+			// spaces as combinators
+			var input = [],
+				results = [],
+				matcher = compile( selector.replace( rtrim, "$1" ) );
+
+			return matcher[ expando ] ?
+				markFunction(function( seed, matches, context, xml ) {
+					var elem,
+						unmatched = matcher( seed, null, xml, [] ),
+						i = seed.length;
+
+					// Match elements unmatched by `matcher`
+					while ( i-- ) {
+						if ( (elem = unmatched[i]) ) {
+							seed[i] = !(matches[i] = elem);
+						}
+					}
+				}) :
+				function( elem, context, xml ) {
+					input[0] = elem;
+					matcher( input, null, xml, results );
+					return !results.pop();
+				};
+		}),
+
+		"has": markFunction(function( selector ) {
+			return function( elem ) {
+				return Sizzle( selector, elem ).length > 0;
+			};
+		}),
+
+		"contains": markFunction(function( text ) {
+			return function( elem ) {
+				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+			};
+		}),
+
+		"enabled": function( elem ) {
+			return elem.disabled === false;
+		},
+
+		"disabled": function( elem ) {
+			return elem.disabled === true;
+		},
+
+		"checked": function( elem ) {
+			// In CSS3, :checked should return both checked and selected elements
+			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+			var nodeName = elem.nodeName.toLowerCase();
+			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+		},
+
+		"selected": function( elem ) {
+			// Accessing this property makes selected-by-default
+			// options in Safari work properly
+			if ( elem.parentNode ) {
+				elem.parentNode.selectedIndex;
+			}
+
+			return elem.selected === true;
+		},
+
+		"parent": function( elem ) {
+			return !Expr.pseudos["empty"]( elem );
+		},
+
+		"empty": function( elem ) {
+			// http://www.w3.org/TR/selectors/#empty-pseudo
+			// :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
+			//   not comment, processing instructions, or others
+			// Thanks to Diego Perini for the nodeName shortcut
+			//   Greater than "@" means alpha characters (specifically not starting with "#" or "?")
+			var nodeType;
+			elem = elem.firstChild;
+			while ( elem ) {
+				if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {
+					return false;
+				}
+				elem = elem.nextSibling;
+			}
+			return true;
+		},
+
+		"header": function( elem ) {
+			return rheader.test( elem.nodeName );
+		},
+
+		"text": function( elem ) {
+			var type, attr;
+			// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+			// use getAttribute instead to test this case
+			return elem.nodeName.toLowerCase() === "input" &&
+				(type = elem.type) === "text" &&
+				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type );
+		},
+
+		// Input types
+		"radio": createInputPseudo("radio"),
+		"checkbox": createInputPseudo("checkbox"),
+		"file": createInputPseudo("file"),
+		"password": createInputPseudo("password"),
+		"image": createInputPseudo("image"),
+
+		"submit": createButtonPseudo("submit"),
+		"reset": createButtonPseudo("reset"),
+
+		"button": function( elem ) {
+			var name = elem.nodeName.toLowerCase();
+			return name === "input" && elem.type === "button" || name === "button";
+		},
+
+		"input": function( elem ) {
+			return rinputs.test( elem.nodeName );
+		},
+
+		"focus": function( elem ) {
+			var doc = elem.ownerDocument;
+			return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+		},
+
+		"active": function( elem ) {
+			return elem === elem.ownerDocument.activeElement;
+		},
+
+		// Positional types
+		"first": createPositionalPseudo(function() {
+			return [ 0 ];
+		}),
+
+		"last": createPositionalPseudo(function( matchIndexes, length ) {
+			return [ length - 1 ];
+		}),
+
+		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+			return [ argument < 0 ? argument + length : argument ];
+		}),
+
+		"even": createPositionalPseudo(function( matchIndexes, length ) {
+			for ( var i = 0; i < length; i += 2 ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"odd": createPositionalPseudo(function( matchIndexes, length ) {
+			for ( var i = 1; i < length; i += 2 ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+			for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+			for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		})
+	}
+};
+
+function siblingCheck( a, b, ret ) {
+	if ( a === b ) {
+		return ret;
+	}
+
+	var cur = a.nextSibling;
+
+	while ( cur ) {
+		if ( cur === b ) {
+			return -1;
+		}
+
+		cur = cur.nextSibling;
+	}
+
+	return 1;
+}
+
+sortOrder = docElem.compareDocumentPosition ?
+	function( a, b ) {
+		if ( a === b ) {
+			hasDuplicate = true;
+			return 0;
+		}
+
+		return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?
+			a.compareDocumentPosition :
+			a.compareDocumentPosition(b) & 4
+		) ? -1 : 1;
+	} :
+	function( a, b ) {
+		// The nodes are identical, we can exit early
+		if ( a === b ) {
+			hasDuplicate = true;
+			return 0;
+
+		// Fallback to using sourceIndex (in IE) if it's available on both nodes
+		} else if ( a.sourceIndex && b.sourceIndex ) {
+			return a.sourceIndex - b.sourceIndex;
+		}
+
+		var al, bl,
+			ap = [],
+			bp = [],
+			aup = a.parentNode,
+			bup = b.parentNode,
+			cur = aup;
+
+		// If the nodes are siblings (or identical) we can do a quick check
+		if ( aup === bup ) {
+			return siblingCheck( a, b );
+
+		// If no parents were found then the nodes are disconnected
+		} else if ( !aup ) {
+			return -1;
+
+		} else if ( !bup ) {
+			return 1;
+		}
+
+		// Otherwise they're somewhere else in the tree so we need
+		// to build up a full list of the parentNodes for comparison
+		while ( cur ) {
+			ap.unshift( cur );
+			cur = cur.parentNode;
+		}
+
+		cur = bup;
+
+		while ( cur ) {
+			bp.unshift( cur );
+			cur = cur.parentNode;
+		}
+
+		al = ap.length;
+		bl = bp.length;
+
+		// Start walking down the tree looking for a discrepancy
+		for ( var i = 0; i < al && i < bl; i++ ) {
+			if ( ap[i] !== bp[i] ) {
+				return siblingCheck( ap[i], bp[i] );
+			}
+		}
+
+		// We ended someplace up the tree so do a sibling check
+		return i === al ?
+			siblingCheck( a, bp[i], -1 ) :
+			siblingCheck( ap[i], b, 1 );
+	};
+
+// Always assume the presence of duplicates if sort doesn't
+// pass them to our comparison function (as in Google Chrome).
+[0, 0].sort( sortOrder );
+baseHasDuplicate = !hasDuplicate;
+
+// Document sorting and removing duplicates
+Sizzle.uniqueSort = function( results ) {
+	var elem,
+		duplicates = [],
+		i = 1,
+		j = 0;
+
+	hasDuplicate = baseHasDuplicate;
+	results.sort( sortOrder );
+
+	if ( hasDuplicate ) {
+		for ( ; (elem = results[i]); i++ ) {
+			if ( elem === results[ i - 1 ] ) {
+				j = duplicates.push( i );
+			}
+		}
+		while ( j-- ) {
+			results.splice( duplicates[ j ], 1 );
+		}
+	}
+
+	return results;
+};
+
+Sizzle.error = function( msg ) {
+	throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+function tokenize( selector, parseOnly ) {
+	var matched, match, tokens, type,
+		soFar, groups, preFilters,
+		cached = tokenCache[ expando ][ selector + " " ];
+
+	if ( cached ) {
+		return parseOnly ? 0 : cached.slice( 0 );
+	}
+
+	soFar = selector;
+	groups = [];
+	preFilters = Expr.preFilter;
+
+	while ( soFar ) {
+
+		// Comma and first run
+		if ( !matched || (match = rcomma.exec( soFar )) ) {
+			if ( match ) {
+				// Don't consume trailing commas as valid
+				soFar = soFar.slice( match[0].length ) || soFar;
+			}
+			groups.push( tokens = [] );
+		}
+
+		matched = false;
+
+		// Combinators
+		if ( (match = rcombinators.exec( soFar )) ) {
+			tokens.push( matched = new Token( match.shift() ) );
+			soFar = soFar.slice( matched.length );
+
+			// Cast descendant combinators to space
+			matched.type = match[0].replace( rtrim, " " );
+		}
+
+		// Filters
+		for ( type in Expr.filter ) {
+			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+				(match = preFilters[ type ]( match ))) ) {
+
+				tokens.push( matched = new Token( match.shift() ) );
+				soFar = soFar.slice( matched.length );
+				matched.type = type;
+				matched.matches = match;
+			}
+		}
+
+		if ( !matched ) {
+			break;
+		}
+	}
+
+	// Return the length of the invalid excess
+	// if we're just parsing
+	// Otherwise, throw an error or return tokens
+	return parseOnly ?
+		soFar.length :
+		soFar ?
+			Sizzle.error( selector ) :
+			// Cache the tokens
+			tokenCache( selector, groups ).slice( 0 );
+}
+
+function addCombinator( matcher, combinator, base ) {
+	var dir = combinator.dir,
+		checkNonElements = base && combinator.dir === "parentNode",
+		doneName = done++;
+
+	return combinator.first ?
+		// Check against closest ancestor/preceding element
+		function( elem, context, xml ) {
+			while ( (elem = elem[ dir ]) ) {
+				if ( checkNonElements || elem.nodeType === 1  ) {
+					return matcher( elem, context, xml );
+				}
+			}
+		} :
+
+		// Check against all ancestor/preceding elements
+		function( elem, context, xml ) {
+			// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
+			if ( !xml ) {
+				var cache,
+					dirkey = dirruns + " " + doneName + " ",
+					cachedkey = dirkey + cachedruns;
+				while ( (elem = elem[ dir ]) ) {
+					if ( checkNonElements || elem.nodeType === 1 ) {
+						if ( (cache = elem[ expando ]) === cachedkey ) {
+							return elem.sizset;
+						} else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {
+							if ( elem.sizset ) {
+								return elem;
+							}
+						} else {
+							elem[ expando ] = cachedkey;
+							if ( matcher( elem, context, xml ) ) {
+								elem.sizset = true;
+								return elem;
+							}
+							elem.sizset = false;
+						}
+					}
+				}
+			} else {
+				while ( (elem = elem[ dir ]) ) {
+					if ( checkNonElements || elem.nodeType === 1 ) {
+						if ( matcher( elem, context, xml ) ) {
+							return elem;
+						}
+					}
+				}
+			}
+		};
+}
+
+function elementMatcher( matchers ) {
+	return matchers.length > 1 ?
+		function( elem, context, xml ) {
+			var i = matchers.length;
+			while ( i-- ) {
+				if ( !matchers[i]( elem, context, xml ) ) {
+					return false;
+				}
+			}
+			return true;
+		} :
+		matchers[0];
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+	var elem,
+		newUnmatched = [],
+		i = 0,
+		len = unmatched.length,
+		mapped = map != null;
+
+	for ( ; i < len; i++ ) {
+		if ( (elem = unmatched[i]) ) {
+			if ( !filter || filter( elem, context, xml ) ) {
+				newUnmatched.push( elem );
+				if ( mapped ) {
+					map.push( i );
+				}
+			}
+		}
+	}
+
+	return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+	if ( postFilter && !postFilter[ expando ] ) {
+		postFilter = setMatcher( postFilter );
+	}
+	if ( postFinder && !postFinder[ expando ] ) {
+		postFinder = setMatcher( postFinder, postSelector );
+	}
+	return markFunction(function( seed, results, context, xml ) {
+		var temp, i, elem,
+			preMap = [],
+			postMap = [],
+			preexisting = results.length,
+
+			// Get initial elements from seed or context
+			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
+
+			// Prefilter to get matcher input, preserving a map for seed-results synchronization
+			matcherIn = preFilter && ( seed || !selector ) ?
+				condense( elems, preMap, preFilter, context, xml ) :
+				elems,
+
+			matcherOut = matcher ?
+				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+					// ...intermediate processing is necessary
+					[] :
+
+					// ...otherwise use results directly
+					results :
+				matcherIn;
+
+		// Find primary matches
+		if ( matcher ) {
+			matcher( matcherIn, matcherOut, context, xml );
+		}
+
+		// Apply postFilter
+		if ( postFilter ) {
+			temp = condense( matcherOut, postMap );
+			postFilter( temp, [], context, xml );
+
+			// Un-match failing elements by moving them back to matcherIn
+			i = temp.length;
+			while ( i-- ) {
+				if ( (elem = temp[i]) ) {
+					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+				}
+			}
+		}
+
+		if ( seed ) {
+			if ( postFinder || preFilter ) {
+				if ( postFinder ) {
+					// Get the final matcherOut by condensing this intermediate into postFinder contexts
+					temp = [];
+					i = matcherOut.length;
+					while ( i-- ) {
+						if ( (elem = matcherOut[i]) ) {
+							// Restore matcherIn since elem is not yet a final match
+							temp.push( (matcherIn[i] = elem) );
+						}
+					}
+					postFinder( null, (matcherOut = []), temp, xml );
+				}
+
+				// Move matched elements from seed to results to keep them synchronized
+				i = matcherOut.length;
+				while ( i-- ) {
+					if ( (elem = matcherOut[i]) &&
+						(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
+
+						seed[temp] = !(results[temp] = elem);
+					}
+				}
+			}
+
+		// Add elements to results, through postFinder if defined
+		} else {
+			matcherOut = condense(
+				matcherOut === results ?
+					matcherOut.splice( preexisting, matcherOut.length ) :
+					matcherOut
+			);
+			if ( postFinder ) {
+				postFinder( null, results, matcherOut, xml );
+			} else {
+				push.apply( results, matcherOut );
+			}
+		}
+	});
+}
+
+function matcherFromTokens( tokens ) {
+	var checkContext, matcher, j,
+		len = tokens.length,
+		leadingRelative = Expr.relative[ tokens[0].type ],
+		implicitRelative = leadingRelative || Expr.relative[" "],
+		i = leadingRelative ? 1 : 0,
+
+		// The foundational matcher ensures that elements are reachable from top-level context(s)
+		matchContext = addCombinator( function( elem ) {
+			return elem === checkContext;
+		}, implicitRelative, true ),
+		matchAnyContext = addCombinator( function( elem ) {
+			return indexOf.call( checkContext, elem ) > -1;
+		}, implicitRelative, true ),
+		matchers = [ function( elem, context, xml ) {
+			return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+				(checkContext = context).nodeType ?
+					matchContext( elem, context, xml ) :
+					matchAnyContext( elem, context, xml ) );
+		} ];
+
+	for ( ; i < len; i++ ) {
+		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+			matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
+		} else {
+			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+			// Return special upon seeing a positional matcher
+			if ( matcher[ expando ] ) {
+				// Find the next relative operator (if any) for proper handling
+				j = ++i;
+				for ( ; j < len; j++ ) {
+					if ( Expr.relative[ tokens[j].type ] ) {
+						break;
+					}
+				}
+				return setMatcher(
+					i > 1 && elementMatcher( matchers ),
+					i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ),
+					matcher,
+					i < j && matcherFromTokens( tokens.slice( i, j ) ),
+					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+					j < len && tokens.join("")
+				);
+			}
+			matchers.push( matcher );
+		}
+	}
+
+	return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+	var bySet = setMatchers.length > 0,
+		byElement = elementMatchers.length > 0,
+		superMatcher = function( seed, context, xml, results, expandContext ) {
+			var elem, j, matcher,
+				setMatched = [],
+				matchedCount = 0,
+				i = "0",
+				unmatched = seed && [],
+				outermost = expandContext != null,
+				contextBackup = outermostContext,
+				// We must always have either seed elements or context
+				elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
+				// Nested matchers should use non-integer dirruns
+				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E);
+
+			if ( outermost ) {
+				outermostContext = context !== document && context;
+				cachedruns = superMatcher.el;
+			}
+
+			// Add elements passing elementMatchers directly to results
+			for ( ; (elem = elems[i]) != null; i++ ) {
+				if ( byElement && elem ) {
+					for ( j = 0; (matcher = elementMatchers[j]); j++ ) {
+						if ( matcher( elem, context, xml ) ) {
+							results.push( elem );
+							break;
+						}
+					}
+					if ( outermost ) {
+						dirruns = dirrunsUnique;
+						cachedruns = ++superMatcher.el;
+					}
+				}
+
+				// Track unmatched elements for set filters
+				if ( bySet ) {
+					// They will have gone through all possible matchers
+					if ( (elem = !matcher && elem) ) {
+						matchedCount--;
+					}
+
+					// Lengthen the array for every element, matched or not
+					if ( seed ) {
+						unmatched.push( elem );
+					}
+				}
+			}
+
+			// Apply set filters to unmatched elements
+			matchedCount += i;
+			if ( bySet && i !== matchedCount ) {
+				for ( j = 0; (matcher = setMatchers[j]); j++ ) {
+					matcher( unmatched, setMatched, context, xml );
+				}
+
+				if ( seed ) {
+					// Reintegrate element matches to eliminate the need for sorting
+					if ( matchedCount > 0 ) {
+						while ( i-- ) {
+							if ( !(unmatched[i] || setMatched[i]) ) {
+								setMatched[i] = pop.call( results );
+							}
+						}
+					}
+
+					// Discard index placeholder values to get only actual matches
+					setMatched = condense( setMatched );
+				}
+
+				// Add matches to results
+				push.apply( results, setMatched );
+
+				// Seedless set matches succeeding multiple successful matchers stipulate sorting
+				if ( outermost && !seed && setMatched.length > 0 &&
+					( matchedCount + setMatchers.length ) > 1 ) {
+
+					Sizzle.uniqueSort( results );
+				}
+			}
+
+			// Override manipulation of globals by nested matchers
+			if ( outermost ) {
+				dirruns = dirrunsUnique;
+				outermostContext = contextBackup;
+			}
+
+			return unmatched;
+		};
+
+	superMatcher.el = 0;
+	return bySet ?
+		markFunction( superMatcher ) :
+		superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
+	var i,
+		setMatchers = [],
+		elementMatchers = [],
+		cached = compilerCache[ expando ][ selector + " " ];
+
+	if ( !cached ) {
+		// Generate a function of recursive functions that can be used to check each element
+		if ( !group ) {
+			group = tokenize( selector );
+		}
+		i = group.length;
+		while ( i-- ) {
+			cached = matcherFromTokens( group[i] );
+			if ( cached[ expando ] ) {
+				setMatchers.push( cached );
+			} else {
+				elementMatchers.push( cached );
+			}
+		}
+
+		// Cache the compiled function
+		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+	}
+	return cached;
+};
+
+function multipleContexts( selector, contexts, results ) {
+	var i = 0,
+		len = contexts.length;
+	for ( ; i < len; i++ ) {
+		Sizzle( selector, contexts[i], results );
+	}
+	return results;
+}
+
+function select( selector, context, results, seed, xml ) {
+	var i, tokens, token, type, find,
+		match = tokenize( selector ),
+		j = match.length;
+
+	if ( !seed ) {
+		// Try to minimize operations if there is only one group
+		if ( match.length === 1 ) {
+
+			// Take a shortcut and set the context if the root selector is an ID
+			tokens = match[0] = match[0].slice( 0 );
+			if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+					context.nodeType === 9 && !xml &&
+					Expr.relative[ tokens[1].type ] ) {
+
+				context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0];
+				if ( !context ) {
+					return results;
+				}
+
+				selector = selector.slice( tokens.shift().length );
+			}
+
+			// Fetch a seed set for right-to-left matching
+			for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) {
+				token = tokens[i];
+
+				// Abort if we hit a combinator
+				if ( Expr.relative[ (type = token.type) ] ) {
+					break;
+				}
+				if ( (find = Expr.find[ type ]) ) {
+					// Search, expanding context for leading sibling combinators
+					if ( (seed = find(
+						token.matches[0].replace( rbackslash, "" ),
+						rsibling.test( tokens[0].type ) && context.parentNode || context,
+						xml
+					)) ) {
+
+						// If seed is empty or no tokens remain, we can return early
+						tokens.splice( i, 1 );
+						selector = seed.length && tokens.join("");
+						if ( !selector ) {
+							push.apply( results, slice.call( seed, 0 ) );
+							return results;
+						}
+
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	// Compile and execute a filtering function
+	// Provide `match` to avoid retokenization if we modified the selector above
+	compile( selector, match )(
+		seed,
+		context,
+		xml,
+		results,
+		rsibling.test( selector )
+	);
+	return results;
+}
+
+if ( document.querySelectorAll ) {
+	(function() {
+		var disconnectedMatch,
+			oldSelect = select,
+			rescape = /'|\\/g,
+			rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,
+
+			// qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA
+			// A support test would require too much code (would include document ready)
+			rbuggyQSA = [ ":focus" ],
+
+			// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+			// A support test would require too much code (would include document ready)
+			// just skip matchesSelector for :active
+			rbuggyMatches = [ ":active" ],
+			matches = docElem.matchesSelector ||
+				docElem.mozMatchesSelector ||
+				docElem.webkitMatchesSelector ||
+				docElem.oMatchesSelector ||
+				docElem.msMatchesSelector;
+
+		// Build QSA regex
+		// Regex strategy adopted from Diego Perini
+		assert(function( div ) {
+			// Select is set to empty string on purpose
+			// This is to test IE's treatment of not explictly
+			// setting a boolean content attribute,
+			// since its presence should be enough
+			// http://bugs.jquery.com/ticket/12359
+			div.innerHTML = "<select><option selected=''></option></select>";
+
+			// IE8 - Some boolean attributes are not treated correctly
+			if ( !div.querySelectorAll("[selected]").length ) {
+				rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" );
+			}
+
+			// Webkit/Opera - :checked should return selected option elements
+			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+			// IE8 throws error here (do not put tests after this one)
+			if ( !div.querySelectorAll(":checked").length ) {
+				rbuggyQSA.push(":checked");
+			}
+		});
+
+		assert(function( div ) {
+
+			// Opera 10-12/IE9 - ^= $= *= and empty values
+			// Should not select anything
+			div.innerHTML = "<p test=''></p>";
+			if ( div.querySelectorAll("[test^='']").length ) {
+				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );
+			}
+
+			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+			// IE8 throws error here (do not put tests after this one)
+			div.innerHTML = "<input type='hidden'/>";
+			if ( !div.querySelectorAll(":enabled").length ) {
+				rbuggyQSA.push(":enabled", ":disabled");
+			}
+		});
+
+		// rbuggyQSA always contains :focus, so no need for a length check
+		rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") );
+
+		select = function( selector, context, results, seed, xml ) {
+			// Only use querySelectorAll when not filtering,
+			// when this is not xml,
+			// and when no QSA bugs apply
+			if ( !seed && !xml && !rbuggyQSA.test( selector ) ) {
+				var groups, i,
+					old = true,
+					nid = expando,
+					newContext = context,
+					newSelector = context.nodeType === 9 && selector;
+
+				// qSA works strangely on Element-rooted queries
+				// We can work around this by specifying an extra ID on the root
+				// and working up from there (Thanks to Andrew Dupont for the technique)
+				// IE 8 doesn't work on object elements
+				if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+					groups = tokenize( selector );
+
+					if ( (old = context.getAttribute("id")) ) {
+						nid = old.replace( rescape, "\\$&" );
+					} else {
+						context.setAttribute( "id", nid );
+					}
+					nid = "[id='" + nid + "'] ";
+
+					i = groups.length;
+					while ( i-- ) {
+						groups[i] = nid + groups[i].join("");
+					}
+					newContext = rsibling.test( selector ) && context.parentNode || context;
+					newSelector = groups.join(",");
+				}
+
+				if ( newSelector ) {
+					try {
+						push.apply( results, slice.call( newContext.querySelectorAll(
+							newSelector
+						), 0 ) );
+						return results;
+					} catch(qsaError) {
+					} finally {
+						if ( !old ) {
+							context.removeAttribute("id");
+						}
+					}
+				}
+			}
+
+			return oldSelect( selector, context, results, seed, xml );
+		};
+
+		if ( matches ) {
+			assert(function( div ) {
+				// Check to see if it's possible to do matchesSelector
+				// on a disconnected node (IE 9)
+				disconnectedMatch = matches.call( div, "div" );
+
+				// This should fail with an exception
+				// Gecko does not error, returns false instead
+				try {
+					matches.call( div, "[test!='']:sizzle" );
+					rbuggyMatches.push( "!=", pseudos );
+				} catch ( e ) {}
+			});
+
+			// rbuggyMatches always contains :active and :focus, so no need for a length check
+			rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") );
+
+			Sizzle.matchesSelector = function( elem, expr ) {
+				// Make sure that attribute selectors are quoted
+				expr = expr.replace( rattributeQuotes, "='$1']" );
+
+				// rbuggyMatches always contains :active, so no need for an existence check
+				if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) {
+					try {
+						var ret = matches.call( elem, expr );
+
+						// IE 9's matchesSelector returns false on disconnected nodes
+						if ( ret || disconnectedMatch ||
+								// As well, disconnected nodes are said to be in a document
+								// fragment in IE 9
+								elem.document && elem.document.nodeType !== 11 ) {
+							return ret;
+						}
+					} catch(e) {}
+				}
+
+				return Sizzle( expr, null, null, [ elem ] ).length > 0;
+			};
+		}
+	})();
+}
+
+// Deprecated
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Back-compat
+function setFilters() {}
+Expr.filters = setFilters.prototype = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
+// Override sizzle attribute retrieval
+Sizzle.attr = jQuery.attr;
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.pseudos;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+})( window );
+var runtil = /Until$/,
+	rparentsprev = /^(?:parents|prev(?:Until|All))/,
+	isSimple = /^.[^:#\[\.,]*$/,
+	rneedsContext = jQuery.expr.match.needsContext,
+	// methods guaranteed to produce a unique set when starting from a unique set
+	guaranteedUnique = {
+		children: true,
+		contents: true,
+		next: true,
+		prev: true
+	};
+
+jQuery.fn.extend({
+	find: function( selector ) {
+		var i, l, length, n, r, ret,
+			self = this;
+
+		if ( typeof selector !== "string" ) {
+			return jQuery( selector ).filter(function() {
+				for ( i = 0, l = self.length; i < l; i++ ) {
+					if ( jQuery.contains( self[ i ], this ) ) {
+						return true;
+					}
+				}
+			});
+		}
+
+		ret = this.pushStack( "", "find", selector );
+
+		for ( i = 0, l = this.length; i < l; i++ ) {
+			length = ret.length;
+			jQuery.find( selector, this[i], ret );
+
+			if ( i > 0 ) {
+				// Make sure that the results are unique
+				for ( n = length; n < ret.length; n++ ) {
+					for ( r = 0; r < length; r++ ) {
+						if ( ret[r] === ret[n] ) {
+							ret.splice(n--, 1);
+							break;
+						}
+					}
+				}
+			}
+		}
+
+		return ret;
+	},
+
+	has: function( target ) {
+		var i,
+			targets = jQuery( target, this ),
+			len = targets.length;
+
+		return this.filter(function() {
+			for ( i = 0; i < len; i++ ) {
+				if ( jQuery.contains( this, targets[i] ) ) {
+					return true;
+				}
+			}
+		});
+	},
+
+	not: function( selector ) {
+		return this.pushStack( winnow(this, selector, false), "not", selector);
+	},
+
+	filter: function( selector ) {
+		return this.pushStack( winnow(this, selector, true), "filter", selector );
+	},
+
+	is: function( selector ) {
+		return !!selector && (
+			typeof selector === "string" ?
+				// If this is a positional/relative selector, check membership in the returned set
+				// so $("p:first").is("p:last") won't return true for a doc with two "p".
+				rneedsContext.test( selector ) ?
+					jQuery( selector, this.context ).index( this[0] ) >= 0 :
+					jQuery.filter( selector, this ).length > 0 :
+				this.filter( selector ).length > 0 );
+	},
+
+	closest: function( selectors, context ) {
+		var cur,
+			i = 0,
+			l = this.length,
+			ret = [],
+			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
+				jQuery( selectors, context || this.context ) :
+				0;
+
+		for ( ; i < l; i++ ) {
+			cur = this[i];
+
+			while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) {
+				if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
+					ret.push( cur );
+					break;
+				}
+				cur = cur.parentNode;
+			}
+		}
+
+		ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
+
+		return this.pushStack( ret, "closest", selectors );
+	},
+
+	// Determine the position of an element within
+	// the matched set of elements
+	index: function( elem ) {
+
+		// No argument, return index in parent
+		if ( !elem ) {
+			return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;
+		}
+
+		// index in selector
+		if ( typeof elem === "string" ) {
+			return jQuery.inArray( this[0], jQuery( elem ) );
+		}
+
+		// Locate the position of the desired element
+		return jQuery.inArray(
+			// If it receives a jQuery object, the first element is used
+			elem.jquery ? elem[0] : elem, this );
+	},
+
+	add: function( selector, context ) {
+		var set = typeof selector === "string" ?
+				jQuery( selector, context ) :
+				jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
+			all = jQuery.merge( this.get(), set );
+
+		return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
+			all :
+			jQuery.unique( all ) );
+	},
+
+	addBack: function( selector ) {
+		return this.add( selector == null ?
+			this.prevObject : this.prevObject.filter(selector)
+		);
+	}
+});
+
+jQuery.fn.andSelf = jQuery.fn.addBack;
+
+// A painfully simple check to see if an element is disconnected
+// from a document (should be improved, where feasible).
+function isDisconnected( node ) {
+	return !node || !node.parentNode || node.parentNode.nodeType === 11;
+}
+
+function sibling( cur, dir ) {
+	do {
+		cur = cur[ dir ];
+	} while ( cur && cur.nodeType !== 1 );
+
+	return cur;
+}
+
+jQuery.each({
+	parent: function( elem ) {
+		var parent = elem.parentNode;
+		return parent && parent.nodeType !== 11 ? parent : null;
+	},
+	parents: function( elem ) {
+		return jQuery.dir( elem, "parentNode" );
+	},
+	parentsUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "parentNode", until );
+	},
+	next: function( elem ) {
+		return sibling( elem, "nextSibling" );
+	},
+	prev: function( elem ) {
+		return sibling( elem, "previousSibling" );
+	},
+	nextAll: function( elem ) {
+		return jQuery.dir( elem, "nextSibling" );
+	},
+	prevAll: function( elem ) {
+		return jQuery.dir( elem, "previousSibling" );
+	},
+	nextUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "nextSibling", until );
+	},
+	prevUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "previousSibling", until );
+	},
+	siblings: function( elem ) {
+		return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
+	},
+	children: function( elem ) {
+		return jQuery.sibling( elem.firstChild );
+	},
+	contents: function( elem ) {
+		return jQuery.nodeName( elem, "iframe" ) ?
+			elem.contentDocument || elem.contentWindow.document :
+			jQuery.merge( [], elem.childNodes );
+	}
+}, function( name, fn ) {
+	jQuery.fn[ name ] = function( until, selector ) {
+		var ret = jQuery.map( this, fn, until );
+
+		if ( !runtil.test( name ) ) {
+			selector = until;
+		}
+
+		if ( selector && typeof selector === "string" ) {
+			ret = jQuery.filter( selector, ret );
+		}
+
+		ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
+
+		if ( this.length > 1 && rparentsprev.test( name ) ) {
+			ret = ret.reverse();
+		}
+
+		return this.pushStack( ret, name, core_slice.call( arguments ).join(",") );
+	};
+});
+
+jQuery.extend({
+	filter: function( expr, elems, not ) {
+		if ( not ) {
+			expr = ":not(" + expr + ")";
+		}
+
+		return elems.length === 1 ?
+			jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
+			jQuery.find.matches(expr, elems);
+	},
+
+	dir: function( elem, dir, until ) {
+		var matched = [],
+			cur = elem[ dir ];
+
+		while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+			if ( cur.nodeType === 1 ) {
+				matched.push( cur );
+			}
+			cur = cur[dir];
+		}
+		return matched;
+	},
+
+	sibling: function( n, elem ) {
+		var r = [];
+
+		for ( ; n; n = n.nextSibling ) {
+			if ( n.nodeType === 1 && n !== elem ) {
+				r.push( n );
+			}
+		}
+
+		return r;
+	}
+});
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, keep ) {
+
+	// Can't pass null or undefined to indexOf in Firefox 4
+	// Set to 0 to skip string check
+	qualifier = qualifier || 0;
+
+	if ( jQuery.isFunction( qualifier ) ) {
+		return jQuery.grep(elements, function( elem, i ) {
+			var retVal = !!qualifier.call( elem, i, elem );
+			return retVal === keep;
+		});
+
+	} else if ( qualifier.nodeType ) {
+		return jQuery.grep(elements, function( elem, i ) {
+			return ( elem === qualifier ) === keep;
+		});
+
+	} else if ( typeof qualifier === "string" ) {
+		var filtered = jQuery.grep(elements, function( elem ) {
+			return elem.nodeType === 1;
+		});
+
+		if ( isSimple.test( qualifier ) ) {
+			return jQuery.filter(qualifier, filtered, !keep);
+		} else {
+			qualifier = jQuery.filter( qualifier, filtered );
+		}
+	}
+
+	return jQuery.grep(elements, function( elem, i ) {
+		return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
+	});
+}
+function createSafeFragment( document ) {
+	var list = nodeNames.split( "|" ),
+	safeFrag = document.createDocumentFragment();
+
+	if ( safeFrag.createElement ) {
+		while ( list.length ) {
+			safeFrag.createElement(
+				list.pop()
+			);
+		}
+	}
+	return safeFrag;
+}
+
+var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
+		"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
+	rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
+	rleadingWhitespace = /^\s+/,
+	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
+	rtagName = /<([\w:]+)/,
+	rtbody = /<tbody/i,
+	rhtml = /<|&#?\w+;/,
+	rnoInnerhtml = /<(?:script|style|link)/i,
+	rnocache = /<(?:script|object|embed|option|style)/i,
+	rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
+	rcheckableType = /^(?:checkbox|radio)$/,
+	// checked="checked" or checked
+	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+	rscriptType = /\/(java|ecma)script/i,
+	rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,
+	wrapMap = {
+		option: [ 1, "<select multiple='multiple'>", "</select>" ],
+		legend: [ 1, "<fieldset>", "</fieldset>" ],
+		thead: [ 1, "<table>", "</table>" ],
+		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+		area: [ 1, "<map>", "</map>" ],
+		_default: [ 0, "", "" ]
+	},
+	safeFragment = createSafeFragment( document ),
+	fragmentDiv = safeFragment.appendChild( document.createElement("div") );
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
+// unless wrapped in a div with non-breaking characters in front of it.
+if ( !jQuery.support.htmlSerialize ) {
+	wrapMap._default = [ 1, "X<div>", "</div>" ];
+}
+
+jQuery.fn.extend({
+	text: function( value ) {
+		return jQuery.access( this, function( value ) {
+			return value === undefined ?
+				jQuery.text( this ) :
+				this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
+		}, null, value, arguments.length );
+	},
+
+	wrapAll: function( html ) {
+		if ( jQuery.isFunction( html ) ) {
+			return this.each(function(i) {
+				jQuery(this).wrapAll( html.call(this, i) );
+			});
+		}
+
+		if ( this[0] ) {
+			// The elements to wrap the target around
+			var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+			if ( this[0].parentNode ) {
+				wrap.insertBefore( this[0] );
+			}
+
+			wrap.map(function() {
+				var elem = this;
+
+				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+					elem = elem.firstChild;
+				}
+
+				return elem;
+			}).append( this );
+		}
+
+		return this;
+	},
+
+	wrapInner: function( html ) {
+		if ( jQuery.isFunction( html ) ) {
+			return this.each(function(i) {
+				jQuery(this).wrapInner( html.call(this, i) );
+			});
+		}
+
+		return this.each(function() {
+			var self = jQuery( this ),
+				contents = self.contents();
+
+			if ( contents.length ) {
+				contents.wrapAll( html );
+
+			} else {
+				self.append( html );
+			}
+		});
+	},
+
+	wrap: function( html ) {
+		var isFunction = jQuery.isFunction( html );
+
+		return this.each(function(i) {
+			jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
+		});
+	},
+
+	unwrap: function() {
+		return this.parent().each(function() {
+			if ( !jQuery.nodeName( this, "body" ) ) {
+				jQuery( this ).replaceWith( this.childNodes );
+			}
+		}).end();
+	},
+
+	append: function() {
+		return this.domManip(arguments, true, function( elem ) {
+			if ( this.nodeType === 1 || this.nodeType === 11 ) {
+				this.appendChild( elem );
+			}
+		});
+	},
+
+	prepend: function() {
+		return this.domManip(arguments, true, function( elem ) {
+			if ( this.nodeType === 1 || this.nodeType === 11 ) {
+				this.insertBefore( elem, this.firstChild );
+			}
+		});
+	},
+
+	before: function() {
+		if ( !isDisconnected( this[0] ) ) {
+			return this.domManip(arguments, false, function( elem ) {
+				this.parentNode.insertBefore( elem, this );
+			});
+		}
+
+		if ( arguments.length ) {
+			var set = jQuery.clean( arguments );
+			return this.pushStack( jQuery.merge( set, this ), "before", this.selector );
+		}
+	},
+
+	after: function() {
+		if ( !isDisconnected( this[0] ) ) {
+			return this.domManip(arguments, false, function( elem ) {
+				this.parentNode.insertBefore( elem, this.nextSibling );
+			});
+		}
+
+		if ( arguments.length ) {
+			var set = jQuery.clean( arguments );
+			return this.pushStack( jQuery.merge( this, set ), "after", this.selector );
+		}
+	},
+
+	// keepData is for internal use only--do not document
+	remove: function( selector, keepData ) {
+		var elem,
+			i = 0;
+
+		for ( ; (elem = this[i]) != null; i++ ) {
+			if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
+				if ( !keepData && elem.nodeType === 1 ) {
+					jQuery.cleanData( elem.getElementsByTagName("*") );
+					jQuery.cleanData( [ elem ] );
+				}
+
+				if ( elem.parentNode ) {
+					elem.parentNode.removeChild( elem );
+				}
+			}
+		}
+
+		return this;
+	},
+
+	empty: function() {
+		var elem,
+			i = 0;
+
+		for ( ; (elem = this[i]) != null; i++ ) {
+			// Remove element nodes and prevent memory leaks
+			if ( elem.nodeType === 1 ) {
+				jQuery.cleanData( elem.getElementsByTagName("*") );
+			}
+
+			// Remove any remaining nodes
+			while ( elem.firstChild ) {
+				elem.removeChild( elem.firstChild );
+			}
+		}
+
+		return this;
+	},
+
+	clone: function( dataAndEvents, deepDataAndEvents ) {
+		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+		return this.map( function () {
+			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+		});
+	},
+
+	html: function( value ) {
+		return jQuery.access( this, function( value ) {
+			var elem = this[0] || {},
+				i = 0,
+				l = this.length;
+
+			if ( value === undefined ) {
+				return elem.nodeType === 1 ?
+					elem.innerHTML.replace( rinlinejQuery, "" ) :
+					undefined;
+			}
+
+			// See if we can take a shortcut and just use innerHTML
+			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
+				( jQuery.support.htmlSerialize || !rnoshimcache.test( value )  ) &&
+				( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
+				!wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {
+
+				value = value.replace( rxhtmlTag, "<$1></$2>" );
+
+				try {
+					for (; i < l; i++ ) {
+						// Remove element nodes and prevent memory leaks
+						elem = this[i] || {};
+						if ( elem.nodeType === 1 ) {
+							jQuery.cleanData( elem.getElementsByTagName( "*" ) );
+							elem.innerHTML = value;
+						}
+					}
+
+					elem = 0;
+
+				// If using innerHTML throws an exception, use the fallback method
+				} catch(e) {}
+			}
+
+			if ( elem ) {
+				this.empty().append( value );
+			}
+		}, null, value, arguments.length );
+	},
+
+	replaceWith: function( value ) {
+		if ( !isDisconnected( this[0] ) ) {
+			// Make sure that the elements are removed from the DOM before they are inserted
+			// this can help fix replacing a parent with child elements
+			if ( jQuery.isFunction( value ) ) {
+				return this.each(function(i) {
+					var self = jQuery(this), old = self.html();
+					self.replaceWith( value.call( this, i, old ) );
+				});
+			}
+
+			if ( typeof value !== "string" ) {
+				value = jQuery( value ).detach();
+			}
+
+			return this.each(function() {
+				var next = this.nextSibling,
+					parent = this.parentNode;
+
+				jQuery( this ).remove();
+
+				if ( next ) {
+					jQuery(next).before( value );
+				} else {
+					jQuery(parent).append( value );
+				}
+			});
+		}
+
+		return this.length ?
+			this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
+			this;
+	},
+
+	detach: function( selector ) {
+		return this.remove( selector, true );
+	},
+
+	domManip: function( args, table, callback ) {
+
+		// Flatten any nested arrays
+		args = [].concat.apply( [], args );
+
+		var results, first, fragment, iNoClone,
+			i = 0,
+			value = args[0],
+			scripts = [],
+			l = this.length;
+
+		// We can't cloneNode fragments that contain checked, in WebKit
+		if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) {
+			return this.each(function() {
+				jQuery(this).domManip( args, table, callback );
+			});
+		}
+
+		if ( jQuery.isFunction(value) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				args[0] = value.call( this, i, table ? self.html() : undefined );
+				self.domManip( args, table, callback );
+			});
+		}
+
+		if ( this[0] ) {
+			results = jQuery.buildFragment( args, this, scripts );
+			fragment = results.fragment;
+			first = fragment.firstChild;
+
+			if ( fragment.childNodes.length === 1 ) {
+				fragment = first;
+			}
+
+			if ( first ) {
+				table = table && jQuery.nodeName( first, "tr" );
+
+				// Use the original fragment for the last item instead of the first because it can end up
+				// being emptied incorrectly in certain situations (#8070).
+				// Fragments from the fragment cache must always be cloned and never used in place.
+				for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) {
+					callback.call(
+						table && jQuery.nodeName( this[i], "table" ) ?
+							findOrAppend( this[i], "tbody" ) :
+							this[i],
+						i === iNoClone ?
+							fragment :
+							jQuery.clone( fragment, true, true )
+					);
+				}
+			}
+
+			// Fix #11809: Avoid leaking memory
+			fragment = first = null;
+
+			if ( scripts.length ) {
+				jQuery.each( scripts, function( i, elem ) {
+					if ( elem.src ) {
+						if ( jQuery.ajax ) {
+							jQuery.ajax({
+								url: elem.src,
+								type: "GET",
+								dataType: "script",
+								async: false,
+								global: false,
+								"throws": true
+							});
+						} else {
+							jQuery.error("no ajax");
+						}
+					} else {
+						jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) );
+					}
+
+					if ( elem.parentNode ) {
+						elem.parentNode.removeChild( elem );
+					}
+				});
+			}
+		}
+
+		return this;
+	}
+});
+
+function findOrAppend( elem, tag ) {
+	return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) );
+}
+
+function cloneCopyEvent( src, dest ) {
+
+	if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
+		return;
+	}
+
+	var type, i, l,
+		oldData = jQuery._data( src ),
+		curData = jQuery._data( dest, oldData ),
+		events = oldData.events;
+
+	if ( events ) {
+		delete curData.handle;
+		curData.events = {};
+
+		for ( type in events ) {
+			for ( i = 0, l = events[ type ].length; i < l; i++ ) {
+				jQuery.event.add( dest, type, events[ type ][ i ] );
+			}
+		}
+	}
+
+	// make the cloned public data object a copy from the original
+	if ( curData.data ) {
+		curData.data = jQuery.extend( {}, curData.data );
+	}
+}
+
+function cloneFixAttributes( src, dest ) {
+	var nodeName;
+
+	// We do not need to do anything for non-Elements
+	if ( dest.nodeType !== 1 ) {
+		return;
+	}
+
+	// clearAttributes removes the attributes, which we don't want,
+	// but also removes the attachEvent events, which we *do* want
+	if ( dest.clearAttributes ) {
+		dest.clearAttributes();
+	}
+
+	// mergeAttributes, in contrast, only merges back on the
+	// original attributes, not the events
+	if ( dest.mergeAttributes ) {
+		dest.mergeAttributes( src );
+	}
+
+	nodeName = dest.nodeName.toLowerCase();
+
+	if ( nodeName === "object" ) {
+		// IE6-10 improperly clones children of object elements using classid.
+		// IE10 throws NoModificationAllowedError if parent is null, #12132.
+		if ( dest.parentNode ) {
+			dest.outerHTML = src.outerHTML;
+		}
+
+		// This path appears unavoidable for IE9. When cloning an object
+		// element in IE9, the outerHTML strategy above is not sufficient.
+		// If the src has innerHTML and the destination does not,
+		// copy the src.innerHTML into the dest.innerHTML. #10324
+		if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) {
+			dest.innerHTML = src.innerHTML;
+		}
+
+	} else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
+		// IE6-8 fails to persist the checked state of a cloned checkbox
+		// or radio button. Worse, IE6-7 fail to give the cloned element
+		// a checked appearance if the defaultChecked value isn't also set
+
+		dest.defaultChecked = dest.checked = src.checked;
+
+		// IE6-7 get confused and end up setting the value of a cloned
+		// checkbox/radio button to an empty string instead of "on"
+		if ( dest.value !== src.value ) {
+			dest.value = src.value;
+		}
+
+	// IE6-8 fails to return the selected option to the default selected
+	// state when cloning options
+	} else if ( nodeName === "option" ) {
+		dest.selected = src.defaultSelected;
+
+	// IE6-8 fails to set the defaultValue to the correct value when
+	// cloning other types of input fields
+	} else if ( nodeName === "input" || nodeName === "textarea" ) {
+		dest.defaultValue = src.defaultValue;
+
+	// IE blanks contents when cloning scripts
+	} else if ( nodeName === "script" && dest.text !== src.text ) {
+		dest.text = src.text;
+	}
+
+	// Event data gets referenced instead of copied if the expando
+	// gets copied too
+	dest.removeAttribute( jQuery.expando );
+}
+
+jQuery.buildFragment = function( args, context, scripts ) {
+	var fragment, cacheable, cachehit,
+		first = args[ 0 ];
+
+	// Set context from what may come in as undefined or a jQuery collection or a node
+	// Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 &
+	// also doubles as fix for #8950 where plain objects caused createDocumentFragment exception
+	context = context || document;
+	context = !context.nodeType && context[0] || context;
+	context = context.ownerDocument || context;
+
+	// Only cache "small" (1/2 KB) HTML strings that are associated with the main document
+	// Cloning options loses the selected state, so don't cache them
+	// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
+	// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
+	// Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501
+	if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document &&
+		first.charAt(0) === "<" && !rnocache.test( first ) &&
+		(jQuery.support.checkClone || !rchecked.test( first )) &&
+		(jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {
+
+		// Mark cacheable and look for a hit
+		cacheable = true;
+		fragment = jQuery.fragments[ first ];
+		cachehit = fragment !== undefined;
+	}
+
+	if ( !fragment ) {
+		fragment = context.createDocumentFragment();
+		jQuery.clean( args, context, fragment, scripts );
+
+		// Update the cache, but only store false
+		// unless this is a second parsing of the same content
+		if ( cacheable ) {
+			jQuery.fragments[ first ] = cachehit && fragment;
+		}
+	}
+
+	return { fragment: fragment, cacheable: cacheable };
+};
+
+jQuery.fragments = {};
+
+jQuery.each({
+	appendTo: "append",
+	prependTo: "prepend",
+	insertBefore: "before",
+	insertAfter: "after",
+	replaceAll: "replaceWith"
+}, function( name, original ) {
+	jQuery.fn[ name ] = function( selector ) {
+		var elems,
+			i = 0,
+			ret = [],
+			insert = jQuery( selector ),
+			l = insert.length,
+			parent = this.length === 1 && this[0].parentNode;
+
+		if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) {
+			insert[ original ]( this[0] );
+			return this;
+		} else {
+			for ( ; i < l; i++ ) {
+				elems = ( i > 0 ? this.clone(true) : this ).get();
+				jQuery( insert[i] )[ original ]( elems );
+				ret = ret.concat( elems );
+			}
+
+			return this.pushStack( ret, name, insert.selector );
+		}
+	};
+});
+
+function getAll( elem ) {
+	if ( typeof elem.getElementsByTagName !== "undefined" ) {
+		return elem.getElementsByTagName( "*" );
+
+	} else if ( typeof elem.querySelectorAll !== "undefined" ) {
+		return elem.querySelectorAll( "*" );
+
+	} else {
+		return [];
+	}
+}
+
+// Used in clean, fixes the defaultChecked property
+function fixDefaultChecked( elem ) {
+	if ( rcheckableType.test( elem.type ) ) {
+		elem.defaultChecked = elem.checked;
+	}
+}
+
+jQuery.extend({
+	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+		var srcElements,
+			destElements,
+			i,
+			clone;
+
+		if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
+			clone = elem.cloneNode( true );
+
+		// IE<=8 does not properly clone detached, unknown element nodes
+		} else {
+			fragmentDiv.innerHTML = elem.outerHTML;
+			fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
+		}
+
+		if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
+				(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
+			// IE copies events bound via attachEvent when using cloneNode.
+			// Calling detachEvent on the clone will also remove the events
+			// from the original. In order to get around this, we use some
+			// proprietary methods to clear the events. Thanks to MooTools
+			// guys for this hotness.
+
+			cloneFixAttributes( elem, clone );
+
+			// Using Sizzle here is crazy slow, so we use getElementsByTagName instead
+			srcElements = getAll( elem );
+			destElements = getAll( clone );
+
+			// Weird iteration because IE will replace the length property
+			// with an element if you are cloning the body and one of the
+			// elements on the page has a name or id of "length"
+			for ( i = 0; srcElements[i]; ++i ) {
+				// Ensure that the destination node is not null; Fixes #9587
+				if ( destElements[i] ) {
+					cloneFixAttributes( srcElements[i], destElements[i] );
+				}
+			}
+		}
+
+		// Copy the events from the original to the clone
+		if ( dataAndEvents ) {
+			cloneCopyEvent( elem, clone );
+
+			if ( deepDataAndEvents ) {
+				srcElements = getAll( elem );
+				destElements = getAll( clone );
+
+				for ( i = 0; srcElements[i]; ++i ) {
+					cloneCopyEvent( srcElements[i], destElements[i] );
+				}
+			}
+		}
+
+		srcElements = destElements = null;
+
+		// Return the cloned set
+		return clone;
+	},
+
+	clean: function( elems, context, fragment, scripts ) {
+		var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags,
+			safe = context === document && safeFragment,
+			ret = [];
+
+		// Ensure that context is a document
+		if ( !context || typeof context.createDocumentFragment === "undefined" ) {
+			context = document;
+		}
+
+		// Use the already-created safe fragment if context permits
+		for ( i = 0; (elem = elems[i]) != null; i++ ) {
+			if ( typeof elem === "number" ) {
+				elem += "";
+			}
+
+			if ( !elem ) {
+				continue;
+			}
+
+			// Convert html string into DOM nodes
+			if ( typeof elem === "string" ) {
+				if ( !rhtml.test( elem ) ) {
+					elem = context.createTextNode( elem );
+				} else {
+					// Ensure a safe container in which to render the html
+					safe = safe || createSafeFragment( context );
+					div = context.createElement("div");
+					safe.appendChild( div );
+
+					// Fix "XHTML"-style tags in all browsers
+					elem = elem.replace(rxhtmlTag, "<$1></$2>");
+
+					// Go to html and back, then peel off extra wrappers
+					tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase();
+					wrap = wrapMap[ tag ] || wrapMap._default;
+					depth = wrap[0];
+					div.innerHTML = wrap[1] + elem + wrap[2];
+
+					// Move to the right depth
+					while ( depth-- ) {
+						div = div.lastChild;
+					}
+
+					// Remove IE's autoinserted <tbody> from table fragments
+					if ( !jQuery.support.tbody ) {
+
+						// String was a <table>, *may* have spurious <tbody>
+						hasBody = rtbody.test(elem);
+							tbody = tag === "table" && !hasBody ?
+								div.firstChild && div.firstChild.childNodes :
+
+								// String was a bare <thead> or <tfoot>
+								wrap[1] === "<table>" && !hasBody ?
+									div.childNodes :
+									[];
+
+						for ( j = tbody.length - 1; j >= 0 ; --j ) {
+							if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
+								tbody[ j ].parentNode.removeChild( tbody[ j ] );
+							}
+						}
+					}
+
+					// IE completely kills leading whitespace when innerHTML is used
+					if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+						div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
+					}
+
+					elem = div.childNodes;
+
+					// Take out of fragment container (we need a fresh div each time)
+					div.parentNode.removeChild( div );
+				}
+			}
+
+			if ( elem.nodeType ) {
+				ret.push( elem );
+			} else {
+				jQuery.merge( ret, elem );
+			}
+		}
+
+		// Fix #11356: Clear elements from safeFragment
+		if ( div ) {
+			elem = div = safe = null;
+		}
+
+		// Reset defaultChecked for any radios and checkboxes
+		// about to be appended to the DOM in IE 6/7 (#8060)
+		if ( !jQuery.support.appendChecked ) {
+			for ( i = 0; (elem = ret[i]) != null; i++ ) {
+				if ( jQuery.nodeName( elem, "input" ) ) {
+					fixDefaultChecked( elem );
+				} else if ( typeof elem.getElementsByTagName !== "undefined" ) {
+					jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
+				}
+			}
+		}
+
+		// Append elements to a provided document fragment
+		if ( fragment ) {
+			// Special handling of each script element
+			handleScript = function( elem ) {
+				// Check if we consider it executable
+				if ( !elem.type || rscriptType.test( elem.type ) ) {
+					// Detach the script and store it in the scripts array (if provided) or the fragment
+					// Return truthy to indicate that it has been handled
+					return scripts ?
+						scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :
+						fragment.appendChild( elem );
+				}
+			};
+
+			for ( i = 0; (elem = ret[i]) != null; i++ ) {
+				// Check if we're done after handling an executable script
+				if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) {
+					// Append to fragment and handle embedded scripts
+					fragment.appendChild( elem );
+					if ( typeof elem.getElementsByTagName !== "undefined" ) {
+						// handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration
+						jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript );
+
+						// Splice the scripts into ret after their former ancestor and advance our index beyond them
+						ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
+						i += jsTags.length;
+					}
+				}
+			}
+		}
+
+		return ret;
+	},
+
+	cleanData: function( elems, /* internal */ acceptData ) {
+		var data, id, elem, type,
+			i = 0,
+			internalKey = jQuery.expando,
+			cache = jQuery.cache,
+			deleteExpando = jQuery.support.deleteExpando,
+			special = jQuery.event.special;
+
+		for ( ; (elem = elems[i]) != null; i++ ) {
+
+			if ( acceptData || jQuery.acceptData( elem ) ) {
+
+				id = elem[ internalKey ];
+				data = id && cache[ id ];
+
+				if ( data ) {
+					if ( data.events ) {
+						for ( type in data.events ) {
+							if ( special[ type ] ) {
+								jQuery.event.remove( elem, type );
+
+							// This is a shortcut to avoid jQuery.event.remove's overhead
+							} else {
+								jQuery.removeEvent( elem, type, data.handle );
+							}
+						}
+					}
+
+					// Remove cache only if it was not already removed by jQuery.event.remove
+					if ( cache[ id ] ) {
+
+						delete cache[ id ];
+
+						// IE does not allow us to delete expando properties from nodes,
+						// nor does it have a removeAttribute function on Document nodes;
+						// we must handle all of these cases
+						if ( deleteExpando ) {
+							delete elem[ internalKey ];
+
+						} else if ( elem.removeAttribute ) {
+							elem.removeAttribute( internalKey );
+
+						} else {
+							elem[ internalKey ] = null;
+						}
+
+						jQuery.deletedIds.push( id );
+					}
+				}
+			}
+		}
+	}
+});
+// Limit scope pollution from any deprecated API
+(function() {
+
+var matched, browser;
+
+// Use of jQuery.browser is frowned upon.
+// More details: http://api.jquery.com/jQuery.browser
+// jQuery.uaMatch maintained for back-compat
+jQuery.uaMatch = function( ua ) {
+	ua = ua.toLowerCase();
+
+	var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
+		/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
+		/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
+		/(msie) ([\w.]+)/.exec( ua ) ||
+		ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
+		[];
+
+	return {
+		browser: match[ 1 ] || "",
+		version: match[ 2 ] || "0"
+	};
+};
+
+matched = jQuery.uaMatch( navigator.userAgent );
+browser = {};
+
+if ( matched.browser ) {
+	browser[ matched.browser ] = true;
+	browser.version = matched.version;
+}
+
+// Chrome is Webkit, but Webkit is also Safari.
+if ( browser.chrome ) {
+	browser.webkit = true;
+} else if ( browser.webkit ) {
+	browser.safari = true;
+}
+
+jQuery.browser = browser;
+
+jQuery.sub = function() {
+	function jQuerySub( selector, context ) {
+		return new jQuerySub.fn.init( selector, context );
+	}
+	jQuery.extend( true, jQuerySub, this );
+	jQuerySub.superclass = this;
+	jQuerySub.fn = jQuerySub.prototype = this();
+	jQuerySub.fn.constructor = jQuerySub;
+	jQuerySub.sub = this.sub;
+	jQuerySub.fn.init = function init( selector, context ) {
+		if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
+			context = jQuerySub( context );
+		}
+
+		return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
+	};
+	jQuerySub.fn.init.prototype = jQuerySub.fn;
+	var rootjQuerySub = jQuerySub(document);
+	return jQuerySub;
+};
+
+})();
+var curCSS, iframe, iframeDoc,
+	ralpha = /alpha\([^)]*\)/i,
+	ropacity = /opacity=([^)]*)/,
+	rposition = /^(top|right|bottom|left)$/,
+	// swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
+	// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
+	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
+	rmargin = /^margin/,
+	rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
+	rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
+	rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ),
+	elemdisplay = { BODY: "block" },
+
+	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+	cssNormalTransform = {
+		letterSpacing: 0,
+		fontWeight: 400
+	},
+
+	cssExpand = [ "Top", "Right", "Bottom", "Left" ],
+	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
+
+	eventsToggle = jQuery.fn.toggle;
+
+// return a css property mapped to a potentially vendor prefixed property
+function vendorPropName( style, name ) {
+
+	// shortcut for names that are not vendor prefixed
+	if ( name in style ) {
+		return name;
+	}
+
+	// check for vendor prefixed names
+	var capName = name.charAt(0).toUpperCase() + name.slice(1),
+		origName = name,
+		i = cssPrefixes.length;
+
+	while ( i-- ) {
+		name = cssPrefixes[ i ] + capName;
+		if ( name in style ) {
+			return name;
+		}
+	}
+
+	return origName;
+}
+
+function isHidden( elem, el ) {
+	elem = el || elem;
+	return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
+}
+
+function showHide( elements, show ) {
+	var elem, display,
+		values = [],
+		index = 0,
+		length = elements.length;
+
+	for ( ; index < length; index++ ) {
+		elem = elements[ index ];
+		if ( !elem.style ) {
+			continue;
+		}
+		values[ index ] = jQuery._data( elem, "olddisplay" );
+		if ( show ) {
+			// Reset the inline display of this element to learn if it is
+			// being hidden by cascaded rules or not
+			if ( !values[ index ] && elem.style.display === "none" ) {
+				elem.style.display = "";
+			}
+
+			// Set elements which have been overridden with display: none
+			// in a stylesheet to whatever the default browser style is
+			// for such an element
+			if ( elem.style.display === "" && isHidden( elem ) ) {
+				values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
+			}
+		} else {
+			display = curCSS( elem, "display" );
+
+			if ( !values[ index ] && display !== "none" ) {
+				jQuery._data( elem, "olddisplay", display );
+			}
+		}
+	}
+
+	// Set the display of most of the elements in a second loop
+	// to avoid the constant reflow
+	for ( index = 0; index < length; index++ ) {
+		elem = elements[ index ];
+		if ( !elem.style ) {
+			continue;
+		}
+		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
+			elem.style.display = show ? values[ index ] || "" : "none";
+		}
+	}
+
+	return elements;
+}
+
+jQuery.fn.extend({
+	css: function( name, value ) {
+		return jQuery.access( this, function( elem, name, value ) {
+			return value !== undefined ?
+				jQuery.style( elem, name, value ) :
+				jQuery.css( elem, name );
+		}, name, value, arguments.length > 1 );
+	},
+	show: function() {
+		return showHide( this, true );
+	},
+	hide: function() {
+		return showHide( this );
+	},
+	toggle: function( state, fn2 ) {
+		var bool = typeof state === "boolean";
+
+		if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) {
+			return eventsToggle.apply( this, arguments );
+		}
+
+		return this.each(function() {
+			if ( bool ? state : isHidden( this ) ) {
+				jQuery( this ).show();
+			} else {
+				jQuery( this ).hide();
+			}
+		});
+	}
+});
+
+jQuery.extend({
+	// Add in style property hooks for overriding the default
+	// behavior of getting and setting a style property
+	cssHooks: {
+		opacity: {
+			get: function( elem, computed ) {
+				if ( computed ) {
+					// We should always get a number back from opacity
+					var ret = curCSS( elem, "opacity" );
+					return ret === "" ? "1" : ret;
+
+				}
+			}
+		}
+	},
+
+	// Exclude the following css properties to add px
+	cssNumber: {
+		"fillOpacity": true,
+		"fontWeight": true,
+		"lineHeight": true,
+		"opacity": true,
+		"orphans": true,
+		"widows": true,
+		"zIndex": true,
+		"zoom": true
+	},
+
+	// Add in properties whose names you wish to fix before
+	// setting or getting the value
+	cssProps: {
+		// normalize float css property
+		"float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
+	},
+
+	// Get and set the style property on a DOM Node
+	style: function( elem, name, value, extra ) {
+		// Don't set styles on text and comment nodes
+		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+			return;
+		}
+
+		// Make sure that we're working with the right name
+		var ret, type, hooks,
+			origName = jQuery.camelCase( name ),
+			style = elem.style;
+
+		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
+
+		// gets hook for the prefixed version
+		// followed by the unprefixed version
+		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+		// Check if we're setting a value
+		if ( value !== undefined ) {
+			type = typeof value;
+
+			// convert relative number strings (+= or -=) to relative numbers. #7345
+			if ( type === "string" && (ret = rrelNum.exec( value )) ) {
+				value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
+				// Fixes bug #9237
+				type = "number";
+			}
+
+			// Make sure that NaN and null values aren't set. See: #7116
+			if ( value == null || type === "number" && isNaN( value ) ) {
+				return;
+			}
+
+			// If a number was passed in, add 'px' to the (except for certain CSS properties)
+			if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
+				value += "px";
+			}
+
+			// If a hook was provided, use that value, otherwise just set the specified value
+			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
+				// Wrapped to prevent IE from throwing errors when 'invalid' values are provided
+				// Fixes bug #5509
+				try {
+					style[ name ] = value;
+				} catch(e) {}
+			}
+
+		} else {
+			// If a hook was provided get the non-computed value from there
+			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
+				return ret;
+			}
+
+			// Otherwise just get the value from the style object
+			return style[ name ];
+		}
+	},
+
+	css: function( elem, name, numeric, extra ) {
+		var val, num, hooks,
+			origName = jQuery.camelCase( name );
+
+		// Make sure that we're working with the right name
+		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
+
+		// gets hook for the prefixed version
+		// followed by the unprefixed version
+		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+		// If a hook was provided get the computed value from there
+		if ( hooks && "get" in hooks ) {
+			val = hooks.get( elem, true, extra );
+		}
+
+		// Otherwise, if a way to get the computed value exists, use that
+		if ( val === undefined ) {
+			val = curCSS( elem, name );
+		}
+
+		//convert "normal" to computed value
+		if ( val === "normal" && name in cssNormalTransform ) {
+			val = cssNormalTransform[ name ];
+		}
+
+		// Return, converting to number if forced or a qualifier was provided and val looks numeric
+		if ( numeric || extra !== undefined ) {
+			num = parseFloat( val );
+			return numeric || jQuery.isNumeric( num ) ? num || 0 : val;
+		}
+		return val;
+	},
+
+	// A method for quickly swapping in/out CSS properties to get correct calculations
+	swap: function( elem, options, callback ) {
+		var ret, name,
+			old = {};
+
+		// Remember the old values, and insert the new ones
+		for ( name in options ) {
+			old[ name ] = elem.style[ name ];
+			elem.style[ name ] = options[ name ];
+		}
+
+		ret = callback.call( elem );
+
+		// Revert the old values
+		for ( name in options ) {
+			elem.style[ name ] = old[ name ];
+		}
+
+		return ret;
+	}
+});
+
+// NOTE: To any future maintainer, we've window.getComputedStyle
+// because jsdom on node.js will break without it.
+if ( window.getComputedStyle ) {
+	curCSS = function( elem, name ) {
+		var ret, width, minWidth, maxWidth,
+			computed = window.getComputedStyle( elem, null ),
+			style = elem.style;
+
+		if ( computed ) {
+
+			// getPropertyValue is only needed for .css('filter') in IE9, see #12537
+			ret = computed.getPropertyValue( name ) || computed[ name ];
+
+			if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
+				ret = jQuery.style( elem, name );
+			}
+
+			// A tribute to the "awesome hack by Dean Edwards"
+			// Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
+			// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
+			// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
+			if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
+				width = style.width;
+				minWidth = style.minWidth;
+				maxWidth = style.maxWidth;
+
+				style.minWidth = style.maxWidth = style.width = ret;
+				ret = computed.width;
+
+				style.width = width;
+				style.minWidth = minWidth;
+				style.maxWidth = maxWidth;
+			}
+		}
+
+		return ret;
+	};
+} else if ( document.documentElement.currentStyle ) {
+	curCSS = function( elem, name ) {
+		var left, rsLeft,
+			ret = elem.currentStyle && elem.currentStyle[ name ],
+			style = elem.style;
+
+		// Avoid setting ret to empty string here
+		// so we don't default to auto
+		if ( ret == null && style && style[ name ] ) {
+			ret = style[ name ];
+		}
+
+		// From the awesome hack by Dean Edwards
+		// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+		// If we're not dealing with a regular pixel number
+		// but a number that has a weird ending, we need to convert it to pixels
+		// but not position css attributes, as those are proportional to the parent element instead
+		// and we can't measure the parent instead because it might trigger a "stacking dolls" problem
+		if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
+
+			// Remember the original values
+			left = style.left;
+			rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;
+
+			// Put in the new values to get a computed value out
+			if ( rsLeft ) {
+				elem.runtimeStyle.left = elem.currentStyle.left;
+			}
+			style.left = name === "fontSize" ? "1em" : ret;
+			ret = style.pixelLeft + "px";
+
+			// Revert the changed values
+			style.left = left;
+			if ( rsLeft ) {
+				elem.runtimeStyle.left = rsLeft;
+			}
+		}
+
+		return ret === "" ? "auto" : ret;
+	};
+}
+
+function setPositiveNumber( elem, value, subtract ) {
+	var matches = rnumsplit.exec( value );
+	return matches ?
+			Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
+			value;
+}
+
+function augmentWidthOrHeight( elem, name, extra, isBorderBox ) {
+	var i = extra === ( isBorderBox ? "border" : "content" ) ?
+		// If we already have the right measurement, avoid augmentation
+		4 :
+		// Otherwise initialize for horizontal or vertical properties
+		name === "width" ? 1 : 0,
+
+		val = 0;
+
+	for ( ; i < 4; i += 2 ) {
+		// both box models exclude margin, so add it if we want it
+		if ( extra === "margin" ) {
+			// we use jQuery.css instead of curCSS here
+			// because of the reliableMarginRight CSS hook!
+			val += jQuery.css( elem, extra + cssExpand[ i ], true );
+		}
+
+		// From this point on we use curCSS for maximum performance (relevant in animations)
+		if ( isBorderBox ) {
+			// border-box includes padding, so remove it if we want content
+			if ( extra === "content" ) {
+				val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0;
+			}
+
+			// at this point, extra isn't border nor margin, so remove border
+			if ( extra !== "margin" ) {
+				val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
+			}
+		} else {
+			// at this point, extra isn't content, so add padding
+			val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0;
+
+			// at this point, extra isn't content nor padding, so add border
+			if ( extra !== "padding" ) {
+				val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
+			}
+		}
+	}
+
+	return val;
+}
+
+function getWidthOrHeight( elem, name, extra ) {
+
+	// Start with offset property, which is equivalent to the border-box value
+	var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
+		valueIsBorderBox = true,
+		isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box";
+
+	// some non-html elements return undefined for offsetWidth, so check for null/undefined
+	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
+	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
+	if ( val <= 0 || val == null ) {
+		// Fall back to computed then uncomputed css if necessary
+		val = curCSS( elem, name );
+		if ( val < 0 || val == null ) {
+			val = elem.style[ name ];
+		}
+
+		// Computed unit is not pixels. Stop here and return.
+		if ( rnumnonpx.test(val) ) {
+			return val;
+		}
+
+		// we need the check for style in case a browser which returns unreliable values
+		// for getComputedStyle silently falls back to the reliable elem.style
+		valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
+
+		// Normalize "", auto, and prepare for extra
+		val = parseFloat( val ) || 0;
+	}
+
+	// use the active box-sizing model to add/subtract irrelevant styles
+	return ( val +
+		augmentWidthOrHeight(
+			elem,
+			name,
+			extra || ( isBorderBox ? "border" : "content" ),
+			valueIsBorderBox
+		)
+	) + "px";
+}
+
+
+// Try to determine the default display value of an element
+function css_defaultDisplay( nodeName ) {
+	if ( elemdisplay[ nodeName ] ) {
+		return elemdisplay[ nodeName ];
+	}
+
+	var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ),
+		display = elem.css("display");
+	elem.remove();
+
+	// If the simple way fails,
+	// get element's real default display by attaching it to a temp iframe
+	if ( display === "none" || display === "" ) {
+		// Use the already-created iframe if possible
+		iframe = document.body.appendChild(
+			iframe || jQuery.extend( document.createElement("iframe"), {
+				frameBorder: 0,
+				width: 0,
+				height: 0
+			})
+		);
+
+		// Create a cacheable copy of the iframe document on first call.
+		// IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
+		// document to it; WebKit & Firefox won't allow reusing the iframe document.
+		if ( !iframeDoc || !iframe.createElement ) {
+			iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
+			iframeDoc.write("<!doctype html><html><body>");
+			iframeDoc.close();
+		}
+
+		elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) );
+
+		display = curCSS( elem, "display" );
+		document.body.removeChild( iframe );
+	}
+
+	// Store the correct default display
+	elemdisplay[ nodeName ] = display;
+
+	return display;
+}
+
+jQuery.each([ "height", "width" ], function( i, name ) {
+	jQuery.cssHooks[ name ] = {
+		get: function( elem, computed, extra ) {
+			if ( computed ) {
+				// certain elements can have dimension info if we invisibly show them
+				// however, it must have a current display style that would benefit from this
+				if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) {
+					return jQuery.swap( elem, cssShow, function() {
+						return getWidthOrHeight( elem, name, extra );
+					});
+				} else {
+					return getWidthOrHeight( elem, name, extra );
+				}
+			}
+		},
+
+		set: function( elem, value, extra ) {
+			return setPositiveNumber( elem, value, extra ?
+				augmentWidthOrHeight(
+					elem,
+					name,
+					extra,
+					jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"
+				) : 0
+			);
+		}
+	};
+});
+
+if ( !jQuery.support.opacity ) {
+	jQuery.cssHooks.opacity = {
+		get: function( elem, computed ) {
+			// IE uses filters for opacity
+			return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
+				( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
+				computed ? "1" : "";
+		},
+
+		set: function( elem, value ) {
+			var style = elem.style,
+				currentStyle = elem.currentStyle,
+				opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
+				filter = currentStyle && currentStyle.filter || style.filter || "";
+
+			// IE has trouble with opacity if it does not have layout
+			// Force it by setting the zoom level
+			style.zoom = 1;
+
+			// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
+			if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
+				style.removeAttribute ) {
+
+				// Setting style.filter to null, "" & " " still leave "filter:" in the cssText
+				// if "filter:" is present at all, clearType is disabled, we want to avoid this
+				// style.removeAttribute is IE Only, but so apparently is this code path...
+				style.removeAttribute( "filter" );
+
+				// if there there is no filter style applied in a css rule, we are done
+				if ( currentStyle && !currentStyle.filter ) {
+					return;
+				}
+			}
+
+			// otherwise, set new filter values
+			style.filter = ralpha.test( filter ) ?
+				filter.replace( ralpha, opacity ) :
+				filter + " " + opacity;
+		}
+	};
+}
+
+// These hooks cannot be added until DOM ready because the support test
+// for it is not run until after DOM ready
+jQuery(function() {
+	if ( !jQuery.support.reliableMarginRight ) {
+		jQuery.cssHooks.marginRight = {
+			get: function( elem, computed ) {
+				// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+				// Work around by temporarily setting element display to inline-block
+				return jQuery.swap( elem, { "display": "inline-block" }, function() {
+					if ( computed ) {
+						return curCSS( elem, "marginRight" );
+					}
+				});
+			}
+		};
+	}
+
+	// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+	// getComputedStyle returns percent when specified for top/left/bottom/right
+	// rather than make the css module depend on the offset module, we just check for it here
+	if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
+		jQuery.each( [ "top", "left" ], function( i, prop ) {
+			jQuery.cssHooks[ prop ] = {
+				get: function( elem, computed ) {
+					if ( computed ) {
+						var ret = curCSS( elem, prop );
+						// if curCSS returns percentage, fallback to offset
+						return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret;
+					}
+				}
+			};
+		});
+	}
+
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+	jQuery.expr.filters.hidden = function( elem ) {
+		return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none");
+	};
+
+	jQuery.expr.filters.visible = function( elem ) {
+		return !jQuery.expr.filters.hidden( elem );
+	};
+}
+
+// These hooks are used by animate to expand properties
+jQuery.each({
+	margin: "",
+	padding: "",
+	border: "Width"
+}, function( prefix, suffix ) {
+	jQuery.cssHooks[ prefix + suffix ] = {
+		expand: function( value ) {
+			var i,
+
+				// assumes a single number if not a string
+				parts = typeof value === "string" ? value.split(" ") : [ value ],
+				expanded = {};
+
+			for ( i = 0; i < 4; i++ ) {
+				expanded[ prefix + cssExpand[ i ] + suffix ] =
+					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
+			}
+
+			return expanded;
+		}
+	};
+
+	if ( !rmargin.test( prefix ) ) {
+		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
+	}
+});
+var r20 = /%20/g,
+	rbracket = /\[\]$/,
+	rCRLF = /\r?\n/g,
+	rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
+	rselectTextarea = /^(?:select|textarea)/i;
+
+jQuery.fn.extend({
+	serialize: function() {
+		return jQuery.param( this.serializeArray() );
+	},
+	serializeArray: function() {
+		return this.map(function(){
+			return this.elements ? jQuery.makeArray( this.elements ) : this;
+		})
+		.filter(function(){
+			return this.name && !this.disabled &&
+				( this.checked || rselectTextarea.test( this.nodeName ) ||
+					rinput.test( this.type ) );
+		})
+		.map(function( i, elem ){
+			var val = jQuery( this ).val();
+
+			return val == null ?
+				null :
+				jQuery.isArray( val ) ?
+					jQuery.map( val, function( val, i ){
+						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+					}) :
+					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+		}).get();
+	}
+});
+
+//Serialize an array of form elements or a set of
+//key/values into a query string
+jQuery.param = function( a, traditional ) {
+	var prefix,
+		s = [],
+		add = function( key, value ) {
+			// If value is a function, invoke it and return its value
+			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
+			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
+		};
+
+	// Set traditional to true for jQuery <= 1.3.2 behavior.
+	if ( traditional === undefined ) {
+		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
+	}
+
+	// If an array was passed in, assume that it is an array of form elements.
+	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+		// Serialize the form elements
+		jQuery.each( a, function() {
+			add( this.name, this.value );
+		});
+
+	} else {
+		// If traditional, encode the "old" way (the way 1.3.2 or older
+		// did it), otherwise encode params recursively.
+		for ( prefix in a ) {
+			buildParams( prefix, a[ prefix ], traditional, add );
+		}
+	}
+
+	// Return the resulting serialization
+	return s.join( "&" ).replace( r20, "+" );
+};
+
+function buildParams( prefix, obj, traditional, add ) {
+	var name;
+
+	if ( jQuery.isArray( obj ) ) {
+		// Serialize array item.
+		jQuery.each( obj, function( i, v ) {
+			if ( traditional || rbracket.test( prefix ) ) {
+				// Treat each array item as a scalar.
+				add( prefix, v );
+
+			} else {
+				// If array item is non-scalar (array or object), encode its
+				// numeric index to resolve deserialization ambiguity issues.
+				// Note that rack (as of 1.0.0) can't currently deserialize
+				// nested arrays properly, and attempting to do so may cause
+				// a server error. Possible fixes are to modify rack's
+				// deserialization algorithm or to provide an option or flag
+				// to force array serialization to be shallow.
+				buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
+			}
+		});
+
+	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
+		// Serialize object item.
+		for ( name in obj ) {
+			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+		}
+
+	} else {
+		// Serialize scalar item.
+		add( prefix, obj );
+	}
+}
+var
+	// Document location
+	ajaxLocParts,
+	ajaxLocation,
+
+	rhash = /#.*$/,
+	rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
+	// #7653, #8125, #8152: local protocol detection
+	rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
+	rnoContent = /^(?:GET|HEAD)$/,
+	rprotocol = /^\/\//,
+	rquery = /\?/,
+	rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
+	rts = /([?&])_=[^&]*/,
+	rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
+
+	// Keep a copy of the old load method
+	_load = jQuery.fn.load,
+
+	/* Prefilters
+	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
+	 * 2) These are called:
+	 *    - BEFORE asking for a transport
+	 *    - AFTER param serialization (s.data is a string if s.processData is true)
+	 * 3) key is the dataType
+	 * 4) the catchall symbol "*" can be used
+	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
+	 */
+	prefilters = {},
+
+	/* Transports bindings
+	 * 1) key is the dataType
+	 * 2) the catchall symbol "*" can be used
+	 * 3) selection will start with transport dataType and THEN go to "*" if needed
+	 */
+	transports = {},
+
+	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
+	allTypes = ["*/"] + ["*"];
+
+// #8138, IE may throw an exception when accessing
+// a field from window.location if document.domain has been set
+try {
+	ajaxLocation = location.href;
+} catch( e ) {
+	// Use the href attribute of an A element
+	// since IE will modify it given document.location
+	ajaxLocation = document.createElement( "a" );
+	ajaxLocation.href = "";
+	ajaxLocation = ajaxLocation.href;
+}
+
+// Segment location into parts
+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
+
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+function addToPrefiltersOrTransports( structure ) {
+
+	// dataTypeExpression is optional and defaults to "*"
+	return function( dataTypeExpression, func ) {
+
+		if ( typeof dataTypeExpression !== "string" ) {
+			func = dataTypeExpression;
+			dataTypeExpression = "*";
+		}
+
+		var dataType, list, placeBefore,
+			dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ),
+			i = 0,
+			length = dataTypes.length;
+
+		if ( jQuery.isFunction( func ) ) {
+			// For each dataType in the dataTypeExpression
+			for ( ; i < length; i++ ) {
+				dataType = dataTypes[ i ];
+				// We control if we're asked to add before
+				// any existing element
+				placeBefore = /^\+/.test( dataType );
+				if ( placeBefore ) {
+					dataType = dataType.substr( 1 ) || "*";
+				}
+				list = structure[ dataType ] = structure[ dataType ] || [];
+				// then we add to the structure accordingly
+				list[ placeBefore ? "unshift" : "push" ]( func );
+			}
+		}
+	};
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
+		dataType /* internal */, inspected /* internal */ ) {
+
+	dataType = dataType || options.dataTypes[ 0 ];
+	inspected = inspected || {};
+
+	inspected[ dataType ] = true;
+
+	var selection,
+		list = structure[ dataType ],
+		i = 0,
+		length = list ? list.length : 0,
+		executeOnly = ( structure === prefilters );
+
+	for ( ; i < length && ( executeOnly || !selection ); i++ ) {
+		selection = list[ i ]( options, originalOptions, jqXHR );
+		// If we got redirected to another dataType
+		// we try there if executing only and not done already
+		if ( typeof selection === "string" ) {
+			if ( !executeOnly || inspected[ selection ] ) {
+				selection = undefined;
+			} else {
+				options.dataTypes.unshift( selection );
+				selection = inspectPrefiltersOrTransports(
+						structure, options, originalOptions, jqXHR, selection, inspected );
+			}
+		}
+	}
+	// If we're only executing or nothing was selected
+	// we try the catchall dataType if not done already
+	if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
+		selection = inspectPrefiltersOrTransports(
+				structure, options, originalOptions, jqXHR, "*", inspected );
+	}
+	// unnecessary when only executing (prefilters)
+	// but it'll be ignored by the caller in that case
+	return selection;
+}
+
+// A special extend for ajax options
+// that takes "flat" options (not to be deep extended)
+// Fixes #9887
+function ajaxExtend( target, src ) {
+	var key, deep,
+		flatOptions = jQuery.ajaxSettings.flatOptions || {};
+	for ( key in src ) {
+		if ( src[ key ] !== undefined ) {
+			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
+		}
+	}
+	if ( deep ) {
+		jQuery.extend( true, target, deep );
+	}
+}
+
+jQuery.fn.load = function( url, params, callback ) {
+	if ( typeof url !== "string" && _load ) {
+		return _load.apply( this, arguments );
+	}
+
+	// Don't do a request if no elements are being requested
+	if ( !this.length ) {
+		return this;
+	}
+
+	var selector, type, response,
+		self = this,
+		off = url.indexOf(" ");
+
+	if ( off >= 0 ) {
+		selector = url.slice( off, url.length );
+		url = url.slice( 0, off );
+	}
+
+	// If it's a function
+	if ( jQuery.isFunction( params ) ) {
+
+		// We assume that it's the callback
+		callback = params;
+		params = undefined;
+
+	// Otherwise, build a param string
+	} else if ( params && typeof params === "object" ) {
+		type = "POST";
+	}
+
+	// Request the remote document
+	jQuery.ajax({
+		url: url,
+
+		// if "type" variable is undefined, then "GET" method will be used
+		type: type,
+		dataType: "html",
+		data: params,
+		complete: function( jqXHR, status ) {
+			if ( callback ) {
+				self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
+			}
+		}
+	}).done(function( responseText ) {
+
+		// Save response for use in complete callback
+		response = arguments;
+
+		// See if a selector was specified
+		self.html( selector ?
+
+			// Create a dummy div to hold the results
+			jQuery("<div>")
+
+				// inject the contents of the document in, removing the scripts
+				// to avoid any 'Permission Denied' errors in IE
+				.append( responseText.replace( rscript, "" ) )
+
+				// Locate the specified elements
+				.find( selector ) :
+
+			// If not, just inject the full result
+			responseText );
+
+	});
+
+	return this;
+};
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
+	jQuery.fn[ o ] = function( f ){
+		return this.on( o, f );
+	};
+});
+
+jQuery.each( [ "get", "post" ], function( i, method ) {
+	jQuery[ method ] = function( url, data, callback, type ) {
+		// shift arguments if data argument was omitted
+		if ( jQuery.isFunction( data ) ) {
+			type = type || callback;
+			callback = data;
+			data = undefined;
+		}
+
+		return jQuery.ajax({
+			type: method,
+			url: url,
+			data: data,
+			success: callback,
+			dataType: type
+		});
+	};
+});
+
+jQuery.extend({
+
+	getScript: function( url, callback ) {
+		return jQuery.get( url, undefined, callback, "script" );
+	},
+
+	getJSON: function( url, data, callback ) {
+		return jQuery.get( url, data, callback, "json" );
+	},
+
+	// Creates a full fledged settings object into target
+	// with both ajaxSettings and settings fields.
+	// If target is omitted, writes into ajaxSettings.
+	ajaxSetup: function( target, settings ) {
+		if ( settings ) {
+			// Building a settings object
+			ajaxExtend( target, jQuery.ajaxSettings );
+		} else {
+			// Extending ajaxSettings
+			settings = target;
+			target = jQuery.ajaxSettings;
+		}
+		ajaxExtend( target, settings );
+		return target;
+	},
+
+	ajaxSettings: {
+		url: ajaxLocation,
+		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
+		global: true,
+		type: "GET",
+		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+		processData: true,
+		async: true,
+		/*
+		timeout: 0,
+		data: null,
+		dataType: null,
+		username: null,
+		password: null,
+		cache: null,
+		throws: false,
+		traditional: false,
+		headers: {},
+		*/
+
+		accepts: {
+			xml: "application/xml, text/xml",
+			html: "text/html",
+			text: "text/plain",
+			json: "application/json, text/javascript",
+			"*": allTypes
+		},
+
+		contents: {
+			xml: /xml/,
+			html: /html/,
+			json: /json/
+		},
+
+		responseFields: {
+			xml: "responseXML",
+			text: "responseText"
+		},
+
+		// List of data converters
+		// 1) key format is "source_type destination_type" (a single space in-between)
+		// 2) the catchall symbol "*" can be used for source_type
+		converters: {
+
+			// Convert anything to text
+			"* text": window.String,
+
+			// Text to html (true = no transformation)
+			"text html": true,
+
+			// Evaluate text as a json expression
+			"text json": jQuery.parseJSON,
+
+			// Parse text as xml
+			"text xml": jQuery.parseXML
+		},
+
+		// For options that shouldn't be deep extended:
+		// you can add your own custom options here if
+		// and when you create one that shouldn't be
+		// deep extended (see ajaxExtend)
+		flatOptions: {
+			context: true,
+			url: true
+		}
+	},
+
+	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+	ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+	// Main method
+	ajax: function( url, options ) {
+
+		// If url is an object, simulate pre-1.5 signature
+		if ( typeof url === "object" ) {
+			options = url;
+			url = undefined;
+		}
+
+		// Force options to be an object
+		options = options || {};
+
+		var // ifModified key
+			ifModifiedKey,
+			// Response headers
+			responseHeadersString,
+			responseHeaders,
+			// transport
+			transport,
+			// timeout handle
+			timeoutTimer,
+			// Cross-domain detection vars
+			parts,
+			// To know if global events are to be dispatched
+			fireGlobals,
+			// Loop variable
+			i,
+			// Create the final options object
+			s = jQuery.ajaxSetup( {}, options ),
+			// Callbacks context
+			callbackContext = s.context || s,
+			// Context for global events
+			// It's the callbackContext if one was provided in the options
+			// and if it's a DOM node or a jQuery collection
+			globalEventContext = callbackContext !== s &&
+				( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
+						jQuery( callbackContext ) : jQuery.event,
+			// Deferreds
+			deferred = jQuery.Deferred(),
+			completeDeferred = jQuery.Callbacks( "once memory" ),
+			// Status-dependent callbacks
+			statusCode = s.statusCode || {},
+			// Headers (they are sent all at once)
+			requestHeaders = {},
+			requestHeadersNames = {},
+			// The jqXHR state
+			state = 0,
+			// Default abort message
+			strAbort = "canceled",
+			// Fake xhr
+			jqXHR = {
+
+				readyState: 0,
+
+				// Caches the header
+				setRequestHeader: function( name, value ) {
+					if ( !state ) {
+						var lname = name.toLowerCase();
+						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+						requestHeaders[ name ] = value;
+					}
+					return this;
+				},
+
+				// Raw string
+				getAllResponseHeaders: function() {
+					return state === 2 ? responseHeadersString : null;
+				},
+
+				// Builds headers hashtable if needed
+				getResponseHeader: function( key ) {
+					var match;
+					if ( state === 2 ) {
+						if ( !responseHeaders ) {
+							responseHeaders = {};
+							while( ( match = rheaders.exec( responseHeadersString ) ) ) {
+								responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
+							}
+						}
+						match = responseHeaders[ key.toLowerCase() ];
+					}
+					return match === undefined ? null : match;
+				},
+
+				// Overrides response content-type header
+				overrideMimeType: function( type ) {
+					if ( !state ) {
+						s.mimeType = type;
+					}
+					return this;
+				},
+
+				// Cancel the request
+				abort: function( statusText ) {
+					statusText = statusText || strAbort;
+					if ( transport ) {
+						transport.abort( statusText );
+					}
+					done( 0, statusText );
+					return this;
+				}
+			};
+
+		// Callback for when everything is done
+		// It is defined here because jslint complains if it is declared
+		// at the end of the function (which would be more logical and readable)
+		function done( status, nativeStatusText, responses, headers ) {
+			var isSuccess, success, error, response, modified,
+				statusText = nativeStatusText;
+
+			// Called once
+			if ( state === 2 ) {
+				return;
+			}
+
+			// State is "done" now
+			state = 2;
+
+			// Clear timeout if it exists
+			if ( timeoutTimer ) {
+				clearTimeout( timeoutTimer );
+			}
+
+			// Dereference transport for early garbage collection
+			// (no matter how long the jqXHR object will be used)
+			transport = undefined;
+
+			// Cache response headers
+			responseHeadersString = headers || "";
+
+			// Set readyState
+			jqXHR.readyState = status > 0 ? 4 : 0;
+
+			// Get response data
+			if ( responses ) {
+				response = ajaxHandleResponses( s, jqXHR, responses );
+			}
+
+			// If successful, handle type chaining
+			if ( status >= 200 && status < 300 || status === 304 ) {
+
+				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+				if ( s.ifModified ) {
+
+					modified = jqXHR.getResponseHeader("Last-Modified");
+					if ( modified ) {
+						jQuery.lastModified[ ifModifiedKey ] = modified;
+					}
+					modified = jqXHR.getResponseHeader("Etag");
+					if ( modified ) {
+						jQuery.etag[ ifModifiedKey ] = modified;
+					}
+				}
+
+				// If not modified
+				if ( status === 304 ) {
+
+					statusText = "notmodified";
+					isSuccess = true;
+
+				// If we have data
+				} else {
+
+					isSuccess = ajaxConvert( s, response );
+					statusText = isSuccess.state;
+					success = isSuccess.data;
+					error = isSuccess.error;
+					isSuccess = !error;
+				}
+			} else {
+				// We extract error from statusText
+				// then normalize statusText and status for non-aborts
+				error = statusText;
+				if ( !statusText || status ) {
+					statusText = "error";
+					if ( status < 0 ) {
+						status = 0;
+					}
+				}
+			}
+
+			// Set data for the fake xhr object
+			jqXHR.status = status;
+			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
+
+			// Success/Error
+			if ( isSuccess ) {
+				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+			} else {
+				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+			}
+
+			// Status-dependent callbacks
+			jqXHR.statusCode( statusCode );
+			statusCode = undefined;
+
+			if ( fireGlobals ) {
+				globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
+						[ jqXHR, s, isSuccess ? success : error ] );
+			}
+
+			// Complete
+			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
+
+			if ( fireGlobals ) {
+				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
+				// Handle the global AJAX counter
+				if ( !( --jQuery.active ) ) {
+					jQuery.event.trigger( "ajaxStop" );
+				}
+			}
+		}
+
+		// Attach deferreds
+		deferred.promise( jqXHR );
+		jqXHR.success = jqXHR.done;
+		jqXHR.error = jqXHR.fail;
+		jqXHR.complete = completeDeferred.add;
+
+		// Status-dependent callbacks
+		jqXHR.statusCode = function( map ) {
+			if ( map ) {
+				var tmp;
+				if ( state < 2 ) {
+					for ( tmp in map ) {
+						statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
+					}
+				} else {
+					tmp = map[ jqXHR.status ];
+					jqXHR.always( tmp );
+				}
+			}
+			return this;
+		};
+
+		// Remove hash character (#7531: and string promotion)
+		// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
+		// We also use the url parameter if available
+		s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
+
+		// Extract dataTypes list
+		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace );
+
+		// A cross-domain request is in order when we have a protocol:host:port mismatch
+		if ( s.crossDomain == null ) {
+			parts = rurl.exec( s.url.toLowerCase() );
+			s.crossDomain = !!( parts &&
+				( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
+					( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
+						( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
+			);
+		}
+
+		// Convert data if not already a string
+		if ( s.data && s.processData && typeof s.data !== "string" ) {
+			s.data = jQuery.param( s.data, s.traditional );
+		}
+
+		// Apply prefilters
+		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+		// If request was aborted inside a prefilter, stop there
+		if ( state === 2 ) {
+			return jqXHR;
+		}
+
+		// We can fire global events as of now if asked to
+		fireGlobals = s.global;
+
+		// Uppercase the type
+		s.type = s.type.toUpperCase();
+
+		// Determine if request has content
+		s.hasContent = !rnoContent.test( s.type );
+
+		// Watch for a new set of requests
+		if ( fireGlobals && jQuery.active++ === 0 ) {
+			jQuery.event.trigger( "ajaxStart" );
+		}
+
+		// More options handling for requests with no content
+		if ( !s.hasContent ) {
+
+			// If data is available, append data to url
+			if ( s.data ) {
+				s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
+				// #9682: remove data so that it's not used in an eventual retry
+				delete s.data;
+			}
+
+			// Get ifModifiedKey before adding the anti-cache parameter
+			ifModifiedKey = s.url;
+
+			// Add anti-cache in url if needed
+			if ( s.cache === false ) {
+
+				var ts = jQuery.now(),
+					// try replacing _= if it is there
+					ret = s.url.replace( rts, "$1_=" + ts );
+
+				// if nothing was replaced, add timestamp to the end
+				s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
+			}
+		}
+
+		// Set the correct header, if data is being sent
+		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+			jqXHR.setRequestHeader( "Content-Type", s.contentType );
+		}
+
+		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+		if ( s.ifModified ) {
+			ifModifiedKey = ifModifiedKey || s.url;
+			if ( jQuery.lastModified[ ifModifiedKey ] ) {
+				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
+			}
+			if ( jQuery.etag[ ifModifiedKey ] ) {
+				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
+			}
+		}
+
+		// Set the Accepts header for the server, depending on the dataType
+		jqXHR.setRequestHeader(
+			"Accept",
+			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
+				s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
+				s.accepts[ "*" ]
+		);
+
+		// Check for headers option
+		for ( i in s.headers ) {
+			jqXHR.setRequestHeader( i, s.headers[ i ] );
+		}
+
+		// Allow custom headers/mimetypes and early abort
+		if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
+				// Abort if not done already and return
+				return jqXHR.abort();
+
+		}
+
+		// aborting is no longer a cancellation
+		strAbort = "abort";
+
+		// Install callbacks on deferreds
+		for ( i in { success: 1, error: 1, complete: 1 } ) {
+			jqXHR[ i ]( s[ i ] );
+		}
+
+		// Get transport
+		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+		// If no transport, we auto-abort
+		if ( !transport ) {
+			done( -1, "No Transport" );
+		} else {
+			jqXHR.readyState = 1;
+			// Send global event
+			if ( fireGlobals ) {
+				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+			}
+			// Timeout
+			if ( s.async && s.timeout > 0 ) {
+				timeoutTimer = setTimeout( function(){
+					jqXHR.abort( "timeout" );
+				}, s.timeout );
+			}
+
+			try {
+				state = 1;
+				transport.send( requestHeaders, done );
+			} catch (e) {
+				// Propagate exception as error if not done
+				if ( state < 2 ) {
+					done( -1, e );
+				// Simply rethrow otherwise
+				} else {
+					throw e;
+				}
+			}
+		}
+
+		return jqXHR;
+	},
+
+	// Counter for holding the number of active queries
+	active: 0,
+
+	// Last-Modified header cache for next request
+	lastModified: {},
+	etag: {}
+
+});
+
+/* Handles responses to an ajax request:
+ * - sets all responseXXX fields accordingly
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+
+	var ct, type, finalDataType, firstDataType,
+		contents = s.contents,
+		dataTypes = s.dataTypes,
+		responseFields = s.responseFields;
+
+	// Fill responseXXX fields
+	for ( type in responseFields ) {
+		if ( type in responses ) {
+			jqXHR[ responseFields[type] ] = responses[ type ];
+		}
+	}
+
+	// Remove auto dataType and get content-type in the process
+	while( dataTypes[ 0 ] === "*" ) {
+		dataTypes.shift();
+		if ( ct === undefined ) {
+			ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
+		}
+	}
+
+	// Check if we're dealing with a known content-type
+	if ( ct ) {
+		for ( type in contents ) {
+			if ( contents[ type ] && contents[ type ].test( ct ) ) {
+				dataTypes.unshift( type );
+				break;
+			}
+		}
+	}
+
+	// Check to see if we have a response for the expected dataType
+	if ( dataTypes[ 0 ] in responses ) {
+		finalDataType = dataTypes[ 0 ];
+	} else {
+		// Try convertible dataTypes
+		for ( type in responses ) {
+			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
+				finalDataType = type;
+				break;
+			}
+			if ( !firstDataType ) {
+				firstDataType = type;
+			}
+		}
+		// Or just use first one
+		finalDataType = finalDataType || firstDataType;
+	}
+
+	// If we found a dataType
+	// We add the dataType to the list if needed
+	// and return the corresponding response
+	if ( finalDataType ) {
+		if ( finalDataType !== dataTypes[ 0 ] ) {
+			dataTypes.unshift( finalDataType );
+		}
+		return responses[ finalDataType ];
+	}
+}
+
+// Chain conversions given the request and the original response
+function ajaxConvert( s, response ) {
+
+	var conv, conv2, current, tmp,
+		// Work with a copy of dataTypes in case we need to modify it for conversion
+		dataTypes = s.dataTypes.slice(),
+		prev = dataTypes[ 0 ],
+		converters = {},
+		i = 0;
+
+	// Apply the dataFilter if provided
+	if ( s.dataFilter ) {
+		response = s.dataFilter( response, s.dataType );
+	}
+
+	// Create converters map with lowercased keys
+	if ( dataTypes[ 1 ] ) {
+		for ( conv in s.converters ) {
+			converters[ conv.toLowerCase() ] = s.converters[ conv ];
+		}
+	}
+
+	// Convert to each sequential dataType, tolerating list modification
+	for ( ; (current = dataTypes[++i]); ) {
+
+		// There's only work to do if current dataType is non-auto
+		if ( current !== "*" ) {
+
+			// Convert response if prev dataType is non-auto and differs from current
+			if ( prev !== "*" && prev !== current ) {
+
+				// Seek a direct converter
+				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
+
+				// If none found, seek a pair
+				if ( !conv ) {
+					for ( conv2 in converters ) {
+
+						// If conv2 outputs current
+						tmp = conv2.split(" ");
+						if ( tmp[ 1 ] === current ) {
+
+							// If prev can be converted to accepted input
+							conv = converters[ prev + " " + tmp[ 0 ] ] ||
+								converters[ "* " + tmp[ 0 ] ];
+							if ( conv ) {
+								// Condense equivalence converters
+								if ( conv === true ) {
+									conv = converters[ conv2 ];
+
+								// Otherwise, insert the intermediate dataType
+								} else if ( converters[ conv2 ] !== true ) {
+									current = tmp[ 0 ];
+									dataTypes.splice( i--, 0, current );
+								}
+
+								break;
+							}
+						}
+					}
+				}
+
+				// Apply converter (if not an equivalence)
+				if ( conv !== true ) {
+
+					// Unless errors are allowed to bubble, catch and return them
+					if ( conv && s["throws"] ) {
+						response = conv( response );
+					} else {
+						try {
+							response = conv( response );
+						} catch ( e ) {
+							return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
+						}
+					}
+				}
+			}
+
+			// Update prev for next iteration
+			prev = current;
+		}
+	}
+
+	return { state: "success", data: response };
+}
+var oldCallbacks = [],
+	rquestion = /\?/,
+	rjsonp = /(=)\?(?=&|$)|\?\?/,
+	nonce = jQuery.now();
+
+// Default jsonp settings
+jQuery.ajaxSetup({
+	jsonp: "callback",
+	jsonpCallback: function() {
+		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
+		this[ callback ] = true;
+		return callback;
+	}
+});
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+	var callbackName, overwritten, responseContainer,
+		data = s.data,
+		url = s.url,
+		hasCallback = s.jsonp !== false,
+		replaceInUrl = hasCallback && rjsonp.test( url ),
+		replaceInData = hasCallback && !replaceInUrl && typeof data === "string" &&
+			!( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") &&
+			rjsonp.test( data );
+
+	// Handle iff the expected data type is "jsonp" or we have a parameter to set
+	if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) {
+
+		// Get callback name, remembering preexisting value associated with it
+		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
+			s.jsonpCallback() :
+			s.jsonpCallback;
+		overwritten = window[ callbackName ];
+
+		// Insert callback into url or form data
+		if ( replaceInUrl ) {
+			s.url = url.replace( rjsonp, "$1" + callbackName );
+		} else if ( replaceInData ) {
+			s.data = data.replace( rjsonp, "$1" + callbackName );
+		} else if ( hasCallback ) {
+			s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
+		}
+
+		// Use data converter to retrieve json after script execution
+		s.converters["script json"] = function() {
+			if ( !responseContainer ) {
+				jQuery.error( callbackName + " was not called" );
+			}
+			return responseContainer[ 0 ];
+		};
+
+		// force json dataType
+		s.dataTypes[ 0 ] = "json";
+
+		// Install callback
+		window[ callbackName ] = function() {
+			responseContainer = arguments;
+		};
+
+		// Clean-up function (fires after converters)
+		jqXHR.always(function() {
+			// Restore preexisting value
+			window[ callbackName ] = overwritten;
+
+			// Save back as free
+			if ( s[ callbackName ] ) {
+				// make sure that re-using the options doesn't screw things around
+				s.jsonpCallback = originalSettings.jsonpCallback;
+
+				// save the callback name for future use
+				oldCallbacks.push( callbackName );
+			}
+
+			// Call if it was a function and we have a response
+			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
+				overwritten( responseContainer[ 0 ] );
+			}
+
+			responseContainer = overwritten = undefined;
+		});
+
+		// Delegate to script
+		return "script";
+	}
+});
+// Install script dataType
+jQuery.ajaxSetup({
+	accepts: {
+		script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
+	},
+	contents: {
+		script: /javascript|ecmascript/
+	},
+	converters: {
+		"text script": function( text ) {
+			jQuery.globalEval( text );
+			return text;
+		}
+	}
+});
+
+// Handle cache's special case and global
+jQuery.ajaxPrefilter( "script", function( s ) {
+	if ( s.cache === undefined ) {
+		s.cache = false;
+	}
+	if ( s.crossDomain ) {
+		s.type = "GET";
+		s.global = false;
+	}
+});
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function(s) {
+
+	// This transport only deals with cross domain requests
+	if ( s.crossDomain ) {
+
+		var script,
+			head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
+
+		return {
+
+			send: function( _, callback ) {
+
+				script = document.createElement( "script" );
+
+				script.async = "async";
+
+				if ( s.scriptCharset ) {
+					script.charset = s.scriptCharset;
+				}
+
+				script.src = s.url;
+
+				// Attach handlers for all browsers
+				script.onload = script.onreadystatechange = function( _, isAbort ) {
+
+					if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
+
+						// Handle memory leak in IE
+						script.onload = script.onreadystatechange = null;
+
+						// Remove the script
+						if ( head && script.parentNode ) {
+							head.removeChild( script );
+						}
+
+						// Dereference the script
+						script = undefined;
+
+						// Callback if not abort
+						if ( !isAbort ) {
+							callback( 200, "success" );
+						}
+					}
+				};
+				// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
+				// This arises when a base node is used (#2709 and #4378).
+				head.insertBefore( script, head.firstChild );
+			},
+
+			abort: function() {
+				if ( script ) {
+					script.onload( 0, 1 );
+				}
+			}
+		};
+	}
+});
+var xhrCallbacks,
+	// #5280: Internet Explorer will keep connections alive if we don't abort on unload
+	xhrOnUnloadAbort = window.ActiveXObject ? function() {
+		// Abort all pending requests
+		for ( var key in xhrCallbacks ) {
+			xhrCallbacks[ key ]( 0, 1 );
+		}
+	} : false,
+	xhrId = 0;
+
+// Functions to create xhrs
+function createStandardXHR() {
+	try {
+		return new window.XMLHttpRequest();
+	} catch( e ) {}
+}
+
+function createActiveXHR() {
+	try {
+		return new window.ActiveXObject( "Microsoft.XMLHTTP" );
+	} catch( e ) {}
+}
+
+// Create the request object
+// (This is still attached to ajaxSettings for backward compatibility)
+jQuery.ajaxSettings.xhr = window.ActiveXObject ?
+	/* Microsoft failed to properly
+	 * implement the XMLHttpRequest in IE7 (can't request local files),
+	 * so we use the ActiveXObject when it is available
+	 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+	 * we need a fallback.
+	 */
+	function() {
+		return !this.isLocal && createStandardXHR() || createActiveXHR();
+	} :
+	// For all other browsers, use the standard XMLHttpRequest object
+	createStandardXHR;
+
+// Determine support properties
+(function( xhr ) {
+	jQuery.extend( jQuery.support, {
+		ajax: !!xhr,
+		cors: !!xhr && ( "withCredentials" in xhr )
+	});
+})( jQuery.ajaxSettings.xhr() );
+
+// Create transport if the browser can provide an xhr
+if ( jQuery.support.ajax ) {
+
+	jQuery.ajaxTransport(function( s ) {
+		// Cross domain only allowed if supported through XMLHttpRequest
+		if ( !s.crossDomain || jQuery.support.cors ) {
+
+			var callback;
+
+			return {
+				send: function( headers, complete ) {
+
+					// Get a new xhr
+					var handle, i,
+						xhr = s.xhr();
+
+					// Open the socket
+					// Passing null username, generates a login popup on Opera (#2865)
+					if ( s.username ) {
+						xhr.open( s.type, s.url, s.async, s.username, s.password );
+					} else {
+						xhr.open( s.type, s.url, s.async );
+					}
+
+					// Apply custom fields if provided
+					if ( s.xhrFields ) {
+						for ( i in s.xhrFields ) {
+							xhr[ i ] = s.xhrFields[ i ];
+						}
+					}
+
+					// Override mime type if needed
+					if ( s.mimeType && xhr.overrideMimeType ) {
+						xhr.overrideMimeType( s.mimeType );
+					}
+
+					// X-Requested-With header
+					// For cross-domain requests, seeing as conditions for a preflight are
+					// akin to a jigsaw puzzle, we simply never set it to be sure.
+					// (it can always be set on a per-request basis or even using ajaxSetup)
+					// For same-domain requests, won't change header if already provided.
+					if ( !s.crossDomain && !headers["X-Requested-With"] ) {
+						headers[ "X-Requested-With" ] = "XMLHttpRequest";
+					}
+
+					// Need an extra try/catch for cross domain requests in Firefox 3
+					try {
+						for ( i in headers ) {
+							xhr.setRequestHeader( i, headers[ i ] );
+						}
+					} catch( _ ) {}
+
+					// Do send the request
+					// This may raise an exception which is actually
+					// handled in jQuery.ajax (so no try/catch here)
+					xhr.send( ( s.hasContent && s.data ) || null );
+
+					// Listener
+					callback = function( _, isAbort ) {
+
+						var status,
+							statusText,
+							responseHeaders,
+							responses,
+							xml;
+
+						// Firefox throws exceptions when accessing properties
+						// of an xhr when a network error occurred
+						// http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
+						try {
+
+							// Was never called and is aborted or complete
+							if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+
+								// Only called once
+								callback = undefined;
+
+								// Do not keep as active anymore
+								if ( handle ) {
+									xhr.onreadystatechange = jQuery.noop;
+									if ( xhrOnUnloadAbort ) {
+										delete xhrCallbacks[ handle ];
+									}
+								}
+
+								// If it's an abort
+								if ( isAbort ) {
+									// Abort it manually if needed
+									if ( xhr.readyState !== 4 ) {
+										xhr.abort();
+									}
+								} else {
+									status = xhr.status;
+									responseHeaders = xhr.getAllResponseHeaders();
+									responses = {};
+									xml = xhr.responseXML;
+
+									// Construct response list
+									if ( xml && xml.documentElement /* #4958 */ ) {
+										responses.xml = xml;
+									}
+
+									// When requesting binary data, IE6-9 will throw an exception
+									// on any attempt to access responseText (#11426)
+									try {
+										responses.text = xhr.responseText;
+									} catch( e ) {
+									}
+
+									// Firefox throws an exception when accessing
+									// statusText for faulty cross-domain requests
+									try {
+										statusText = xhr.statusText;
+									} catch( e ) {
+										// We normalize with Webkit giving an empty statusText
+										statusText = "";
+									}
+
+									// Filter status for non standard behaviors
+
+									// If the request is local and we have data: assume a success
+									// (success with no data won't get notified, that's the best we
+									// can do given current implementations)
+									if ( !status && s.isLocal && !s.crossDomain ) {
+										status = responses.text ? 200 : 404;
+									// IE - #1450: sometimes returns 1223 when it should be 204
+									} else if ( status === 1223 ) {
+										status = 204;
+									}
+								}
+							}
+						} catch( firefoxAccessException ) {
+							if ( !isAbort ) {
+								complete( -1, firefoxAccessException );
+							}
+						}
+
+						// Call complete if needed
+						if ( responses ) {
+							complete( status, statusText, responses, responseHeaders );
+						}
+					};
+
+					if ( !s.async ) {
+						// if we're in sync mode we fire the callback
+						callback();
+					} else if ( xhr.readyState === 4 ) {
+						// (IE6 & IE7) if it's in cache and has been
+						// retrieved directly we need to fire the callback
+						setTimeout( callback, 0 );
+					} else {
+						handle = ++xhrId;
+						if ( xhrOnUnloadAbort ) {
+							// Create the active xhrs callbacks list if needed
+							// and attach the unload handler
+							if ( !xhrCallbacks ) {
+								xhrCallbacks = {};
+								jQuery( window ).unload( xhrOnUnloadAbort );
+							}
+							// Add to list of active xhrs callbacks
+							xhrCallbacks[ handle ] = callback;
+						}
+						xhr.onreadystatechange = callback;
+					}
+				},
+
+				abort: function() {
+					if ( callback ) {
+						callback(0,1);
+					}
+				}
+			};
+		}
+	});
+}
+var fxNow, timerId,
+	rfxtypes = /^(?:toggle|show|hide)$/,
+	rfxnum = new RegExp( "^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
+	rrun = /queueHooks$/,
+	animationPrefilters = [ defaultPrefilter ],
+	tweeners = {
+		"*": [function( prop, value ) {
+			var end, unit,
+				tween = this.createTween( prop, value ),
+				parts = rfxnum.exec( value ),
+				target = tween.cur(),
+				start = +target || 0,
+				scale = 1,
+				maxIterations = 20;
+
+			if ( parts ) {
+				end = +parts[2];
+				unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" );
+
+				// We need to compute starting value
+				if ( unit !== "px" && start ) {
+					// Iteratively approximate from a nonzero starting point
+					// Prefer the current property, because this process will be trivial if it uses the same units
+					// Fallback to end or a simple constant
+					start = jQuery.css( tween.elem, prop, true ) || end || 1;
+
+					do {
+						// If previous iteration zeroed out, double until we get *something*
+						// Use a string for doubling factor so we don't accidentally see scale as unchanged below
+						scale = scale || ".5";
+
+						// Adjust and apply
+						start = start / scale;
+						jQuery.style( tween.elem, prop, start + unit );
+
+					// Update scale, tolerating zero or NaN from tween.cur()
+					// And breaking the loop if scale is unchanged or perfect, or if we've just had enough
+					} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
+				}
+
+				tween.unit = unit;
+				tween.start = start;
+				// If a +=/-= token was provided, we're doing a relative animation
+				tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end;
+			}
+			return tween;
+		}]
+	};
+
+// Animations created synchronously will run synchronously
+function createFxNow() {
+	setTimeout(function() {
+		fxNow = undefined;
+	}, 0 );
+	return ( fxNow = jQuery.now() );
+}
+
+function createTweens( animation, props ) {
+	jQuery.each( props, function( prop, value ) {
+		var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
+			index = 0,
+			length = collection.length;
+		for ( ; index < length; index++ ) {
+			if ( collection[ index ].call( animation, prop, value ) ) {
+
+				// we're done with this property
+				return;
+			}
+		}
+	});
+}
+
+function Animation( elem, properties, options ) {
+	var result,
+		index = 0,
+		tweenerIndex = 0,
+		length = animationPrefilters.length,
+		deferred = jQuery.Deferred().always( function() {
+			// don't match elem in the :animated selector
+			delete tick.elem;
+		}),
+		tick = function() {
+			var currentTime = fxNow || createFxNow(),
+				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
+				// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
+				temp = remaining / animation.duration || 0,
+				percent = 1 - temp,
+				index = 0,
+				length = animation.tweens.length;
+
+			for ( ; index < length ; index++ ) {
+				animation.tweens[ index ].run( percent );
+			}
+
+			deferred.notifyWith( elem, [ animation, percent, remaining ]);
+
+			if ( percent < 1 && length ) {
+				return remaining;
+			} else {
+				deferred.resolveWith( elem, [ animation ] );
+				return false;
+			}
+		},
+		animation = deferred.promise({
+			elem: elem,
+			props: jQuery.extend( {}, properties ),
+			opts: jQuery.extend( true, { specialEasing: {} }, options ),
+			originalProperties: properties,
+			originalOptions: options,
+			startTime: fxNow || createFxNow(),
+			duration: options.duration,
+			tweens: [],
+			createTween: function( prop, end, easing ) {
+				var tween = jQuery.Tween( elem, animation.opts, prop, end,
+						animation.opts.specialEasing[ prop ] || animation.opts.easing );
+				animation.tweens.push( tween );
+				return tween;
+			},
+			stop: function( gotoEnd ) {
+				var index = 0,
+					// if we are going to the end, we want to run all the tweens
+					// otherwise we skip this part
+					length = gotoEnd ? animation.tweens.length : 0;
+
+				for ( ; index < length ; index++ ) {
+					animation.tweens[ index ].run( 1 );
+				}
+
+				// resolve when we played the last frame
+				// otherwise, reject
+				if ( gotoEnd ) {
+					deferred.resolveWith( elem, [ animation, gotoEnd ] );
+				} else {
+					deferred.rejectWith( elem, [ animation, gotoEnd ] );
+				}
+				return this;
+			}
+		}),
+		props = animation.props;
+
+	propFilter( props, animation.opts.specialEasing );
+
+	for ( ; index < length ; index++ ) {
+		result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
+		if ( result ) {
+			return result;
+		}
+	}
+
+	createTweens( animation, props );
+
+	if ( jQuery.isFunction( animation.opts.start ) ) {
+		animation.opts.start.call( elem, animation );
+	}
+
+	jQuery.fx.timer(
+		jQuery.extend( tick, {
+			anim: animation,
+			queue: animation.opts.queue,
+			elem: elem
+		})
+	);
+
+	// attach callbacks from options
+	return animation.progress( animation.opts.progress )
+		.done( animation.opts.done, animation.opts.complete )
+		.fail( animation.opts.fail )
+		.always( animation.opts.always );
+}
+
+function propFilter( props, specialEasing ) {
+	var index, name, easing, value, hooks;
+
+	// camelCase, specialEasing and expand cssHook pass
+	for ( index in props ) {
+		name = jQuery.camelCase( index );
+		easing = specialEasing[ name ];
+		value = props[ index ];
+		if ( jQuery.isArray( value ) ) {
+			easing = value[ 1 ];
+			value = props[ index ] = value[ 0 ];
+		}
+
+		if ( index !== name ) {
+			props[ name ] = value;
+			delete props[ index ];
+		}
+
+		hooks = jQuery.cssHooks[ name ];
+		if ( hooks && "expand" in hooks ) {
+			value = hooks.expand( value );
+			delete props[ name ];
+
+			// not quite $.extend, this wont overwrite keys already present.
+			// also - reusing 'index' from above because we have the correct "name"
+			for ( index in value ) {
+				if ( !( index in props ) ) {
+					props[ index ] = value[ index ];
+					specialEasing[ index ] = easing;
+				}
+			}
+		} else {
+			specialEasing[ name ] = easing;
+		}
+	}
+}
+
+jQuery.Animation = jQuery.extend( Animation, {
+
+	tweener: function( props, callback ) {
+		if ( jQuery.isFunction( props ) ) {
+			callback = props;
+			props = [ "*" ];
+		} else {
+			props = props.split(" ");
+		}
+
+		var prop,
+			index = 0,
+			length = props.length;
+
+		for ( ; index < length ; index++ ) {
+			prop = props[ index ];
+			tweeners[ prop ] = tweeners[ prop ] || [];
+			tweeners[ prop ].unshift( callback );
+		}
+	},
+
+	prefilter: function( callback, prepend ) {
+		if ( prepend ) {
+			animationPrefilters.unshift( callback );
+		} else {
+			animationPrefilters.push( callback );
+		}
+	}
+});
+
+function defaultPrefilter( elem, props, opts ) {
+	var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire,
+		anim = this,
+		style = elem.style,
+		orig = {},
+		handled = [],
+		hidden = elem.nodeType && isHidden( elem );
+
+	// handle queue: false promises
+	if ( !opts.queue ) {
+		hooks = jQuery._queueHooks( elem, "fx" );
+		if ( hooks.unqueued == null ) {
+			hooks.unqueued = 0;
+			oldfire = hooks.empty.fire;
+			hooks.empty.fire = function() {
+				if ( !hooks.unqueued ) {
+					oldfire();
+				}
+			};
+		}
+		hooks.unqueued++;
+
+		anim.always(function() {
+			// doing this makes sure that the complete handler will be called
+			// before this completes
+			anim.always(function() {
+				hooks.unqueued--;
+				if ( !jQuery.queue( elem, "fx" ).length ) {
+					hooks.empty.fire();
+				}
+			});
+		});
+	}
+
+	// height/width overflow pass
+	if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
+		// Make sure that nothing sneaks out
+		// Record all 3 overflow attributes because IE does not
+		// change the overflow attribute when overflowX and
+		// overflowY are set to the same value
+		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
+
+		// Set display property to inline-block for height/width
+		// animations on inline elements that are having width/height animated
+		if ( jQuery.css( elem, "display" ) === "inline" &&
+				jQuery.css( elem, "float" ) === "none" ) {
+
+			// inline-level elements accept inline-block;
+			// block-level elements need to be inline with layout
+			if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) {
+				style.display = "inline-block";
+
+			} else {
+				style.zoom = 1;
+			}
+		}
+	}
+
+	if ( opts.overflow ) {
+		style.overflow = "hidden";
+		if ( !jQuery.support.shrinkWrapBlocks ) {
+			anim.done(function() {
+				style.overflow = opts.overflow[ 0 ];
+				style.overflowX = opts.overflow[ 1 ];
+				style.overflowY = opts.overflow[ 2 ];
+			});
+		}
+	}
+
+
+	// show/hide pass
+	for ( index in props ) {
+		value = props[ index ];
+		if ( rfxtypes.exec( value ) ) {
+			delete props[ index ];
+			toggle = toggle || value === "toggle";
+			if ( value === ( hidden ? "hide" : "show" ) ) {
+				continue;
+			}
+			handled.push( index );
+		}
+	}
+
+	length = handled.length;
+	if ( length ) {
+		dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} );
+		if ( "hidden" in dataShow ) {
+			hidden = dataShow.hidden;
+		}
+
+		// store state if its toggle - enables .stop().toggle() to "reverse"
+		if ( toggle ) {
+			dataShow.hidden = !hidden;
+		}
+		if ( hidden ) {
+			jQuery( elem ).show();
+		} else {
+			anim.done(function() {
+				jQuery( elem ).hide();
+			});
+		}
+		anim.done(function() {
+			var prop;
+			jQuery.removeData( elem, "fxshow", true );
+			for ( prop in orig ) {
+				jQuery.style( elem, prop, orig[ prop ] );
+			}
+		});
+		for ( index = 0 ; index < length ; index++ ) {
+			prop = handled[ index ];
+			tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 );
+			orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop );
+
+			if ( !( prop in dataShow ) ) {
+				dataShow[ prop ] = tween.start;
+				if ( hidden ) {
+					tween.end = tween.start;
+					tween.start = prop === "width" || prop === "height" ? 1 : 0;
+				}
+			}
+		}
+	}
+}
+
+function Tween( elem, options, prop, end, easing ) {
+	return new Tween.prototype.init( elem, options, prop, end, easing );
+}
+jQuery.Tween = Tween;
+
+Tween.prototype = {
+	constructor: Tween,
+	init: function( elem, options, prop, end, easing, unit ) {
+		this.elem = elem;
+		this.prop = prop;
+		this.easing = easing || "swing";
+		this.options = options;
+		this.start = this.now = this.cur();
+		this.end = end;
+		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
+	},
+	cur: function() {
+		var hooks = Tween.propHooks[ this.prop ];
+
+		return hooks && hooks.get ?
+			hooks.get( this ) :
+			Tween.propHooks._default.get( this );
+	},
+	run: function( percent ) {
+		var eased,
+			hooks = Tween.propHooks[ this.prop ];
+
+		if ( this.options.duration ) {
+			this.pos = eased = jQuery.easing[ this.easing ](
+				percent, this.options.duration * percent, 0, 1, this.options.duration
+			);
+		} else {
+			this.pos = eased = percent;
+		}
+		this.now = ( this.end - this.start ) * eased + this.start;
+
+		if ( this.options.step ) {
+			this.options.step.call( this.elem, this.now, this );
+		}
+
+		if ( hooks && hooks.set ) {
+			hooks.set( this );
+		} else {
+			Tween.propHooks._default.set( this );
+		}
+		return this;
+	}
+};
+
+Tween.prototype.init.prototype = Tween.prototype;
+
+Tween.propHooks = {
+	_default: {
+		get: function( tween ) {
+			var result;
+
+			if ( tween.elem[ tween.prop ] != null &&
+				(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
+				return tween.elem[ tween.prop ];
+			}
+
+			// passing any value as a 4th parameter to .css will automatically
+			// attempt a parseFloat and fallback to a string if the parse fails
+			// so, simple values such as "10px" are parsed to Float.
+			// complex values such as "rotate(1rad)" are returned as is.
+			result = jQuery.css( tween.elem, tween.prop, false, "" );
+			// Empty strings, null, undefined and "auto" are converted to 0.
+			return !result || result === "auto" ? 0 : result;
+		},
+		set: function( tween ) {
+			// use step hook for back compat - use cssHook if its there - use .style if its
+			// available and use plain properties where available
+			if ( jQuery.fx.step[ tween.prop ] ) {
+				jQuery.fx.step[ tween.prop ]( tween );
+			} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
+				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
+			} else {
+				tween.elem[ tween.prop ] = tween.now;
+			}
+		}
+	}
+};
+
+// Remove in 2.0 - this supports IE8's panic based approach
+// to setting things on disconnected nodes
+
+Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
+	set: function( tween ) {
+		if ( tween.elem.nodeType && tween.elem.parentNode ) {
+			tween.elem[ tween.prop ] = tween.now;
+		}
+	}
+};
+
+jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
+	var cssFn = jQuery.fn[ name ];
+	jQuery.fn[ name ] = function( speed, easing, callback ) {
+		return speed == null || typeof speed === "boolean" ||
+			// special check for .toggle( handler, handler, ... )
+			( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ?
+			cssFn.apply( this, arguments ) :
+			this.animate( genFx( name, true ), speed, easing, callback );
+	};
+});
+
+jQuery.fn.extend({
+	fadeTo: function( speed, to, easing, callback ) {
+
+		// show any hidden elements after setting opacity to 0
+		return this.filter( isHidden ).css( "opacity", 0 ).show()
+
+			// animate to the value specified
+			.end().animate({ opacity: to }, speed, easing, callback );
+	},
+	animate: function( prop, speed, easing, callback ) {
+		var empty = jQuery.isEmptyObject( prop ),
+			optall = jQuery.speed( speed, easing, callback ),
+			doAnimation = function() {
+				// Operate on a copy of prop so per-property easing won't be lost
+				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
+
+				// Empty animations resolve immediately
+				if ( empty ) {
+					anim.stop( true );
+				}
+			};
+
+		return empty || optall.queue === false ?
+			this.each( doAnimation ) :
+			this.queue( optall.queue, doAnimation );
+	},
+	stop: function( type, clearQueue, gotoEnd ) {
+		var stopQueue = function( hooks ) {
+			var stop = hooks.stop;
+			delete hooks.stop;
+			stop( gotoEnd );
+		};
+
+		if ( typeof type !== "string" ) {
+			gotoEnd = clearQueue;
+			clearQueue = type;
+			type = undefined;
+		}
+		if ( clearQueue && type !== false ) {
+			this.queue( type || "fx", [] );
+		}
+
+		return this.each(function() {
+			var dequeue = true,
+				index = type != null && type + "queueHooks",
+				timers = jQuery.timers,
+				data = jQuery._data( this );
+
+			if ( index ) {
+				if ( data[ index ] && data[ index ].stop ) {
+					stopQueue( data[ index ] );
+				}
+			} else {
+				for ( index in data ) {
+					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
+						stopQueue( data[ index ] );
+					}
+				}
+			}
+
+			for ( index = timers.length; index--; ) {
+				if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
+					timers[ index ].anim.stop( gotoEnd );
+					dequeue = false;
+					timers.splice( index, 1 );
+				}
+			}
+
+			// start the next in the queue if the last step wasn't forced
+			// timers currently will call their complete callbacks, which will dequeue
+			// but only if they were gotoEnd
+			if ( dequeue || !gotoEnd ) {
+				jQuery.dequeue( this, type );
+			}
+		});
+	}
+});
+
+// Generate parameters to create a standard animation
+function genFx( type, includeWidth ) {
+	var which,
+		attrs = { height: type },
+		i = 0;
+
+	// if we include width, step value is 1 to do all cssExpand values,
+	// if we don't include width, step value is 2 to skip over Left and Right
+	includeWidth = includeWidth? 1 : 0;
+	for( ; i < 4 ; i += 2 - includeWidth ) {
+		which = cssExpand[ i ];
+		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
+	}
+
+	if ( includeWidth ) {
+		attrs.opacity = attrs.width = type;
+	}
+
+	return attrs;
+}
+
+// Generate shortcuts for custom animations
+jQuery.each({
+	slideDown: genFx("show"),
+	slideUp: genFx("hide"),
+	slideToggle: genFx("toggle"),
+	fadeIn: { opacity: "show" },
+	fadeOut: { opacity: "hide" },
+	fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+	jQuery.fn[ name ] = function( speed, easing, callback ) {
+		return this.animate( props, speed, easing, callback );
+	};
+});
+
+jQuery.speed = function( speed, easing, fn ) {
+	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
+		complete: fn || !fn && easing ||
+			jQuery.isFunction( speed ) && speed,
+		duration: speed,
+		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
+	};
+
+	opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+		opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
+
+	// normalize opt.queue - true/undefined/null -> "fx"
+	if ( opt.queue == null || opt.queue === true ) {
+		opt.queue = "fx";
+	}
+
+	// Queueing
+	opt.old = opt.complete;
+
+	opt.complete = function() {
+		if ( jQuery.isFunction( opt.old ) ) {
+			opt.old.call( this );
+		}
+
+		if ( opt.queue ) {
+			jQuery.dequeue( this, opt.queue );
+		}
+	};
+
+	return opt;
+};
+
+jQuery.easing = {
+	linear: function( p ) {
+		return p;
+	},
+	swing: function( p ) {
+		return 0.5 - Math.cos( p*Math.PI ) / 2;
+	}
+};
+
+jQuery.timers = [];
+jQuery.fx = Tween.prototype.init;
+jQuery.fx.tick = function() {
+	var timer,
+		timers = jQuery.timers,
+		i = 0;
+
+	fxNow = jQuery.now();
+
+	for ( ; i < timers.length; i++ ) {
+		timer = timers[ i ];
+		// Checks the timer has not already been removed
+		if ( !timer() && timers[ i ] === timer ) {
+			timers.splice( i--, 1 );
+		}
+	}
+
+	if ( !timers.length ) {
+		jQuery.fx.stop();
+	}
+	fxNow = undefined;
+};
+
+jQuery.fx.timer = function( timer ) {
+	if ( timer() && jQuery.timers.push( timer ) && !timerId ) {
+		timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
+	}
+};
+
+jQuery.fx.interval = 13;
+
+jQuery.fx.stop = function() {
+	clearInterval( timerId );
+	timerId = null;
+};
+
+jQuery.fx.speeds = {
+	slow: 600,
+	fast: 200,
+	// Default speed
+	_default: 400
+};
+
+// Back Compat <1.8 extension point
+jQuery.fx.step = {};
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+	jQuery.expr.filters.animated = function( elem ) {
+		return jQuery.grep(jQuery.timers, function( fn ) {
+			return elem === fn.elem;
+		}).length;
+	};
+}
+var rroot = /^(?:body|html)$/i;
+
+jQuery.fn.offset = function( options ) {
+	if ( arguments.length ) {
+		return options === undefined ?
+			this :
+			this.each(function( i ) {
+				jQuery.offset.setOffset( this, options, i );
+			});
+	}
+
+	var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft,
+		box = { top: 0, left: 0 },
+		elem = this[ 0 ],
+		doc = elem && elem.ownerDocument;
+
+	if ( !doc ) {
+		return;
+	}
+
+	if ( (body = doc.body) === elem ) {
+		return jQuery.offset.bodyOffset( elem );
+	}
+
+	docElem = doc.documentElement;
+
+	// Make sure it's not a disconnected DOM node
+	if ( !jQuery.contains( docElem, elem ) ) {
+		return box;
+	}
+
+	// If we don't have gBCR, just use 0,0 rather than error
+	// BlackBerry 5, iOS 3 (original iPhone)
+	if ( typeof elem.getBoundingClientRect !== "undefined" ) {
+		box = elem.getBoundingClientRect();
+	}
+	win = getWindow( doc );
+	clientTop  = docElem.clientTop  || body.clientTop  || 0;
+	clientLeft = docElem.clientLeft || body.clientLeft || 0;
+	scrollTop  = win.pageYOffset || docElem.scrollTop;
+	scrollLeft = win.pageXOffset || docElem.scrollLeft;
+	return {
+		top: box.top  + scrollTop  - clientTop,
+		left: box.left + scrollLeft - clientLeft
+	};
+};
+
+jQuery.offset = {
+
+	bodyOffset: function( body ) {
+		var top = body.offsetTop,
+			left = body.offsetLeft;
+
+		if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {
+			top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
+			left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
+		}
+
+		return { top: top, left: left };
+	},
+
+	setOffset: function( elem, options, i ) {
+		var position = jQuery.css( elem, "position" );
+
+		// set position first, in-case top/left are set even on static elem
+		if ( position === "static" ) {
+			elem.style.position = "relative";
+		}
+
+		var curElem = jQuery( elem ),
+			curOffset = curElem.offset(),
+			curCSSTop = jQuery.css( elem, "top" ),
+			curCSSLeft = jQuery.css( elem, "left" ),
+			calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
+			props = {}, curPosition = {}, curTop, curLeft;
+
+		// need to be able to calculate position if either top or left is auto and position is either absolute or fixed
+		if ( calculatePosition ) {
+			curPosition = curElem.position();
+			curTop = curPosition.top;
+			curLeft = curPosition.left;
+		} else {
+			curTop = parseFloat( curCSSTop ) || 0;
+			curLeft = parseFloat( curCSSLeft ) || 0;
+		}
+
+		if ( jQuery.isFunction( options ) ) {
+			options = options.call( elem, i, curOffset );
+		}
+
+		if ( options.top != null ) {
+			props.top = ( options.top - curOffset.top ) + curTop;
+		}
+		if ( options.left != null ) {
+			props.left = ( options.left - curOffset.left ) + curLeft;
+		}
+
+		if ( "using" in options ) {
+			options.using.call( elem, props );
+		} else {
+			curElem.css( props );
+		}
+	}
+};
+
+
+jQuery.fn.extend({
+
+	position: function() {
+		if ( !this[0] ) {
+			return;
+		}
+
+		var elem = this[0],
+
+		// Get *real* offsetParent
+		offsetParent = this.offsetParent(),
+
+		// Get correct offsets
+		offset       = this.offset(),
+		parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+		// Subtract element margins
+		// note: when an element has margin: auto the offsetLeft and marginLeft
+		// are the same in Safari causing offset.left to incorrectly be 0
+		offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
+		offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
+
+		// Add offsetParent borders
+		parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
+		parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
+
+		// Subtract the two offsets
+		return {
+			top:  offset.top  - parentOffset.top,
+			left: offset.left - parentOffset.left
+		};
+	},
+
+	offsetParent: function() {
+		return this.map(function() {
+			var offsetParent = this.offsetParent || document.body;
+			while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
+				offsetParent = offsetParent.offsetParent;
+			}
+			return offsetParent || document.body;
+		});
+	}
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
+	var top = /Y/.test( prop );
+
+	jQuery.fn[ method ] = function( val ) {
+		return jQuery.access( this, function( elem, method, val ) {
+			var win = getWindow( elem );
+
+			if ( val === undefined ) {
+				return win ? (prop in win) ? win[ prop ] :
+					win.document.documentElement[ method ] :
+					elem[ method ];
+			}
+
+			if ( win ) {
+				win.scrollTo(
+					!top ? val : jQuery( win ).scrollLeft(),
+					 top ? val : jQuery( win ).scrollTop()
+				);
+
+			} else {
+				elem[ method ] = val;
+			}
+		}, method, val, arguments.length, null );
+	};
+});
+
+function getWindow( elem ) {
+	return jQuery.isWindow( elem ) ?
+		elem :
+		elem.nodeType === 9 ?
+			elem.defaultView || elem.parentWindow :
+			false;
+}
+// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
+jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
+	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
+		// margin is only for outerHeight, outerWidth
+		jQuery.fn[ funcName ] = function( margin, value ) {
+			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
+				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
+
+			return jQuery.access( this, function( elem, type, value ) {
+				var doc;
+
+				if ( jQuery.isWindow( elem ) ) {
+					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
+					// isn't a whole lot we can do. See pull request at this URL for discussion:
+					// https://github.com/jquery/jquery/pull/764
+					return elem.document.documentElement[ "client" + name ];
+				}
+
+				// Get document width or height
+				if ( elem.nodeType === 9 ) {
+					doc = elem.documentElement;
+
+					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
+					// unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
+					return Math.max(
+						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
+						elem.body[ "offset" + name ], doc[ "offset" + name ],
+						doc[ "client" + name ]
+					);
+				}
+
+				return value === undefined ?
+					// Get width or height on the element, requesting but not forcing parseFloat
+					jQuery.css( elem, type, value, extra ) :
+
+					// Set width or height on the element
+					jQuery.style( elem, type, value, extra );
+			}, type, chainable ? margin : undefined, chainable, null );
+		};
+	});
+});
+// Expose jQuery to the global object
+window.jQuery = window.$ = jQuery;
+
+// Expose jQuery as an AMD module, but only for AMD loaders that
+// understand the issues with loading multiple versions of jQuery
+// in a page that all might call define(). The loader will indicate
+// they have special allowances for multiple jQuery versions by
+// specifying define.amd.jQuery = true. Register as a named module,
+// since jQuery can be concatenated with other files that may use define,
+// but not use a proper concatenation script that understands anonymous
+// AMD modules. A named AMD is safest and most robust way to register.
+// Lowercase jquery is used because AMD module names are derived from
+// file names, and jQuery is normally delivered in a lowercase file name.
+// Do this after creating the global so that if an AMD module wants to call
+// noConflict to hide this version of jQuery, it will work.
+if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
+	define( "jquery", [], function () { return jQuery; } );
+}
+
+})( window );
diff --git a/sphinx/themes/basic/static/minus.png b/sphinx/themes/basic/static/minus.png
index da1c562..0f22b16 100644
--- a/sphinx/themes/basic/static/minus.png
+++ b/sphinx/themes/basic/static/minus.png
Binary files differ
diff --git a/sphinx/themes/basic/static/plus.png b/sphinx/themes/basic/static/plus.png
index b3cb374..0cfe084 100644
--- a/sphinx/themes/basic/static/plus.png
+++ b/sphinx/themes/basic/static/plus.png
Binary files differ
diff --git a/sphinx/themes/basic/static/underscore-1.3.1.js b/sphinx/themes/basic/static/underscore-1.3.1.js
new file mode 100644
index 0000000..208d4cd
--- /dev/null
+++ b/sphinx/themes/basic/static/underscore-1.3.1.js
@@ -0,0 +1,999 @@
+//     Underscore.js 1.3.1
+//     (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
+//     Underscore is freely distributable under the MIT license.
+//     Portions of Underscore are inspired or borrowed from Prototype,
+//     Oliver Steele's Functional, and John Resig's Micro-Templating.
+//     For all details and documentation:
+//     http://documentcloud.github.com/underscore
+
+(function() {
+
+  // Baseline setup
+  // --------------
+
+  // Establish the root object, `window` in the browser, or `global` on the server.
+  var root = this;
+
+  // Save the previous value of the `_` variable.
+  var previousUnderscore = root._;
+
+  // Establish the object that gets returned to break out of a loop iteration.
+  var breaker = {};
+
+  // Save bytes in the minified (but not gzipped) version:
+  var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
+
+  // Create quick reference variables for speed access to core prototypes.
+  var slice            = ArrayProto.slice,
+      unshift          = ArrayProto.unshift,
+      toString         = ObjProto.toString,
+      hasOwnProperty   = ObjProto.hasOwnProperty;
+
+  // All **ECMAScript 5** native function implementations that we hope to use
+  // are declared here.
+  var
+    nativeForEach      = ArrayProto.forEach,
+    nativeMap          = ArrayProto.map,
+    nativeReduce       = ArrayProto.reduce,
+    nativeReduceRight  = ArrayProto.reduceRight,
+    nativeFilter       = ArrayProto.filter,
+    nativeEvery        = ArrayProto.every,
+    nativeSome         = ArrayProto.some,
+    nativeIndexOf      = ArrayProto.indexOf,
+    nativeLastIndexOf  = ArrayProto.lastIndexOf,
+    nativeIsArray      = Array.isArray,
+    nativeKeys         = Object.keys,
+    nativeBind         = FuncProto.bind;
+
+  // Create a safe reference to the Underscore object for use below.
+  var _ = function(obj) { return new wrapper(obj); };
+
+  // Export the Underscore object for **Node.js**, with
+  // backwards-compatibility for the old `require()` API. If we're in
+  // the browser, add `_` as a global object via a string identifier,
+  // for Closure Compiler "advanced" mode.
+  if (typeof exports !== 'undefined') {
+    if (typeof module !== 'undefined' && module.exports) {
+      exports = module.exports = _;
+    }
+    exports._ = _;
+  } else {
+    root['_'] = _;
+  }
+
+  // Current version.
+  _.VERSION = '1.3.1';
+
+  // Collection Functions
+  // --------------------
+
+  // The cornerstone, an `each` implementation, aka `forEach`.
+  // Handles objects with the built-in `forEach`, arrays, and raw objects.
+  // Delegates to **ECMAScript 5**'s native `forEach` if available.
+  var each = _.each = _.forEach = function(obj, iterator, context) {
+    if (obj == null) return;
+    if (nativeForEach && obj.forEach === nativeForEach) {
+      obj.forEach(iterator, context);
+    } else if (obj.length === +obj.length) {
+      for (var i = 0, l = obj.length; i < l; i++) {
+        if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
+      }
+    } else {
+      for (var key in obj) {
+        if (_.has(obj, key)) {
+          if (iterator.call(context, obj[key], key, obj) === breaker) return;
+        }
+      }
+    }
+  };
+
+  // Return the results of applying the iterator to each element.
+  // Delegates to **ECMAScript 5**'s native `map` if available.
+  _.map = _.collect = function(obj, iterator, context) {
+    var results = [];
+    if (obj == null) return results;
+    if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
+    each(obj, function(value, index, list) {
+      results[results.length] = iterator.call(context, value, index, list);
+    });
+    if (obj.length === +obj.length) results.length = obj.length;
+    return results;
+  };
+
+  // **Reduce** builds up a single result from a list of values, aka `inject`,
+  // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
+  _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
+    var initial = arguments.length > 2;
+    if (obj == null) obj = [];
+    if (nativeReduce && obj.reduce === nativeReduce) {
+      if (context) iterator = _.bind(iterator, context);
+      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
+    }
+    each(obj, function(value, index, list) {
+      if (!initial) {
+        memo = value;
+        initial = true;
+      } else {
+        memo = iterator.call(context, memo, value, index, list);
+      }
+    });
+    if (!initial) throw new TypeError('Reduce of empty array with no initial value');
+    return memo;
+  };
+
+  // The right-associative version of reduce, also known as `foldr`.
+  // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
+  _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
+    var initial = arguments.length > 2;
+    if (obj == null) obj = [];
+    if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
+      if (context) iterator = _.bind(iterator, context);
+      return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
+    }
+    var reversed = _.toArray(obj).reverse();
+    if (context && !initial) iterator = _.bind(iterator, context);
+    return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);
+  };
+
+  // Return the first value which passes a truth test. Aliased as `detect`.
+  _.find = _.detect = function(obj, iterator, context) {
+    var result;
+    any(obj, function(value, index, list) {
+      if (iterator.call(context, value, index, list)) {
+        result = value;
+        return true;
+      }
+    });
+    return result;
+  };
+
+  // Return all the elements that pass a truth test.
+  // Delegates to **ECMAScript 5**'s native `filter` if available.
+  // Aliased as `select`.
+  _.filter = _.select = function(obj, iterator, context) {
+    var results = [];
+    if (obj == null) return results;
+    if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
+    each(obj, function(value, index, list) {
+      if (iterator.call(context, value, index, list)) results[results.length] = value;
+    });
+    return results;
+  };
+
+  // Return all the elements for which a truth test fails.
+  _.reject = function(obj, iterator, context) {
+    var results = [];
+    if (obj == null) return results;
+    each(obj, function(value, index, list) {
+      if (!iterator.call(context, value, index, list)) results[results.length] = value;
+    });
+    return results;
+  };
+
+  // Determine whether all of the elements match a truth test.
+  // Delegates to **ECMAScript 5**'s native `every` if available.
+  // Aliased as `all`.
+  _.every = _.all = function(obj, iterator, context) {
+    var result = true;
+    if (obj == null) return result;
+    if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
+    each(obj, function(value, index, list) {
+      if (!(result = result && iterator.call(context, value, index, list))) return breaker;
+    });
+    return result;
+  };
+
+  // Determine if at least one element in the object matches a truth test.
+  // Delegates to **ECMAScript 5**'s native `some` if available.
+  // Aliased as `any`.
+  var any = _.some = _.any = function(obj, iterator, context) {
+    iterator || (iterator = _.identity);
+    var result = false;
+    if (obj == null) return result;
+    if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
+    each(obj, function(value, index, list) {
+      if (result || (result = iterator.call(context, value, index, list))) return breaker;
+    });
+    return !!result;
+  };
+
+  // Determine if a given value is included in the array or object using `===`.
+  // Aliased as `contains`.
+  _.include = _.contains = function(obj, target) {
+    var found = false;
+    if (obj == null) return found;
+    if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
+    found = any(obj, function(value) {
+      return value === target;
+    });
+    return found;
+  };
+
+  // Invoke a method (with arguments) on every item in a collection.
+  _.invoke = function(obj, method) {
+    var args = slice.call(arguments, 2);
+    return _.map(obj, function(value) {
+      return (_.isFunction(method) ? method || value : value[method]).apply(value, args);
+    });
+  };
+
+  // Convenience version of a common use case of `map`: fetching a property.
+  _.pluck = function(obj, key) {
+    return _.map(obj, function(value){ return value[key]; });
+  };
+
+  // Return the maximum element or (element-based computation).
+  _.max = function(obj, iterator, context) {
+    if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
+    if (!iterator && _.isEmpty(obj)) return -Infinity;
+    var result = {computed : -Infinity};
+    each(obj, function(value, index, list) {
+      var computed = iterator ? iterator.call(context, value, index, list) : value;
+      computed >= result.computed && (result = {value : value, computed : computed});
+    });
+    return result.value;
+  };
+
+  // Return the minimum element (or element-based computation).
+  _.min = function(obj, iterator, context) {
+    if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
+    if (!iterator && _.isEmpty(obj)) return Infinity;
+    var result = {computed : Infinity};
+    each(obj, function(value, index, list) {
+      var computed = iterator ? iterator.call(context, value, index, list) : value;
+      computed < result.computed && (result = {value : value, computed : computed});
+    });
+    return result.value;
+  };
+
+  // Shuffle an array.
+  _.shuffle = function(obj) {
+    var shuffled = [], rand;
+    each(obj, function(value, index, list) {
+      if (index == 0) {
+        shuffled[0] = value;
+      } else {
+        rand = Math.floor(Math.random() * (index + 1));
+        shuffled[index] = shuffled[rand];
+        shuffled[rand] = value;
+      }
+    });
+    return shuffled;
+  };
+
+  // Sort the object's values by a criterion produced by an iterator.
+  _.sortBy = function(obj, iterator, context) {
+    return _.pluck(_.map(obj, function(value, index, list) {
+      return {
+        value : value,
+        criteria : iterator.call(context, value, index, list)
+      };
+    }).sort(function(left, right) {
+      var a = left.criteria, b = right.criteria;
+      return a < b ? -1 : a > b ? 1 : 0;
+    }), 'value');
+  };
+
+  // Groups the object's values by a criterion. Pass either a string attribute
+  // to group by, or a function that returns the criterion.
+  _.groupBy = function(obj, val) {
+    var result = {};
+    var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
+    each(obj, function(value, index) {
+      var key = iterator(value, index);
+      (result[key] || (result[key] = [])).push(value);
+    });
+    return result;
+  };
+
+  // Use a comparator function to figure out at what index an object should
+  // be inserted so as to maintain order. Uses binary search.
+  _.sortedIndex = function(array, obj, iterator) {
+    iterator || (iterator = _.identity);
+    var low = 0, high = array.length;
+    while (low < high) {
+      var mid = (low + high) >> 1;
+      iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
+    }
+    return low;
+  };
+
+  // Safely convert anything iterable into a real, live array.
+  _.toArray = function(iterable) {
+    if (!iterable)                return [];
+    if (iterable.toArray)         return iterable.toArray();
+    if (_.isArray(iterable))      return slice.call(iterable);
+    if (_.isArguments(iterable))  return slice.call(iterable);
+    return _.values(iterable);
+  };
+
+  // Return the number of elements in an object.
+  _.size = function(obj) {
+    return _.toArray(obj).length;
+  };
+
+  // Array Functions
+  // ---------------
+
+  // Get the first element of an array. Passing **n** will return the first N
+  // values in the array. Aliased as `head`. The **guard** check allows it to work
+  // with `_.map`.
+  _.first = _.head = function(array, n, guard) {
+    return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
+  };
+
+  // Returns everything but the last entry of the array. Especcialy useful on
+  // the arguments object. Passing **n** will return all the values in
+  // the array, excluding the last N. The **guard** check allows it to work with
+  // `_.map`.
+  _.initial = function(array, n, guard) {
+    return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
+  };
+
+  // Get the last element of an array. Passing **n** will return the last N
+  // values in the array. The **guard** check allows it to work with `_.map`.
+  _.last = function(array, n, guard) {
+    if ((n != null) && !guard) {
+      return slice.call(array, Math.max(array.length - n, 0));
+    } else {
+      return array[array.length - 1];
+    }
+  };
+
+  // Returns everything but the first entry of the array. Aliased as `tail`.
+  // Especially useful on the arguments object. Passing an **index** will return
+  // the rest of the values in the array from that index onward. The **guard**
+  // check allows it to work with `_.map`.
+  _.rest = _.tail = function(array, index, guard) {
+    return slice.call(array, (index == null) || guard ? 1 : index);
+  };
+
+  // Trim out all falsy values from an array.
+  _.compact = function(array) {
+    return _.filter(array, function(value){ return !!value; });
+  };
+
+  // Return a completely flattened version of an array.
+  _.flatten = function(array, shallow) {
+    return _.reduce(array, function(memo, value) {
+      if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
+      memo[memo.length] = value;
+      return memo;
+    }, []);
+  };
+
+  // Return a version of the array that does not contain the specified value(s).
+  _.without = function(array) {
+    return _.difference(array, slice.call(arguments, 1));
+  };
+
+  // Produce a duplicate-free version of the array. If the array has already
+  // been sorted, you have the option of using a faster algorithm.
+  // Aliased as `unique`.
+  _.uniq = _.unique = function(array, isSorted, iterator) {
+    var initial = iterator ? _.map(array, iterator) : array;
+    var result = [];
+    _.reduce(initial, function(memo, el, i) {
+      if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
+        memo[memo.length] = el;
+        result[result.length] = array[i];
+      }
+      return memo;
+    }, []);
+    return result;
+  };
+
+  // Produce an array that contains the union: each distinct element from all of
+  // the passed-in arrays.
+  _.union = function() {
+    return _.uniq(_.flatten(arguments, true));
+  };
+
+  // Produce an array that contains every item shared between all the
+  // passed-in arrays. (Aliased as "intersect" for back-compat.)
+  _.intersection = _.intersect = function(array) {
+    var rest = slice.call(arguments, 1);
+    return _.filter(_.uniq(array), function(item) {
+      return _.every(rest, function(other) {
+        return _.indexOf(other, item) >= 0;
+      });
+    });
+  };
+
+  // Take the difference between one array and a number of other arrays.
+  // Only the elements present in just the first array will remain.
+  _.difference = function(array) {
+    var rest = _.flatten(slice.call(arguments, 1));
+    return _.filter(array, function(value){ return !_.include(rest, value); });
+  };
+
+  // Zip together multiple lists into a single array -- elements that share
+  // an index go together.
+  _.zip = function() {
+    var args = slice.call(arguments);
+    var length = _.max(_.pluck(args, 'length'));
+    var results = new Array(length);
+    for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
+    return results;
+  };
+
+  // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
+  // we need this function. Return the position of the first occurrence of an
+  // item in an array, or -1 if the item is not included in the array.
+  // Delegates to **ECMAScript 5**'s native `indexOf` if available.
+  // If the array is large and already in sort order, pass `true`
+  // for **isSorted** to use binary search.
+  _.indexOf = function(array, item, isSorted) {
+    if (array == null) return -1;
+    var i, l;
+    if (isSorted) {
+      i = _.sortedIndex(array, item);
+      return array[i] === item ? i : -1;
+    }
+    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
+    for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;
+    return -1;
+  };
+
+  // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
+  _.lastIndexOf = function(array, item) {
+    if (array == null) return -1;
+    if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
+    var i = array.length;
+    while (i--) if (i in array && array[i] === item) return i;
+    return -1;
+  };
+
+  // Generate an integer Array containing an arithmetic progression. A port of
+  // the native Python `range()` function. See
+  // [the Python documentation](http://docs.python.org/library/functions.html#range).
+  _.range = function(start, stop, step) {
+    if (arguments.length <= 1) {
+      stop = start || 0;
+      start = 0;
+    }
+    step = arguments[2] || 1;
+
+    var len = Math.max(Math.ceil((stop - start) / step), 0);
+    var idx = 0;
+    var range = new Array(len);
+
+    while(idx < len) {
+      range[idx++] = start;
+      start += step;
+    }
+
+    return range;
+  };
+
+  // Function (ahem) Functions
+  // ------------------
+
+  // Reusable constructor function for prototype setting.
+  var ctor = function(){};
+
+  // Create a function bound to a given object (assigning `this`, and arguments,
+  // optionally). Binding with arguments is also known as `curry`.
+  // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
+  // We check for `func.bind` first, to fail fast when `func` is undefined.
+  _.bind = function bind(func, context) {
+    var bound, args;
+    if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
+    if (!_.isFunction(func)) throw new TypeError;
+    args = slice.call(arguments, 2);
+    return bound = function() {
+      if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
+      ctor.prototype = func.prototype;
+      var self = new ctor;
+      var result = func.apply(self, args.concat(slice.call(arguments)));
+      if (Object(result) === result) return result;
+      return self;
+    };
+  };
+
+  // Bind all of an object's methods to that object. Useful for ensuring that
+  // all callbacks defined on an object belong to it.
+  _.bindAll = function(obj) {
+    var funcs = slice.call(arguments, 1);
+    if (funcs.length == 0) funcs = _.functions(obj);
+    each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
+    return obj;
+  };
+
+  // Memoize an expensive function by storing its results.
+  _.memoize = function(func, hasher) {
+    var memo = {};
+    hasher || (hasher = _.identity);
+    return function() {
+      var key = hasher.apply(this, arguments);
+      return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
+    };
+  };
+
+  // Delays a function for the given number of milliseconds, and then calls
+  // it with the arguments supplied.
+  _.delay = function(func, wait) {
+    var args = slice.call(arguments, 2);
+    return setTimeout(function(){ return func.apply(func, args); }, wait);
+  };
+
+  // Defers a function, scheduling it to run after the current call stack has
+  // cleared.
+  _.defer = function(func) {
+    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
+  };
+
+  // Returns a function, that, when invoked, will only be triggered at most once
+  // during a given window of time.
+  _.throttle = function(func, wait) {
+    var context, args, timeout, throttling, more;
+    var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
+    return function() {
+      context = this; args = arguments;
+      var later = function() {
+        timeout = null;
+        if (more) func.apply(context, args);
+        whenDone();
+      };
+      if (!timeout) timeout = setTimeout(later, wait);
+      if (throttling) {
+        more = true;
+      } else {
+        func.apply(context, args);
+      }
+      whenDone();
+      throttling = true;
+    };
+  };
+
+  // Returns a function, that, as long as it continues to be invoked, will not
+  // be triggered. The function will be called after it stops being called for
+  // N milliseconds.
+  _.debounce = function(func, wait) {
+    var timeout;
+    return function() {
+      var context = this, args = arguments;
+      var later = function() {
+        timeout = null;
+        func.apply(context, args);
+      };
+      clearTimeout(timeout);
+      timeout = setTimeout(later, wait);
+    };
+  };
+
+  // Returns a function that will be executed at most one time, no matter how
+  // often you call it. Useful for lazy initialization.
+  _.once = function(func) {
+    var ran = false, memo;
+    return function() {
+      if (ran) return memo;
+      ran = true;
+      return memo = func.apply(this, arguments);
+    };
+  };
+
+  // Returns the first function passed as an argument to the second,
+  // allowing you to adjust arguments, run code before and after, and
+  // conditionally execute the original function.
+  _.wrap = function(func, wrapper) {
+    return function() {
+      var args = [func].concat(slice.call(arguments, 0));
+      return wrapper.apply(this, args);
+    };
+  };
+
+  // Returns a function that is the composition of a list of functions, each
+  // consuming the return value of the function that follows.
+  _.compose = function() {
+    var funcs = arguments;
+    return function() {
+      var args = arguments;
+      for (var i = funcs.length - 1; i >= 0; i--) {
+        args = [funcs[i].apply(this, args)];
+      }
+      return args[0];
+    };
+  };
+
+  // Returns a function that will only be executed after being called N times.
+  _.after = function(times, func) {
+    if (times <= 0) return func();
+    return function() {
+      if (--times < 1) { return func.apply(this, arguments); }
+    };
+  };
+
+  // Object Functions
+  // ----------------
+
+  // Retrieve the names of an object's properties.
+  // Delegates to **ECMAScript 5**'s native `Object.keys`
+  _.keys = nativeKeys || function(obj) {
+    if (obj !== Object(obj)) throw new TypeError('Invalid object');
+    var keys = [];
+    for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
+    return keys;
+  };
+
+  // Retrieve the values of an object's properties.
+  _.values = function(obj) {
+    return _.map(obj, _.identity);
+  };
+
+  // Return a sorted list of the function names available on the object.
+  // Aliased as `methods`
+  _.functions = _.methods = function(obj) {
+    var names = [];
+    for (var key in obj) {
+      if (_.isFunction(obj[key])) names.push(key);
+    }
+    return names.sort();
+  };
+
+  // Extend a given object with all the properties in passed-in object(s).
+  _.extend = function(obj) {
+    each(slice.call(arguments, 1), function(source) {
+      for (var prop in source) {
+        obj[prop] = source[prop];
+      }
+    });
+    return obj;
+  };
+
+  // Fill in a given object with default properties.
+  _.defaults = function(obj) {
+    each(slice.call(arguments, 1), function(source) {
+      for (var prop in source) {
+        if (obj[prop] == null) obj[prop] = source[prop];
+      }
+    });
+    return obj;
+  };
+
+  // Create a (shallow-cloned) duplicate of an object.
+  _.clone = function(obj) {
+    if (!_.isObject(obj)) return obj;
+    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
+  };
+
+  // Invokes interceptor with the obj, and then returns obj.
+  // The primary purpose of this method is to "tap into" a method chain, in
+  // order to perform operations on intermediate results within the chain.
+  _.tap = function(obj, interceptor) {
+    interceptor(obj);
+    return obj;
+  };
+
+  // Internal recursive comparison function.
+  function eq(a, b, stack) {
+    // Identical objects are equal. `0 === -0`, but they aren't identical.
+    // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
+    if (a === b) return a !== 0 || 1 / a == 1 / b;
+    // A strict comparison is necessary because `null == undefined`.
+    if (a == null || b == null) return a === b;
+    // Unwrap any wrapped objects.
+    if (a._chain) a = a._wrapped;
+    if (b._chain) b = b._wrapped;
+    // Invoke a custom `isEqual` method if one is provided.
+    if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);
+    if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);
+    // Compare `[[Class]]` names.
+    var className = toString.call(a);
+    if (className != toString.call(b)) return false;
+    switch (className) {
+      // Strings, numbers, dates, and booleans are compared by value.
+      case '[object String]':
+        // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
+        // equivalent to `new String("5")`.
+        return a == String(b);
+      case '[object Number]':
+        // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
+        // other numeric values.
+        return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
+      case '[object Date]':
+      case '[object Boolean]':
+        // Coerce dates and booleans to numeric primitive values. Dates are compared by their
+        // millisecond representations. Note that invalid dates with millisecond representations
+        // of `NaN` are not equivalent.
+        return +a == +b;
+      // RegExps are compared by their source patterns and flags.
+      case '[object RegExp]':
+        return a.source == b.source &&
+               a.global == b.global &&
+               a.multiline == b.multiline &&
+               a.ignoreCase == b.ignoreCase;
+    }
+    if (typeof a != 'object' || typeof b != 'object') return false;
+    // Assume equality for cyclic structures. The algorithm for detecting cyclic
+    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+    var length = stack.length;
+    while (length--) {
+      // Linear search. Performance is inversely proportional to the number of
+      // unique nested structures.
+      if (stack[length] == a) return true;
+    }
+    // Add the first object to the stack of traversed objects.
+    stack.push(a);
+    var size = 0, result = true;
+    // Recursively compare objects and arrays.
+    if (className == '[object Array]') {
+      // Compare array lengths to determine if a deep comparison is necessary.
+      size = a.length;
+      result = size == b.length;
+      if (result) {
+        // Deep compare the contents, ignoring non-numeric properties.
+        while (size--) {
+          // Ensure commutative equality for sparse arrays.
+          if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
+        }
+      }
+    } else {
+      // Objects with different constructors are not equivalent.
+      if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;
+      // Deep compare objects.
+      for (var key in a) {
+        if (_.has(a, key)) {
+          // Count the expected number of properties.
+          size++;
+          // Deep compare each member.
+          if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break;
+        }
+      }
+      // Ensure that both objects contain the same number of properties.
+      if (result) {
+        for (key in b) {
+          if (_.has(b, key) && !(size--)) break;
+        }
+        result = !size;
+      }
+    }
+    // Remove the first object from the stack of traversed objects.
+    stack.pop();
+    return result;
+  }
+
+  // Perform a deep comparison to check if two objects are equal.
+  _.isEqual = function(a, b) {
+    return eq(a, b, []);
+  };
+
+  // Is a given array, string, or object empty?
+  // An "empty" object has no enumerable own-properties.
+  _.isEmpty = function(obj) {
+    if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
+    for (var key in obj) if (_.has(obj, key)) return false;
+    return true;
+  };
+
+  // Is a given value a DOM element?
+  _.isElement = function(obj) {
+    return !!(obj && obj.nodeType == 1);
+  };
+
+  // Is a given value an array?
+  // Delegates to ECMA5's native Array.isArray
+  _.isArray = nativeIsArray || function(obj) {
+    return toString.call(obj) == '[object Array]';
+  };
+
+  // Is a given variable an object?
+  _.isObject = function(obj) {
+    return obj === Object(obj);
+  };
+
+  // Is a given variable an arguments object?
+  _.isArguments = function(obj) {
+    return toString.call(obj) == '[object Arguments]';
+  };
+  if (!_.isArguments(arguments)) {
+    _.isArguments = function(obj) {
+      return !!(obj && _.has(obj, 'callee'));
+    };
+  }
+
+  // Is a given value a function?
+  _.isFunction = function(obj) {
+    return toString.call(obj) == '[object Function]';
+  };
+
+  // Is a given value a string?
+  _.isString = function(obj) {
+    return toString.call(obj) == '[object String]';
+  };
+
+  // Is a given value a number?
+  _.isNumber = function(obj) {
+    return toString.call(obj) == '[object Number]';
+  };
+
+  // Is the given value `NaN`?
+  _.isNaN = function(obj) {
+    // `NaN` is the only value for which `===` is not reflexive.
+    return obj !== obj;
+  };
+
+  // Is a given value a boolean?
+  _.isBoolean = function(obj) {
+    return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
+  };
+
+  // Is a given value a date?
+  _.isDate = function(obj) {
+    return toString.call(obj) == '[object Date]';
+  };
+
+  // Is the given value a regular expression?
+  _.isRegExp = function(obj) {
+    return toString.call(obj) == '[object RegExp]';
+  };
+
+  // Is a given value equal to null?
+  _.isNull = function(obj) {
+    return obj === null;
+  };
+
+  // Is a given variable undefined?
+  _.isUndefined = function(obj) {
+    return obj === void 0;
+  };
+
+  // Has own property?
+  _.has = function(obj, key) {
+    return hasOwnProperty.call(obj, key);
+  };
+
+  // Utility Functions
+  // -----------------
+
+  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
+  // previous owner. Returns a reference to the Underscore object.
+  _.noConflict = function() {
+    root._ = previousUnderscore;
+    return this;
+  };
+
+  // Keep the identity function around for default iterators.
+  _.identity = function(value) {
+    return value;
+  };
+
+  // Run a function **n** times.
+  _.times = function (n, iterator, context) {
+    for (var i = 0; i < n; i++) iterator.call(context, i);
+  };
+
+  // Escape a string for HTML interpolation.
+  _.escape = function(string) {
+    return (''+string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
+  };
+
+  // Add your own custom functions to the Underscore object, ensuring that
+  // they're correctly added to the OOP wrapper as well.
+  _.mixin = function(obj) {
+    each(_.functions(obj), function(name){
+      addToWrapper(name, _[name] = obj[name]);
+    });
+  };
+
+  // Generate a unique integer id (unique within the entire client session).
+  // Useful for temporary DOM ids.
+  var idCounter = 0;
+  _.uniqueId = function(prefix) {
+    var id = idCounter++;
+    return prefix ? prefix + id : id;
+  };
+
+  // By default, Underscore uses ERB-style template delimiters, change the
+  // following template settings to use alternative delimiters.
+  _.templateSettings = {
+    evaluate    : /<%([\s\S]+?)%>/g,
+    interpolate : /<%=([\s\S]+?)%>/g,
+    escape      : /<%-([\s\S]+?)%>/g
+  };
+
+  // When customizing `templateSettings`, if you don't want to define an
+  // interpolation, evaluation or escaping regex, we need one that is
+  // guaranteed not to match.
+  var noMatch = /.^/;
+
+  // Within an interpolation, evaluation, or escaping, remove HTML escaping
+  // that had been previously added.
+  var unescape = function(code) {
+    return code.replace(/\\\\/g, '\\').replace(/\\'/g, "'");
+  };
+
+  // JavaScript micro-templating, similar to John Resig's implementation.
+  // Underscore templating handles arbitrary delimiters, preserves whitespace,
+  // and correctly escapes quotes within interpolated code.
+  _.template = function(str, data) {
+    var c  = _.templateSettings;
+    var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
+      'with(obj||{}){__p.push(\'' +
+      str.replace(/\\/g, '\\\\')
+         .replace(/'/g, "\\'")
+         .replace(c.escape || noMatch, function(match, code) {
+           return "',_.escape(" + unescape(code) + "),'";
+         })
+         .replace(c.interpolate || noMatch, function(match, code) {
+           return "'," + unescape(code) + ",'";
+         })
+         .replace(c.evaluate || noMatch, function(match, code) {
+           return "');" + unescape(code).replace(/[\r\n\t]/g, ' ') + ";__p.push('";
+         })
+         .replace(/\r/g, '\\r')
+         .replace(/\n/g, '\\n')
+         .replace(/\t/g, '\\t')
+         + "');}return __p.join('');";
+    var func = new Function('obj', '_', tmpl);
+    if (data) return func(data, _);
+    return function(data) {
+      return func.call(this, data, _);
+    };
+  };
+
+  // Add a "chain" function, which will delegate to the wrapper.
+  _.chain = function(obj) {
+    return _(obj).chain();
+  };
+
+  // The OOP Wrapper
+  // ---------------
+
+  // If Underscore is called as a function, it returns a wrapped object that
+  // can be used OO-style. This wrapper holds altered versions of all the
+  // underscore functions. Wrapped objects may be chained.
+  var wrapper = function(obj) { this._wrapped = obj; };
+
+  // Expose `wrapper.prototype` as `_.prototype`
+  _.prototype = wrapper.prototype;
+
+  // Helper function to continue chaining intermediate results.
+  var result = function(obj, chain) {
+    return chain ? _(obj).chain() : obj;
+  };
+
+  // A method to easily add functions to the OOP wrapper.
+  var addToWrapper = function(name, func) {
+    wrapper.prototype[name] = function() {
+      var args = slice.call(arguments);
+      unshift.call(args, this._wrapped);
+      return result(func.apply(_, args), this._chain);
+    };
+  };
+
+  // Add all of the Underscore functions to the wrapper object.
+  _.mixin(_);
+
+  // Add all mutator Array functions to the wrapper.
+  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
+    var method = ArrayProto[name];
+    wrapper.prototype[name] = function() {
+      var wrapped = this._wrapped;
+      method.apply(wrapped, arguments);
+      var length = wrapped.length;
+      if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];
+      return result(wrapped, this._chain);
+    };
+  });
+
+  // Add all accessor Array functions to the wrapper.
+  each(['concat', 'join', 'slice'], function(name) {
+    var method = ArrayProto[name];
+    wrapper.prototype[name] = function() {
+      return result(method.apply(this._wrapped, arguments), this._chain);
+    };
+  });
+
+  // Start chaining a wrapped Underscore object.
+  wrapper.prototype.chain = function() {
+    this._chain = true;
+    return this;
+  };
+
+  // Extracts the result from a wrapped and chained object.
+  wrapper.prototype.value = function() {
+    return this._wrapped;
+  };
+
+}).call(this);
diff --git a/sphinx/themes/basic/static/up-pressed.png b/sphinx/themes/basic/static/up-pressed.png
index 8bd587a..99e7210 100644
--- a/sphinx/themes/basic/static/up-pressed.png
+++ b/sphinx/themes/basic/static/up-pressed.png
Binary files differ
diff --git a/sphinx/themes/basic/static/up.png b/sphinx/themes/basic/static/up.png
index b946256..26de002 100644
--- a/sphinx/themes/basic/static/up.png
+++ b/sphinx/themes/basic/static/up.png
Binary files differ
diff --git a/sphinx/themes/basic/static/websupport.js b/sphinx/themes/basic/static/websupport.js
index 71c0a13..9932afb 100644
--- a/sphinx/themes/basic/static/websupport.js
+++ b/sphinx/themes/basic/static/websupport.js
@@ -700,8 +700,8 @@
         (<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\
       <div class="comment-markup-box" id="mb<%id%>">\
         reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \
-        <tt>``code``</tt>, \
-        code blocks: <tt>::</tt> and an indented block after blank line</div>\
+        <code>``code``</code>, \
+        code blocks: <code>::</code> and an indented block after blank line</div>\
       <form method="post" id="cf<%id%>" class="comment-form" action="">\
         <textarea name="comment" cols="80"></textarea>\
         <p class="propose-button">\
diff --git a/sphinx/themes/bizstyle/layout.html b/sphinx/themes/bizstyle/layout.html
new file mode 100644
index 0000000..de2754f
--- /dev/null
+++ b/sphinx/themes/bizstyle/layout.html
@@ -0,0 +1,28 @@
+{#
+    bizstyle/layout.html
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Sphinx layout template for the bizstyle theme.
+
+    :copyright: Copyright 2011-2014 by Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+#}
+{% extends "basic/layout.html" %}
+
+{% set script_files = script_files + ["_static/bizstyle.js"] %}
+
+{# put the sidebar before the body #}
+{% block sidebar1 %}{{ sidebar() }}{% endblock %}
+{% block sidebar2 %}{% endblock %}
+
+{# doctype override #}
+{%- block doctype %}
+<!doctype html>
+{%- endblock %}
+
+{%- block extrahead %}
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+    <!--[if lt IE 9]>
+    <script type="text/javascript" src="_static/css3-mediaqueries.js"></script>
+    <![endif]-->
+{%- endblock %}
diff --git a/sphinx/themes/bizstyle/static/background_b01.png b/sphinx/themes/bizstyle/static/background_b01.png
new file mode 100644
index 0000000..d262745
--- /dev/null
+++ b/sphinx/themes/bizstyle/static/background_b01.png
Binary files differ
diff --git a/sphinx/themes/bizstyle/static/bizstyle.css_t b/sphinx/themes/bizstyle/static/bizstyle.css_t
new file mode 100644
index 0000000..80b6dfe
--- /dev/null
+++ b/sphinx/themes/bizstyle/static/bizstyle.css_t
@@ -0,0 +1,487 @@
+/*
+ * bizstyle.css_t
+ * ~~~~~~~~~~~~~~
+ *
+ * Sphinx stylesheet -- business style theme.
+ *
+ * :copyright: Copyright 2011-2014 by Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+@import url("basic.css");
+
+/* -- page layout ----------------------------------------------------------- */
+
+body {
+    font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',
+                 'Verdana', sans-serif;
+    font-size: 14px;
+    letter-spacing: -0.01em;
+    line-height: 150%;
+    text-align: center;
+    background-color: white;
+    background-image: url(background_b01.png);
+    color: black;
+    padding: 0;
+    border-right: 1px solid {{ theme_maincolor }};
+    border-left: 1px solid {{ theme_maincolor }};
+
+    margin: 0px 40px 0px 40px;
+}
+
+div.document {
+    background-color: white;
+    text-align: left;
+    background-repeat: repeat-x;
+
+    -moz-box-shadow: 2px 2px 5px #000;
+    -webkit-box-shadow: 2px 2px 5px #000;
+}
+
+div.bodywrapper {
+    margin: 0 0 0 240px;
+    border-left: 1px solid #ccc;
+}
+
+div.body {
+    margin: 0;
+    padding: 0.5em 20px 20px 20px;
+}
+
+{%- if theme_rightsidebar|tobool %}
+div.bodywrapper {
+    margin: 0 240px 0 0;
+    border-right: 1px solid #ccc;
+}
+{%- endif %}
+
+div.related {
+    font-size: 1em;
+
+    -moz-box-shadow: 2px 2px 5px #000;
+    -webkit-box-shadow: 2px 2px 5px #000;
+}
+
+div.related ul {
+    background-color: {{ theme_maincolor }};
+    height: 2em;
+    border-top: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+}
+
+div.related ul li {
+    color: white;
+    margin: 0;
+    padding: 0;
+    height: 2em;
+    float: left;
+}
+
+div.related ul li.right {
+    float: right;
+    margin-right: 5px;
+}
+
+div.related ul li a {
+    margin: 0;
+    padding: 0 5px 0 5px;
+    line-height: 1.75em;
+    color: #fff;
+}
+
+div.related ul li a:hover {
+    color: #fff;
+    text-decoration: underline;
+}
+
+div.sphinxsidebarwrapper {
+    padding: 0;
+}
+
+div.sphinxsidebar {
+    margin: 0;
+    padding: 0.5em 12px 12px 12px;
+    width: 210px;
+    {%- if theme_rightsidebar|tobool %}
+    float: right;
+    {%- endif %}
+    font-size: 1em;
+    text-align: left;
+}
+
+div.sphinxsidebar h3, div.sphinxsidebar h4 {
+    margin: 1em 0 0.5em 0;
+    font-size: 1em;
+    padding: 0.1em 0 0.1em 0.5em;
+    color: white;
+    border: 1px solid {{ theme_maincolor }};
+    background-color: {{ theme_maincolor }};
+}
+
+div.sphinxsidebar h3 a {
+    color: white;
+}
+
+div.sphinxsidebar ul {
+    padding-left: 1.5em;
+    margin-top: 7px;
+    padding: 0;
+    line-height: 130%;
+}
+
+div.sphinxsidebar ul ul {
+    margin-left: 20px;
+}
+
+div.sphinxsidebar input {
+    border: 1px solid {{ theme_maincolor }};
+}
+
+div.footer {
+    background-color: white;
+    color: {{ theme_maincolor }};
+    padding: 3px 8px 3px 0;
+    clear: both;
+    font-size: 0.8em;
+    text-align: right;
+    border-bottom: 1px solid {{ theme_maincolor }};
+
+    -moz-box-shadow: 2px 2px 5px #000;
+    -webkit-box-shadow: 2px 2px 5px #000;
+}
+
+div.footer a {
+    color: {{ theme_maincolor }};
+    text-decoration: underline;
+}
+
+/* -- body styles ----------------------------------------------------------- */
+
+p {
+    margin: 0.8em 0 0.5em 0;
+}
+
+a {
+    color: {{ theme_maincolor }};
+    text-decoration: none;
+}
+
+a:hover {
+    color: {{ theme_maincolor }};
+    text-decoration: underline;
+}
+
+div.body a {
+    text-decoration: underline;
+}
+
+h1, h2, h3 {
+    color: {{ theme_maincolor }};
+}
+
+h1 {
+    margin: 0;
+    padding: 0.7em 0 0.3em 0;
+    font-size: 1.5em;
+}
+
+h2 {
+    margin: 1.3em 0 0.2em 0;
+    font-size: 1.35em;
+    padding-bottom: .5em;
+    border-bottom: 1px solid {{ theme_maincolor }};
+}
+
+h3 {
+    margin: 1em 0 -0.3em 0;
+    font-size: 1.2em;
+    padding-bottom: .3em;
+    border-bottom: 1px solid #CCCCCC;
+}
+
+div.body h1 a, div.body h2 a, div.body h3 a,
+div.body h4 a, div.body h5 a, div.body h6 a {
+    color: black!important;
+}
+
+h1 a.anchor, h2 a.anchor, h3 a.anchor,
+h4 a.anchor, h5 a.anchor, h6 a.anchor {
+    display: none;
+    margin: 0 0 0 0.3em;
+    padding: 0 0.2em 0 0.2em;
+    color: #aaa!important;
+}
+
+h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor,
+h5:hover a.anchor, h6:hover a.anchor {
+    display: inline;
+}
+
+h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover,
+h5 a.anchor:hover, h6 a.anchor:hover {
+    color: #777;
+    background-color: #eee;
+}
+
+a.headerlink {
+    color: #c60f0f!important;
+    font-size: 1em;
+    margin-left: 6px;
+    padding: 0 4px 0 4px;
+    text-decoration: none!important;
+}
+
+a.headerlink:hover {
+    background-color: #ccc;
+    color: white!important;
+}
+
+cite, code, tt {
+    font-family: 'Consolas', 'Deja Vu Sans Mono',
+                 'Bitstream Vera Sans Mono', monospace;
+    font-size: 0.95em;
+    letter-spacing: 0.01em;
+}
+
+tt {
+    background-color: #F2F2F2;
+    border-bottom: 1px solid #ddd;
+    color: #333;
+}
+
+tt.descname, tt.descclassname, tt.xref {
+    border: 0;
+}
+
+hr {
+    border: 1px solid #abc;
+    margin: 2em;
+}
+
+a tt {
+    border: 0;
+    color: #CA7900;
+}
+
+a tt:hover {
+    color: #2491CF;
+}
+
+pre {
+    font-family: 'Consolas', 'Deja Vu Sans Mono',
+                 'Bitstream Vera Sans Mono', monospace;
+    font-size: 0.95em;
+    letter-spacing: 0.015em;
+    line-height: 120%;
+    padding: 0.5em;
+    border-right: 5px solid #ccc;
+    border-left: 5px solid #ccc;
+}
+
+pre a {
+    color: inherit;
+    text-decoration: underline;
+}
+
+td.linenos pre {
+    padding: 0.5em 0;
+}
+
+div.quotebar {
+    background-color: #f8f8f8;
+    max-width: 250px;
+    float: right;
+    padding: 2px 7px;
+    border: 1px solid #ccc;
+}
+
+div.topic {
+    background-color: #f8f8f8;
+}
+
+table {
+    border-collapse: collapse;
+    margin: 0 -0.5em 0 -0.5em;
+}
+
+table td, table th {
+    padding: 0.2em 0.5em 0.2em 0.5em;
+}
+
+div.admonition {
+    font-size: 0.9em;
+    margin: 1em 0 1em 0;
+    border: 3px solid #cccccc;
+    background-color: #f7f7f7;
+    padding: 0;
+}
+
+div.admonition p {
+    margin: 0.5em 1em 0.5em 1em;
+    padding: 0;
+}
+
+div.admonition li p {
+    margin-left: 0;
+}
+
+div.admonition pre, div.warning pre {
+    margin: 0.4em 1em 0.4em 1em;
+}
+
+div.admonition p.admonition-title {
+    margin: 0;
+    padding: 0.1em 0 0.1em 0.5em;
+    color: white;
+    border-bottom: 3px solid #cccccc;
+    font-weight: bold;
+    background-color: #165e83;
+}
+
+div.danger    { border: 3px solid #f0908d; background-color: #f0cfa0; }
+div.error     { border: 3px solid #f0908d; background-color: #ede4cd; }
+div.warning   { border: 3px solid #f8b862; background-color: #f0cfa0; }
+div.caution   { border: 3px solid #f8b862; background-color: #ede4cd; }
+div.attention { border: 3px solid #f8b862; background-color: #f3f3f3; }
+div.important { border: 3px solid #f0cfa0; background-color: #ede4cd; }
+div.note      { border: 3px solid #f0cfa0; background-color: #f3f3f3; }
+div.hint      { border: 3px solid #bed2c3; background-color: #f3f3f3; }
+div.tip       { border: 3px solid #bed2c3; background-color: #f3f3f3; }
+
+div.danger p.admonition-title, div.error p.admonition-title {
+    background-color: #b7282e;
+    border-bottom: 3px solid #f0908d;
+}
+
+div.caution p.admonition-title,
+div.warning p.admonition-title,
+div.attention p.admonition-title {
+    background-color: #f19072;
+    border-bottom: 3px solid #f8b862;
+}
+
+div.note p.admonition-title, div.important p.admonition-title {
+    background-color: #f8b862;
+    border-bottom: 3px solid #f0cfa0;
+}
+
+div.hint p.admonition-title, div.tip p.admonition-title {
+    background-color: #7ebea5;
+    border-bottom: 3px solid #bed2c3;
+}
+
+div.admonition ul, div.admonition ol,
+div.warning ul, div.warning ol {
+    margin: 0.1em 0.5em 0.5em 3em;
+    padding: 0;
+}
+
+div.versioninfo {
+    margin: 1em 0 0 0;
+    border: 1px solid #ccc;
+    background-color: #DDEAF0;
+    padding: 8px;
+    line-height: 1.3em;
+    font-size: 0.9em;
+}
+
+.viewcode-back {
+    font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',
+                 'Verdana', sans-serif;
+}
+
+div.viewcode-block:target {
+    background-color: #f4debf;
+    border-top: 1px solid #ac9;
+    border-bottom: 1px solid #ac9;
+}
+
+p.versionchanged span.versionmodified {
+    font-size: 0.9em;
+    margin-right: 0.2em;
+    padding: 0.1em;
+    background-color: #DCE6A0;
+}
+
+/* -- table styles ---------------------------------------------------------- */
+
+table.docutils {
+    margin: 1em 0;
+    padding: 0;
+    border: 1px solid white;
+    background-color: #f7f7f7;
+}
+
+table.docutils td, table.docutils th {
+    padding: 1px 8px 1px 5px;
+    border-top: 0;
+    border-left: 0;
+    border-right: 1px solid white;
+    border-bottom: 1px solid white;
+}
+
+table.docutils td p {
+    margin-top: 0;
+    margin-bottom: 0.3em;
+}
+
+table.field-list td, table.field-list th {
+    border: 0 !important;
+    word-break: break-word;
+}
+
+table.footnote td, table.footnote th {
+    border: 0 !important;
+}
+
+th {
+    color: white;
+    text-align: left;
+    padding-right: 5px;
+    background-color: #82A0BE;
+}
+
+/* WIDE DESKTOP STYLE */
+@media only screen and (min-width: 1176px) {
+body {
+    margin: 0 40px 0 40px;
+}
+}
+
+/* TABLET STYLE */
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+body {
+    margin: 0 40px 0 40px;
+}
+}
+
+/* MOBILE LAYOUT (PORTRAIT/320px) */
+@media only screen and (max-width: 767px) {
+body {
+    margin: 0;
+}
+div.bodywrapper {
+    margin: 0;
+    width: 100%;
+    border: none;
+}
+div.sphinxsidebar {
+    display: none;
+}
+}
+
+/* MOBILE LAYOUT (LANDSCAPE/480px) */
+@media only screen and (min-width: 480px) and (max-width: 767px) {
+body {
+    margin: 0 20px 0 20px;
+}
+}
+
+/* RETINA OVERRIDES */
+@media
+only screen and (-webkit-min-device-pixel-ratio: 2),
+only screen and (min-device-pixel-ratio: 2) {
+}
+
+/* -- end ------------------------------------------------------------------- */
diff --git a/sphinx/themes/bizstyle/static/bizstyle.js_t b/sphinx/themes/bizstyle/static/bizstyle.js_t
new file mode 100644
index 0000000..1950d39
--- /dev/null
+++ b/sphinx/themes/bizstyle/static/bizstyle.js_t
@@ -0,0 +1,45 @@
+//
+// bizstyle.js
+// ~~~~~~~~~~~
+//
+// Sphinx javascript -- for bizstyle theme.
+//
+// This theme was created by referring to 'sphinxdoc'
+//
+// :copyright: Copyright 2012-2014 by Sphinx team, see AUTHORS.
+// :license: BSD, see LICENSE for details.
+//
+$(document).ready(function(){
+    if (navigator.userAgent.indexOf('iPhone') > 0 ||
+        navigator.userAgent.indexOf('Android') > 0) {
+        $("div.related ul li:not(.right) a").text("Top");
+    }
+
+    $("div.related:first ul li:not(.right) a").slice(1).each(function(i, item){
+        if (item.text.length > 20) {
+            var tmpstr = item.text
+            $(item).attr("title", tmpstr);
+            $(item).text(tmpstr.substr(0, 5) + "...");
+            alert(i + ":" + item.text + ":" + $(item).attr("title") + ":" + $(item).size());
+        }
+    });
+    $("div.related:last ul li:not(.right) a").slice(1).each(function(i, item){
+        if (item.text.length > 20) {
+            var tmpstr = item.text
+            $(item).attr("title", tmpstr);
+            $(item).text(tmpstr.substr(0, 5) + "...");
+            alert(i + ":" + item.text + ":" + $(item).attr("title") + ":" + $(item).size());
+        }
+    });
+});
+
+$(window).resize(function(){
+    if ($(window).width() <= 776) {
+        $("div.related:first ul li:not(.right):first a").text("Top");
+        $("div.related:last  ul li:not(.right):first a").text("Top");
+    }
+    else {
+        $("div.related:first ul li:not(.right):first a").text("{{ shorttitle|e }}");
+        $("div.related:last  ul li:not(.right):first a").text("{{ shorttitle|e }}");
+    }
+});
diff --git a/sphinx/themes/bizstyle/static/css3-mediaqueries.js b/sphinx/themes/bizstyle/static/css3-mediaqueries.js
new file mode 100644
index 0000000..3b90652
--- /dev/null
+++ b/sphinx/themes/bizstyle/static/css3-mediaqueries.js
@@ -0,0 +1 @@
+if(typeof Object.create!=="function"){Object.create=function(e){function t(){}t.prototype=e;return new t}}var ua={toString:function(){return navigator.userAgent},test:function(e){return this.toString().toLowerCase().indexOf(e.toLowerCase())>-1}};ua.version=(ua.toString().toLowerCase().match(/[\s\S]+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[])[1];ua.webkit=ua.test("webkit");ua.gecko=ua.test("gecko")&&!ua.webkit;ua.opera=ua.test("opera");ua.ie=ua.test("msie")&&!ua.opera;ua.ie6=ua.ie&&document.compatMode&&typeof document.documentElement.style.maxHeight==="undefined";ua.ie7=ua.ie&&document.documentElement&&typeof document.documentElement.style.maxHeight!=="undefined"&&typeof XDomainRequest==="undefined";ua.ie8=ua.ie&&typeof XDomainRequest!=="undefined";var domReady=function(){var e=[];var t=function(){if(!arguments.callee.done){arguments.callee.done=true;for(var t=0;t<e.length;t++){e[t]()}}};if(document.addEventListener){document.addEventListener("DOMContentLoaded",t,false)}if(ua.ie){(function(){try{document.documentElement.doScroll("left")}catch(e){setTimeout(arguments.callee,50);return}t()})();document.onreadystatechange=function(){if(document.readyState==="complete"){document.onreadystatechange=null;t()}}}if(ua.webkit&&document.readyState){(function(){if(document.readyState!=="loading"){t()}else{setTimeout(arguments.callee,10)}})()}window.onload=t;return function(t){if(typeof t==="function"){e[e.length]=t}return t}}();var cssHelper=function(){var e={BLOCKS:/[^\s{;][^{;]*\{(?:[^{}]*\{[^{}]*\}[^{}]*|[^{}]*)*\}/g,BLOCKS_INSIDE:/[^\s{][^{]*\{[^{}]*\}/g,DECLARATIONS:/[a-zA-Z\-]+[^;]*:[^;]+;/g,RELATIVE_URLS:/url\(['"]?([^\/\)'"][^:\)'"]+)['"]?\)/g,REDUNDANT_COMPONENTS:/(?:\/\*([^*\\\\]|\*(?!\/))+\*\/|@import[^;]+;)/g,REDUNDANT_WHITESPACE:/\s*(,|:|;|\{|\})\s*/g,WHITESPACE_IN_PARENTHESES:/\(\s*(\S*)\s*\)/g,MORE_WHITESPACE:/\s{2,}/g,FINAL_SEMICOLONS:/;\}/g,NOT_WHITESPACE:/\S+/g};var t,n=false;var r=[];var s=function(e){if(typeof e==="function"){r[r.length]=e}};var o=function(){for(var e=0;e<r.length;e++){r[e](t)}};var u={};var a=function(e,t){if(u[e]){var n=u[e].listeners;if(n){for(var r=0;r<n.length;r++){n[r](t)}}}};var f=function(e,t,n){if(ua.ie&&!window.XMLHttpRequest){window.XMLHttpRequest=function(){return new ActiveXObject("Microsoft.XMLHTTP")}}if(!XMLHttpRequest){return""}var r=new XMLHttpRequest;try{r.open("get",e,true);r.setRequestHeader("X_REQUESTED_WITH","XMLHttpRequest")}catch(i){n();return}var s=false;setTimeout(function(){s=true},5e3);document.documentElement.style.cursor="progress";r.onreadystatechange=function(){if(r.readyState===4&&!s){if(!r.status&&location.protocol==="file:"||r.status>=200&&r.status<300||r.status===304||navigator.userAgent.indexOf("Safari")>-1&&typeof r.status==="undefined"){t(r.responseText)}else{n()}document.documentElement.style.cursor="";r=null}};r.send("")};var l=function(t){t=t.replace(e.REDUNDANT_COMPONENTS,"");t=t.replace(e.REDUNDANT_WHITESPACE,"$1");t=t.replace(e.WHITESPACE_IN_PARENTHESES,"($1)");t=t.replace(e.MORE_WHITESPACE," ");t=t.replace(e.FINAL_SEMICOLONS,"}");return t};var c={stylesheet:function(t){var n={};var r=[],i=[],s=[],o=[];var u=t.cssHelperText;var a=t.getAttribute("media");if(a){var f=a.toLowerCase().split(",")}else{var f=["all"]}for(var l=0;l<f.length;l++){r[r.length]=c.mediaQuery(f[l],n)}var h=u.match(e.BLOCKS);if(h!==null){for(var l=0;l<h.length;l++){if(h[l].substring(0,7)==="@media "){var p=c.mediaQueryList(h[l],n);s=s.concat(p.getRules());i[i.length]=p}else{s[s.length]=o[o.length]=c.rule(h[l],n,null)}}}n.element=t;n.getCssText=function(){return u};n.getAttrMediaQueries=function(){return r};n.getMediaQueryLists=function(){return i};n.getRules=function(){return s};n.getRulesWithoutMQ=function(){return o};return n},mediaQueryList:function(t,n){var r={};var i=t.indexOf("{");var s=t.substring(0,i);t=t.substring(i+1,t.length-1);var o=[],u=[];var a=s.toLowerCase().substring(7).split(",");for(var f=0;f<a.length;f++){o[o.length]=c.mediaQuery(a[f],r)}var l=t.match(e.BLOCKS_INSIDE);if(l!==null){for(f=0;f<l.length;f++){u[u.length]=c.rule(l[f],n,r)}}r.type="mediaQueryList";r.getMediaQueries=function(){return o};r.getRules=function(){return u};r.getListText=function(){return s};r.getCssText=function(){return t};return r},mediaQuery:function(t,n){t=t||"";var r,i;if(n.type==="mediaQueryList"){r=n}else{i=n}var s=false,o;var u=[];var a=true;var f=t.match(e.NOT_WHITESPACE);for(var l=0;l<f.length;l++){var c=f[l];if(!o&&(c==="not"||c==="only")){if(c==="not"){s=true}}else if(!o){o=c}else if(c.charAt(0)==="("){var h=c.substring(1,c.length-1).split(":");u[u.length]={mediaFeature:h[0],value:h[1]||null}}}return{getQueryText:function(){return t},getAttrStyleSheet:function(){return i||null},getList:function(){return r||null},getValid:function(){return a},getNot:function(){return s},getMediaType:function(){return o},getExpressions:function(){return u}}},rule:function(e,t,n){var r={};var i=e.indexOf("{");var s=e.substring(0,i);var o=s.split(",");var u=[];var a=e.substring(i+1,e.length-1).split(";");for(var f=0;f<a.length;f++){u[u.length]=c.declaration(a[f],r)}r.getStylesheet=function(){return t||null};r.getMediaQueryList=function(){return n||null};r.getSelectors=function(){return o};r.getSelectorText=function(){return s};r.getDeclarations=function(){return u};r.getPropertyValue=function(e){for(var t=0;t<u.length;t++){if(u[t].getProperty()===e){return u[t].getValue()}}return null};return r},declaration:function(e,t){var n=e.indexOf(":");var r=e.substring(0,n);var i=e.substring(n+1);return{getRule:function(){return t||null},getProperty:function(){return r},getValue:function(){return i}}}};var h=function(e){if(typeof e.cssHelperText!=="string"){return}var n={stylesheet:null,mediaQueryLists:[],rules:[],selectors:{},declarations:[],properties:{}};var r=n.stylesheet=c.stylesheet(e);var s=n.mediaQueryLists=r.getMediaQueryLists();var o=n.rules=r.getRules();var u=n.selectors;var a=function(e){var t=e.getSelectors();for(var n=0;n<t.length;n++){var r=t[n];if(!u[r]){u[r]=[]}u[r][u[r].length]=e}};for(i=0;i<o.length;i++){a(o[i])}var f=n.declarations;for(i=0;i<o.length;i++){f=n.declarations=f.concat(o[i].getDeclarations())}var l=n.properties;for(i=0;i<f.length;i++){var h=f[i].getProperty();if(!l[h]){l[h]=[]}l[h][l[h].length]=f[i]}e.cssHelperParsed=n;t[t.length]=e;return n};var p=function(e,t){return;e.cssHelperText=l(t||e.innerHTML);return h(e)};var d=function(){n=true;t=[];var r=[];var i=function(){for(var e=0;e<r.length;e++){h(r[e])}var t=document.getElementsByTagName("style");for(e=0;e<t.length;e++){p(t[e])}n=false;o()};var s=document.getElementsByTagName("link");for(var u=0;u<s.length;u++){var a=s[u];if(a.getAttribute("rel").indexOf("style")>-1&&a.href&&a.href.length!==0&&!a.disabled){r[r.length]=a}}if(r.length>0){var c=0;var d=function(){c++;if(c===r.length){i()}};var v=function(t){var n=t.href;f(n,function(r){r=l(r).replace(e.RELATIVE_URLS,"url("+n.substring(0,n.lastIndexOf("/"))+"/$1)");t.cssHelperText=r;d()},d)};for(u=0;u<r.length;u++){v(r[u])}}else{i()}};var v={stylesheets:"array",mediaQueryLists:"array",rules:"array",selectors:"object",declarations:"array",properties:"object"};var m={stylesheets:null,mediaQueryLists:null,rules:null,selectors:null,declarations:null,properties:null};var g=function(e,t){if(m[e]!==null){if(v[e]==="array"){return m[e]=m[e].concat(t)}else{var n=m[e];for(var r in t){if(t.hasOwnProperty(r)){if(!n[r]){n[r]=t[r]}else{n[r]=n[r].concat(t[r])}}}return n}}};var y=function(e){m[e]=v[e]==="array"?[]:{};for(var n=0;n<t.length;n++){var r=e==="stylesheets"?"stylesheet":e;g(e,t[n].cssHelperParsed[r])}return m[e]};var b=function(e){if(typeof window.innerWidth!="undefined"){return window["inner"+e]}else if(typeof document.documentElement!=="undefined"&&typeof document.documentElement.clientWidth!=="undefined"&&document.documentElement.clientWidth!=0){return document.documentElement["client"+e]}};return{addStyle:function(e,t,n){var r=document.createElement("style");r.setAttribute("type","text/css");if(t&&t.length>0){r.setAttribute("media",t.join(","))}document.getElementsByTagName("head")[0].appendChild(r);if(r.styleSheet){r.styleSheet.cssText=e}else{r.appendChild(document.createTextNode(e))}r.addedWithCssHelper=true;if(typeof n==="undefined"||n===true){cssHelper.parsed(function(t){var n=p(r,e);for(var i in n){if(n.hasOwnProperty(i)){g(i,n[i])}}a("newStyleParsed",r)})}else{r.parsingDisallowed=true}return r},removeStyle:function(e){return e.parentNode.removeChild(e)},parsed:function(e){if(n){s(e)}else{if(typeof t!=="undefined"){if(typeof e==="function"){e(t)}}else{s(e);d()}}},stylesheets:function(e){cssHelper.parsed(function(t){e(m.stylesheets||y("stylesheets"))})},mediaQueryLists:function(e){cssHelper.parsed(function(t){e(m.mediaQueryLists||y("mediaQueryLists"))})},rules:function(e){cssHelper.parsed(function(t){e(m.rules||y("rules"))})},selectors:function(e){cssHelper.parsed(function(t){e(m.selectors||y("selectors"))})},declarations:function(e){cssHelper.parsed(function(t){e(m.declarations||y("declarations"))})},properties:function(e){cssHelper.parsed(function(t){e(m.properties||y("properties"))})},broadcast:a,addListener:function(e,t){if(typeof t==="function"){if(!u[e]){u[e]={listeners:[]}}u[e].listeners[u[e].listeners.length]=t}},removeListener:function(e,t){if(typeof t==="function"&&u[e]){var n=u[e].listeners;for(var r=0;r<n.length;r++){if(n[r]===t){n.splice(r,1);r-=1}}}},getViewportWidth:function(){return b("Width")},getViewportHeight:function(){return b("Height")}}}();domReady(function(){var t;var n={LENGTH_UNIT:/[0-9]+(em|ex|px|in|cm|mm|pt|pc)$/,RESOLUTION_UNIT:/[0-9]+(dpi|dpcm)$/,ASPECT_RATIO:/^[0-9]+\/[0-9]+$/,ABSOLUTE_VALUE:/^[0-9]*(\.[0-9]+)*$/};var r=[];var i=function(){var e="css3-mediaqueries-test";var t=document.createElement("div");t.id=e;var n=cssHelper.addStyle("@media all and (width) { #"+e+" { width: 1px !important; } }",[],false);document.body.appendChild(t);var r=t.offsetWidth===1;n.parentNode.removeChild(n);t.parentNode.removeChild(t);i=function(){return r};return r};var s=function(){t=document.createElement("div");t.style.cssText="position:absolute;top:-9999em;left:-9999em;"+"margin:0;border:none;padding:0;width:1em;font-size:1em;";document.body.appendChild(t);if(t.offsetWidth!==16){t.style.fontSize=16/t.offsetWidth+"em"}t.style.width=""};var o=function(e){t.style.width=e;var n=t.offsetWidth;t.style.width="";return n};var u=function(e,t){var r=e.length;var i=e.substring(0,4)==="min-";var s=!i&&e.substring(0,4)==="max-";if(t!==null){var u;var a;if(n.LENGTH_UNIT.exec(t)){u="length";a=o(t)}else if(n.RESOLUTION_UNIT.exec(t)){u="resolution";a=parseInt(t,10);var f=t.substring((a+"").length)}else if(n.ASPECT_RATIO.exec(t)){u="aspect-ratio";a=t.split("/")}else if(n.ABSOLUTE_VALUE){u="absolute";a=t}else{u="unknown"}}var l,c;if("device-width"===e.substring(r-12,r)){l=screen.width;if(t!==null){if(u==="length"){return i&&l>=a||s&&l<a||!i&&!s&&l===a}else{return false}}else{return l>0}}else if("device-height"===e.substring(r-13,r)){c=screen.height;if(t!==null){if(u==="length"){return i&&c>=a||s&&c<a||!i&&!s&&c===a}else{return false}}else{return c>0}}else if("width"===e.substring(r-5,r)){l=document.documentElement.clientWidth||document.body.clientWidth;if(t!==null){if(u==="length"){return i&&l>=a||s&&l<a||!i&&!s&&l===a}else{return false}}else{return l>0}}else if("height"===e.substring(r-6,r)){c=document.documentElement.clientHeight||document.body.clientHeight;if(t!==null){if(u==="length"){return i&&c>=a||s&&c<a||!i&&!s&&c===a}else{return false}}else{return c>0}}else if("device-aspect-ratio"===e.substring(r-19,r)){return u==="aspect-ratio"&&screen.width*a[1]===screen.height*a[0]}else if("color-index"===e.substring(r-11,r)){var h=Math.pow(2,screen.colorDepth);if(t!==null){if(u==="absolute"){return i&&h>=a||s&&h<a||!i&&!s&&h===a}else{return false}}else{return h>0}}else if("color"===e.substring(r-5,r)){var p=screen.colorDepth;if(t!==null){if(u==="absolute"){return i&&p>=a||s&&p<a||!i&&!s&&p===a}else{return false}}else{return p>0}}else if("resolution"===e.substring(r-10,r)){var d;if(f==="dpcm"){d=o("1cm")}else{d=o("1in")}if(t!==null){if(u==="resolution"){return i&&d>=a||s&&d<a||!i&&!s&&d===a}else{return false}}else{return d>0}}else{return false}};var a=function(e){var t=e.getValid();var n=e.getExpressions();var r=n.length;if(r>0){for(var i=0;i<r&&t;i++){t=u(n[i].mediaFeature,n[i].value)}var s=e.getNot();return t&&!s||s&&!t}return t};var f=function(e,t){var n=e.getMediaQueries();var i={};for(var s=0;s<n.length;s++){var o=n[s].getMediaType();if(n[s].getExpressions().length===0){continue}var u=true;if(o!=="all"&&t&&t.length>0){u=false;for(var f=0;f<t.length;f++){if(t[f]===o){u=true}}}if(u&&a(n[s])){i[o]=true}}var l=[],c=0;for(var h in i){if(i.hasOwnProperty(h)){if(c>0){l[c++]=","}l[c++]=h}}if(l.length>0){r[r.length]=cssHelper.addStyle("@media "+l.join("")+"{"+e.getCssText()+"}",t,false)}};var l=function(e,t){for(var n=0;n<e.length;n++){f(e[n],t)}};var c=function(e){var t=e.getAttrMediaQueries();var n=false;var i={};for(var s=0;s<t.length;s++){if(a(t[s])){i[t[s].getMediaType()]=t[s].getExpressions().length>0}}var o=[],u=[];for(var f in i){if(i.hasOwnProperty(f)){o[o.length]=f;if(i[f]){u[u.length]=f}if(f==="all"){n=true}}}if(u.length>0){r[r.length]=cssHelper.addStyle(e.getCssText(),u,false)}var c=e.getMediaQueryLists();if(n){l(c)}else{l(c,o)}};var h=function(e){for(var t=0;t<e.length;t++){c(e[t])}if(ua.ie){document.documentElement.style.display="block";setTimeout(function(){document.documentElement.style.display=""},0);setTimeout(function(){cssHelper.broadcast("cssMediaQueriesTested")},100)}else{cssHelper.broadcast("cssMediaQueriesTested")}};var p=function(){for(var e=0;e<r.length;e++){cssHelper.removeStyle(r[e])}r=[];cssHelper.stylesheets(h)};var d=0;var v=function(){var e=cssHelper.getViewportWidth();var t=cssHelper.getViewportHeight();if(ua.ie){var n=document.createElement("div");n.style.position="absolute";n.style.top="-9999em";n.style.overflow="scroll";document.body.appendChild(n);d=n.offsetWidth-n.clientWidth;document.body.removeChild(n)}var r;var s=function(){var n=cssHelper.getViewportWidth();var s=cssHelper.getViewportHeight();if(Math.abs(n-e)>d||Math.abs(s-t)>d){e=n;t=s;clearTimeout(r);r=setTimeout(function(){if(!i()){p()}else{cssHelper.broadcast("cssMediaQueriesTested")}},500)}};window.onresize=function(){var e=window.onresize||function(){};return function(){e();s()}}()};var m=document.documentElement;m.style.marginLeft="-32767px";setTimeout(function(){m.style.marginLeft=""},5e3);return function(){if(!i()){cssHelper.addListener("newStyleParsed",function(e){c(e.cssHelperParsed.stylesheet)});cssHelper.addListener("cssMediaQueriesTested",function(){if(ua.ie){m.style.width="1px"}setTimeout(function(){m.style.width="";m.style.marginLeft=""},0);cssHelper.removeListener("cssMediaQueriesTested",arguments.callee)});s();p()}else{m.style.marginLeft=""}v()}}());try{document.execCommand("BackgroundImageCache",false,true)}catch(e){}
\ No newline at end of file
diff --git a/sphinx/themes/bizstyle/static/css3-mediaqueries_src.js b/sphinx/themes/bizstyle/static/css3-mediaqueries_src.js
new file mode 100644
index 0000000..e5a3bb0
--- /dev/null
+++ b/sphinx/themes/bizstyle/static/css3-mediaqueries_src.js
@@ -0,0 +1,1104 @@
+/*

+css3-mediaqueries.js - CSS Helper and CSS3 Media Queries Enabler

+

+author: Wouter van der Graaf <wouter at dynora nl>

+version: 1.0 (20110330)

+license: MIT

+website: http://code.google.com/p/css3-mediaqueries-js/

+

+W3C spec: http://www.w3.org/TR/css3-mediaqueries/

+

+Note: use of embedded <style> is not recommended when using media queries, because IE  has no way of returning the raw literal css text from a <style> element.

+*/

+

+

+// true prototypal inheritance (http://javascript.crockford.com/prototypal.html)

+if (typeof Object.create !== 'function') {

+	Object.create = function (o) {

+		function F() {}

+		F.prototype = o;

+		return new F();

+	};

+}

+

+

+// user agent sniffing shortcuts

+var ua = {

+	toString: function () {

+		return navigator.userAgent;

+	},

+	test: function (s) {

+		return this.toString().toLowerCase().indexOf(s.toLowerCase()) > -1;

+	}

+};

+ua.version = (ua.toString().toLowerCase().match(/[\s\S]+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1];

+ua.webkit = ua.test('webkit');

+ua.gecko = ua.test('gecko') && !ua.webkit;

+ua.opera = ua.test('opera');

+ua.ie = ua.test('msie') && !ua.opera;

+ua.ie6 = ua.ie && document.compatMode && typeof document.documentElement.style.maxHeight === 'undefined';

+ua.ie7 = ua.ie && document.documentElement && typeof document.documentElement.style.maxHeight !== 'undefined' && typeof XDomainRequest === 'undefined';

+ua.ie8 = ua.ie && typeof XDomainRequest !== 'undefined';

+

+

+

+// initialize when DOM content is loaded

+var domReady = function () {

+	var fns = [];

+	var init = function () {

+		if (!arguments.callee.done) { // run init functions once

+			arguments.callee.done = true;

+			for (var i = 0; i < fns.length; i++) {

+				fns[i]();

+			}

+		}

+	};

+

+	// listeners for different browsers

+	if (document.addEventListener) {

+		document.addEventListener('DOMContentLoaded', init, false);

+	}

+	if (ua.ie) {

+		(function () {

+			try {

+				// throws errors until after ondocumentready

+				document.documentElement.doScroll('left');

+			}

+			catch (e) {

+				setTimeout(arguments.callee, 50);

+				return;

+			}

+			// no errors, fire

+			init();

+		})();

+		// trying to always fire before onload

+		document.onreadystatechange = function () {

+			if (document.readyState === 'complete') {

+				document.onreadystatechange = null;

+				init();

+			}

+		};

+	}

+	if (ua.webkit && document.readyState) {

+		(function () {

+			if (document.readyState !== 'loading') {

+				init();

+			}

+			else {

+				setTimeout(arguments.callee, 10);

+			}

+		})();

+	}

+	window.onload = init; // fallback

+

+	return function (fn) { // add fn to init functions

+		if (typeof fn === 'function') {

+			fns[fns.length] = fn;

+		}

+		return fn;

+	};

+}();

+

+

+

+// helper library for parsing css to objects

+var cssHelper = function () {

+

+	var regExp = {

+		BLOCKS: /[^\s{;][^{;]*\{(?:[^{}]*\{[^{}]*\}[^{}]*|[^{}]*)*\}/g,

+		BLOCKS_INSIDE: /[^\s{][^{]*\{[^{}]*\}/g,

+		DECLARATIONS: /[a-zA-Z\-]+[^;]*:[^;]+;/g,

+		RELATIVE_URLS: /url\(['"]?([^\/\)'"][^:\)'"]+)['"]?\)/g,

+		// strip whitespace and comments, @import is evil

+		REDUNDANT_COMPONENTS: /(?:\/\*([^*\\\\]|\*(?!\/))+\*\/|@import[^;]+;)/g,

+		REDUNDANT_WHITESPACE: /\s*(,|:|;|\{|\})\s*/g,

+        WHITESPACE_IN_PARENTHESES: /\(\s*(\S*)\s*\)/g,

+		MORE_WHITESPACE: /\s{2,}/g,

+		FINAL_SEMICOLONS: /;\}/g,

+		NOT_WHITESPACE: /\S+/g

+	};

+

+	var parsed, parsing = false;

+

+	var waiting = [];

+	var wait = function (fn) {

+		if (typeof fn === 'function') {

+			waiting[waiting.length] = fn;

+		}

+	};

+	var ready = function () {

+		for (var i = 0; i < waiting.length; i++) {

+			waiting[i](parsed);

+		}

+	};

+	var events = {};

+	var broadcast = function (n, v) {

+		if (events[n]) {

+			var listeners = events[n].listeners;

+			if (listeners) {

+				for (var i = 0; i < listeners.length; i++) {

+					listeners[i](v);

+				}

+			}

+		}

+	};

+

+	var requestText = function (url, fnSuccess, fnFailure) {

+		if (ua.ie && !window.XMLHttpRequest) {

+			window.XMLHttpRequest = function () {

+				return new ActiveXObject('Microsoft.XMLHTTP');

+			};

+		}

+		if (!XMLHttpRequest) {

+			return '';

+		}

+		var r = new XMLHttpRequest();

+		try {

+			r.open('get', url, true);

+			r.setRequestHeader('X_REQUESTED_WITH', 'XMLHttpRequest');

+		}

+		catch (e) {

+			fnFailure();

+			return;

+		}

+		var done = false;

+		setTimeout(function () {

+			done = true;

+		}, 5000);

+		document.documentElement.style.cursor = 'progress';

+		r.onreadystatechange = function () {

+			if (r.readyState === 4 && !done) {

+				if (!r.status && location.protocol === 'file:' ||

+						(r.status >= 200 && r.status < 300) ||

+						r.status === 304 ||

+						navigator.userAgent.indexOf('Safari') > -1 && typeof r.status === 'undefined') {

+					fnSuccess(r.responseText);

+				}

+				else {

+					fnFailure();

+				}

+				document.documentElement.style.cursor = '';

+				r = null; // avoid memory leaks

+			}

+		};

+		r.send('');

+	};

+

+	var sanitize = function (text) {

+		text = text.replace(regExp.REDUNDANT_COMPONENTS, '');

+		text = text.replace(regExp.REDUNDANT_WHITESPACE, '$1');

+        text = text.replace(regExp.WHITESPACE_IN_PARENTHESES, '($1)');

+		text = text.replace(regExp.MORE_WHITESPACE, ' ');

+		text = text.replace(regExp.FINAL_SEMICOLONS, '}'); // optional final semicolons

+		return text;

+	};

+

+	var objects = {

+	    stylesheet: function (el) {

+	        var o = {};

+	        var amqs = [], mqls = [], rs = [], rsw = [];

+	        var s = el.cssHelperText;

+

+	        // add attribute media queries

+	        var attr = el.getAttribute('media');

+	        if (attr) {

+	            var qts = attr.toLowerCase().split(',')

+	        }

+	        else {

+	            var qts = ['all'] // imply 'all'

+            }

+	        for (var i = 0; i < qts.length; i++) {

+	            amqs[amqs.length] = objects.mediaQuery(qts[i], o);

+	        }

+

+	        // add media query lists and rules (top down order)

+		    var blocks = s.match(regExp.BLOCKS); // @charset is not a block

+		    if (blocks !== null) {

+			    for (var i = 0; i < blocks.length; i++) {

+				    if (blocks[i].substring(0, 7) === '@media ') { // media query (list)

+					    var mql = objects.mediaQueryList(blocks[i], o);

+					    rs = rs.concat(mql.getRules());

+					    mqls[mqls.length] = mql;

+				    }

+				    else { // regular rule set, page context (@page) or font description (@font-face)

+					    rs[rs.length] = rsw[rsw.length] = objects.rule(blocks[i], o, null);

+				    }

+			    }

+		    }

+

+	        o.element = el;

+	        o.getCssText = function () {

+	            return s;

+	        };

+	        o.getAttrMediaQueries = function () {

+	            return amqs;

+	        };

+	        o.getMediaQueryLists = function () {

+	            return mqls;

+	        };

+	        o.getRules = function () {

+	            return rs;

+	        };

+	        o.getRulesWithoutMQ = function () {

+	            return rsw;

+	        };

+	        return o;

+	    },

+

+		mediaQueryList: function (s, stsh) {

+			var o = {};

+			var idx = s.indexOf('{');

+			var lt = s.substring(0, idx);

+			s = s.substring(idx + 1, s.length - 1);

+			var mqs = [], rs = [];

+

+			// add media queries

+			var qts = lt.toLowerCase().substring(7).split(',');

+			for (var i = 0; i < qts.length; i++) { // parse each media query

+				mqs[mqs.length] = objects.mediaQuery(qts[i], o);

+			}

+

+			// add rule sets

+			var rts = s.match(regExp.BLOCKS_INSIDE);

+			if (rts !== null) {

+				for (i = 0; i < rts.length; i++) {

+					rs[rs.length] = objects.rule(rts[i], stsh, o);

+				}

+			}

+

+			o.type = 'mediaQueryList';

+			o.getMediaQueries = function () {

+				return mqs;

+			};

+			o.getRules = function () {

+				return rs;

+			};

+			o.getListText = function () {

+				return lt;

+			};

+			o.getCssText = function () {

+				return s;

+			};

+			return o;

+		},

+

+		mediaQuery: function (s, listOrSheet) {

+			s = s || '';

+			var mql, stsh;

+			if (listOrSheet.type === 'mediaQueryList') {

+			    mql = listOrSheet;

+		    }

+		    else {

+		        stsh = listOrSheet;

+		    }

+			var not = false, type;

+			var expr = [];

+			var valid = true;

+			var tokens = s.match(regExp.NOT_WHITESPACE);

+

+

+

+			for (var i = 0; i < tokens.length; i++) {

+				var token = tokens[i];

+				if (!type && (token === 'not' || token === 'only')) { // 'not' and 'only' keywords

+					// keyword 'only' does nothing, as if it was not present

+					if (token === 'not') {

+						not = true;

+					}

+				}

+				else if (!type) { // media type

+					type = token;

+				}

+				else if (token.charAt(0) === '(') { // media feature expression

+					var pair = token.substring(1, token.length - 1).split(':');

+					expr[expr.length] = {

+						mediaFeature: pair[0],

+						value: pair[1] || null

+					};

+				}

+			}

+

+			return {

+			    getQueryText: function () {

+			        return s;

+			    },

+			    getAttrStyleSheet: function () {

+			        return stsh || null;

+			    },

+				getList: function () {

+					return mql || null;

+				},

+				getValid: function () {

+					return valid;

+				},

+				getNot: function () {

+					return not;

+				},

+				getMediaType: function () {

+					return type;

+				},

+				getExpressions: function () {

+					return expr;

+				}

+			};

+		},

+

+		rule: function (s, stsh, mql) {

+			var o = {};

+			var idx = s.indexOf('{');

+			var st = s.substring(0, idx);

+			var ss = st.split(',');

+			var ds = [];

+			var dts = s.substring(idx + 1, s.length - 1).split(';');

+			for (var i = 0; i < dts.length; i++) {

+				ds[ds.length] = objects.declaration(dts[i], o);

+			}

+

+			o.getStylesheet = function () {

+			    return stsh || null;

+			};

+			o.getMediaQueryList = function () {

+				return mql || null;

+			};

+			o.getSelectors = function () {

+				return ss;

+			};

+			o.getSelectorText = function () {

+				return st;

+			};

+			o.getDeclarations = function () {

+				return ds;

+			};

+			o.getPropertyValue = function (n) {

+				for (var i = 0; i < ds.length; i++) {

+					if (ds[i].getProperty() === n) {

+						return ds[i].getValue();

+					}

+				}

+				return null;

+			};

+			return o;

+		},

+

+		declaration: function (s, r) {

+			var idx = s.indexOf(':');

+			var p = s.substring(0, idx);

+			var v = s.substring(idx + 1);

+			return {

+				getRule: function () {

+					return r || null;

+				},

+				getProperty: function () {

+					return p;

+				},

+				getValue: function () {

+					return v;

+				}

+			};

+		}

+	};

+

+	var parseText = function (el) {

+		if (typeof el.cssHelperText !== 'string') {

+			return;

+		}

+		var o = {

+		    stylesheet: null,

+			mediaQueryLists: [],

+			rules: [],

+			selectors: {},

+			declarations: [],

+			properties: {}

+		};

+

+		// build stylesheet object

+		var stsh = o.stylesheet = objects.stylesheet(el);

+

+		// collect media query lists

+		var mqls = o.mediaQueryLists = stsh.getMediaQueryLists();

+

+		// collect all rules

+		var ors = o.rules = stsh.getRules();

+

+		// collect all selectors

+		var oss = o.selectors;

+		var collectSelectors = function (r) {

+			var ss = r.getSelectors();

+			for (var i = 0; i < ss.length; i++) {

+				var n = ss[i];

+				if (!oss[n]) {

+					oss[n] = [];

+				}

+				oss[n][oss[n].length] = r;

+			}

+		};

+		for (i = 0; i < ors.length; i++) {

+			collectSelectors(ors[i]);

+		}

+

+		// collect all declarations

+		var ods = o.declarations;

+		for (i = 0; i < ors.length; i++) {

+			ods = o.declarations = ods.concat(ors[i].getDeclarations());

+		}

+

+		// collect all properties

+		var ops = o.properties;

+		for (i = 0; i < ods.length; i++) {

+			var n = ods[i].getProperty();

+			if (!ops[n]) {

+				ops[n] = [];

+			}

+			ops[n][ops[n].length] = ods[i];

+		}

+

+		el.cssHelperParsed = o;

+		parsed[parsed.length] = el;

+		return o;

+	};

+

+	var parseEmbedded = function (el, s) {

+	    return;

+	    // This function doesn't work because of a bug in IE, where innerHTML gives us parsed css instead of raw literal.

+		el.cssHelperText = sanitize(s || el.innerHTML);

+		return parseText(el);

+	};

+

+	var parse = function () {

+		parsing = true;

+		parsed = [];

+		var linked = [];

+		var finish = function () {

+			for (var i = 0; i < linked.length; i++) {

+				parseText(linked[i]);

+			}

+			var styles = document.getElementsByTagName('style');

+			for (i = 0; i < styles.length; i++) {

+				parseEmbedded(styles[i]);

+			}

+			parsing = false;

+			ready();

+		};

+		var links = document.getElementsByTagName('link');

+		for (var i = 0; i < links.length; i++) {

+			var link = links[i];

+			if (link.getAttribute('rel').indexOf('style') > -1 && link.href && link.href.length !== 0 && !link.disabled) {

+				linked[linked.length] = link;

+			}

+		}

+		if (linked.length > 0) {

+			var c = 0;

+			var checkForFinish = function () {

+				c++;

+				if (c === linked.length) { // parse in right order, so after last link is read

+					finish();

+				}

+			};

+			var processLink = function (link) {

+				var href = link.href;

+				requestText(href, function (text) {

+					// fix url's

+					text = sanitize(text).replace(regExp.RELATIVE_URLS, 'url(' + href.substring(0, href.lastIndexOf('/')) + '/$1)');

+					link.cssHelperText = text;

+					checkForFinish();

+				}, checkForFinish);

+			};

+			for (i = 0; i < linked.length; i++) {

+				processLink(linked[i]);

+			}

+		}

+		else {

+			finish();

+		}

+	};

+

+	var types = {

+	    stylesheets: 'array',

+		mediaQueryLists: 'array',

+		rules: 'array',

+		selectors: 'object',

+		declarations: 'array',

+		properties: 'object'

+	};

+

+	var collections = {

+	    stylesheets: null,

+		mediaQueryLists: null,

+		rules: null,

+		selectors: null,

+		declarations: null,

+		properties: null

+	};

+

+	var addToCollection = function (name, v) {

+		if (collections[name] !== null) {

+			if (types[name] === 'array') {

+				return (collections[name] = collections[name].concat(v));

+			}

+			else {

+				var c = collections[name];

+				for (var n in v) {

+					if (v.hasOwnProperty(n)) {

+						if (!c[n]) {

+							c[n] = v[n];

+						}

+						else {

+							c[n] = c[n].concat(v[n]);

+						}

+					}

+				}

+				return c;

+			}

+		}

+	};

+

+	var collect = function (name) {

+		collections[name] = (types[name] === 'array') ? [] : {};

+		for (var i = 0; i < parsed.length; i++) {

+		    var pname = name === 'stylesheets' ? 'stylesheet' : name; // the exception

+			addToCollection(name, parsed[i].cssHelperParsed[pname]);

+		}

+		return collections[name];

+	};

+

+	// viewport size

+	var getViewportSize = function (d) {

+		if (typeof window.innerWidth != 'undefined') {

+			return window['inner' + d];

+		}

+		else if (typeof document.documentElement !== 'undefined'

+				&& typeof document.documentElement.clientWidth !== 'undefined'

+				&& document.documentElement.clientWidth != 0) {

+			return document.documentElement['client' + d];

+		}

+	};

+

+	// public static functions

+	return {

+		addStyle: function (s, mediaTypes, process) {

+			var el = document.createElement('style');

+			el.setAttribute('type', 'text/css');

+			if (mediaTypes && mediaTypes.length > 0) {

+			    el.setAttribute('media', mediaTypes.join(','));

+			}

+			document.getElementsByTagName('head')[0].appendChild(el);

+			if (el.styleSheet) { // IE

+				el.styleSheet.cssText = s;

+			}

+			else {

+				el.appendChild(document.createTextNode(s));

+			}

+			el.addedWithCssHelper = true;

+			if (typeof process === 'undefined' || process === true) {

+				cssHelper.parsed(function (parsed) {

+					var o = parseEmbedded(el, s);

+					for (var n in o) {

+						if (o.hasOwnProperty(n)) {

+							addToCollection(n, o[n]);

+						}

+					}

+					broadcast('newStyleParsed', el);

+				});

+			}

+			else {

+				el.parsingDisallowed = true;

+			}

+			return el;

+		},

+

+		removeStyle: function (el) {

+			return el.parentNode.removeChild(el);

+		},

+

+		parsed: function (fn) {

+			if (parsing) {

+				wait(fn);

+			}

+			else {

+				if (typeof parsed !== 'undefined') {

+					if (typeof fn === 'function') {

+						fn(parsed);

+					}

+				}

+				else {

+					wait(fn);

+					parse();

+				}

+			}

+		},

+

+		stylesheets: function (fn) {

+		    cssHelper.parsed(function (parsed) {

+		        fn(collections.stylesheets || collect('stylesheets'));

+		    });

+		},

+

+		mediaQueryLists: function (fn) {

+			cssHelper.parsed(function (parsed) {

+				fn(collections.mediaQueryLists || collect('mediaQueryLists'));

+			});

+		},

+

+		rules: function (fn) {

+			cssHelper.parsed(function (parsed) {

+				fn(collections.rules || collect('rules'));

+			});

+		},

+

+		selectors: function (fn) {

+			cssHelper.parsed(function (parsed) {

+				fn(collections.selectors || collect('selectors'));

+			});

+		},

+

+		declarations: function (fn) {

+			cssHelper.parsed(function (parsed) {

+				fn(collections.declarations || collect('declarations'));

+			});

+		},

+

+		properties: function (fn) {

+			cssHelper.parsed(function (parsed) {

+				fn(collections.properties || collect('properties'));

+			});

+		},

+

+		broadcast: broadcast,

+

+		addListener: function (n, fn) { // in case n is 'styleadd': added function is called everytime style is added and parsed

+			if (typeof fn === 'function') {

+				if (!events[n]) {

+					events[n] = {

+						listeners: []

+					};

+				}

+				events[n].listeners[events[n].listeners.length] = fn;

+			}

+		},

+

+		removeListener: function (n, fn) {

+			if (typeof fn === 'function' && events[n]) {

+				var ls = events[n].listeners;

+				for (var i = 0; i < ls.length; i++) {

+					if (ls[i] === fn) {

+						ls.splice(i, 1);

+						i -= 1;

+					}

+				}

+			}

+		},

+

+		getViewportWidth: function () {

+			return getViewportSize('Width');

+		},

+

+		getViewportHeight: function () {

+			return getViewportSize('Height');

+		}

+	};

+}();

+

+

+

+// function to test and apply parsed media queries against browser capabilities

+domReady(function enableCssMediaQueries() {

+	var meter;

+

+	var regExp = {

+		LENGTH_UNIT: /[0-9]+(em|ex|px|in|cm|mm|pt|pc)$/,

+		RESOLUTION_UNIT: /[0-9]+(dpi|dpcm)$/,

+		ASPECT_RATIO: /^[0-9]+\/[0-9]+$/,

+		ABSOLUTE_VALUE: /^[0-9]*(\.[0-9]+)*$/

+	};

+

+	var styles = [];

+

+	var nativeSupport = function () {

+		// check support for media queries

+		var id = 'css3-mediaqueries-test';

+		var el = document.createElement('div');

+		el.id = id;

+		var style = cssHelper.addStyle('@media all and (width) { #' + id +

+			' { width: 1px !important; } }', [], false); // false means don't parse this temp style

+		document.body.appendChild(el);

+		var ret = el.offsetWidth === 1;

+		style.parentNode.removeChild(style);

+		el.parentNode.removeChild(el);

+		nativeSupport = function () {

+			return ret;

+		};

+		return ret;

+	};

+

+	var createMeter = function () { // create measuring element

+		meter = document.createElement('div');

+		meter.style.cssText = 'position:absolute;top:-9999em;left:-9999em;' +

+			'margin:0;border:none;padding:0;width:1em;font-size:1em;'; // cssText is needed for IE, works for the others

+		document.body.appendChild(meter);

+		// meter must have browser default font size of 16px

+		if (meter.offsetWidth !== 16) {

+			meter.style.fontSize = 16 / meter.offsetWidth + 'em';

+		}

+		meter.style.width = '';

+	};

+

+	var measure = function (value) {

+		meter.style.width = value;

+		var amount = meter.offsetWidth;

+		meter.style.width = '';

+		return amount;

+	};

+

+	var testMediaFeature = function (feature, value) {

+		// non-testable features: monochrome|min-monochrome|max-monochrome|scan|grid

+		var l = feature.length;

+		var min = (feature.substring(0, 4) === 'min-');

+		var max = (!min && feature.substring(0, 4) === 'max-');

+

+		if (value !== null) { // determine value type and parse to usable amount

+			var valueType;

+			var amount;

+			if (regExp.LENGTH_UNIT.exec(value)) {

+				valueType = 'length';

+				amount = measure(value);

+			}

+			else if (regExp.RESOLUTION_UNIT.exec(value)) {

+				valueType = 'resolution';

+				amount = parseInt(value, 10);

+				var unit = value.substring((amount + '').length);

+			}

+			else if (regExp.ASPECT_RATIO.exec(value)) {

+				valueType = 'aspect-ratio';

+				amount = value.split('/');

+			}

+			else if (regExp.ABSOLUTE_VALUE) {

+				valueType = 'absolute';

+				amount = value;

+			}

+			else {

+				valueType = 'unknown';

+			}

+		}

+

+		var width, height;

+		if ('device-width' === feature.substring(l - 12, l)) { // screen width

+			width = screen.width;

+			if (value !== null) {

+				if (valueType === 'length') {

+					return ((min && width >= amount) || (max && width < amount) || (!min && !max && width === amount));

+				}

+				else {

+					return false;

+				}

+			}

+			else { // test width without value

+				return width > 0;

+			}

+		}

+		else if ('device-height' === feature.substring(l - 13, l)) { // screen height

+			height = screen.height;

+			if (value !== null) {

+				if (valueType === 'length') {

+					return ((min && height >= amount) || (max && height < amount) || (!min && !max && height === amount));

+				}

+				else {

+					return false;

+				}

+			}

+			else { // test height without value

+				return height > 0;

+			}

+		}

+		else if ('width' === feature.substring(l - 5, l)) { // viewport width

+			width = document.documentElement.clientWidth || document.body.clientWidth; // the latter for IE quirks mode

+			if (value !== null) {

+				if (valueType === 'length') {

+					return ((min && width >= amount) || (max && width < amount) || (!min && !max && width === amount));

+				}

+				else {

+					return false;

+				}

+			}

+			else { // test width without value

+				return width > 0;

+			}

+		}

+		else if ('height' === feature.substring(l - 6, l)) { // viewport height

+			height = document.documentElement.clientHeight || document.body.clientHeight; // the latter for IE quirks mode

+			if (value !== null) {

+				if (valueType === 'length') {

+					return ((min && height >= amount) || (max && height < amount) || (!min && !max && height === amount));

+				}

+				else {

+					return false;

+				}

+			}

+			else { // test height without value

+				return height > 0;

+			}

+		}

+		else if ('device-aspect-ratio' === feature.substring(l - 19, l)) { // screen aspect ratio

+			return valueType === 'aspect-ratio' && screen.width * amount[1] === screen.height * amount[0];

+		}

+		else if ('color-index' === feature.substring(l - 11, l)) { // number of colors

+			var colors = Math.pow(2, screen.colorDepth);

+			if (value !== null) {

+				if (valueType === 'absolute') {

+					return ((min && colors >= amount) || (max && colors < amount) || (!min && !max && colors === amount));

+				}

+				else {

+					return false;

+				}

+			}

+			else { // test height without value

+				return colors > 0;

+			}

+		}

+		else if ('color' === feature.substring(l - 5, l)) { // bits per color component

+			var color = screen.colorDepth;

+			if (value !== null) {

+				if (valueType === 'absolute') {

+					return ((min && color >= amount) || (max && color < amount) || (!min && !max && color === amount));

+				}

+				else {

+					return false;

+				}

+			}

+			else { // test height without value

+				return color > 0;

+			}

+		}

+		else if ('resolution' === feature.substring(l - 10, l)) {

+			var res;

+			if (unit === 'dpcm') {

+				res = measure('1cm');

+			}

+			else {

+				res = measure('1in');

+			}

+			if (value !== null) {

+				if (valueType === 'resolution') {

+					return ((min && res >= amount) || (max && res < amount) || (!min && !max && res === amount));

+				}

+				else {

+					return false;

+				}

+			}

+			else { // test height without value

+				return res > 0;

+			}

+		}

+		else {

+			return false;

+		}

+	};

+

+	var testMediaQuery = function (mq) {

+		var test = mq.getValid();

+		var expressions = mq.getExpressions();

+		var l = expressions.length;

+		if (l > 0) {

+			for (var i = 0; i < l && test; i++) {

+				test = testMediaFeature(expressions[i].mediaFeature, expressions[i].value);

+			}

+			var not = mq.getNot();

+			return (test && !not || not && !test);

+		}

+		return test;

+	};

+

+	var testMediaQueryList = function (mql, ts) {

+	    // ts is null or an array with any media type but 'all'.

+		var mqs = mql.getMediaQueries();

+		var t = {};

+		for (var i = 0; i < mqs.length; i++) {

+		    var type = mqs[i].getMediaType();

+		    if (mqs[i].getExpressions().length === 0) {

+		        continue;

+		        // TODO: Browser check! Assuming old browsers do apply the bare media types, even in a list with media queries.

+		    }

+		    var typeAllowed = true;

+		    if (type !== 'all' && ts && ts.length > 0) {

+		        typeAllowed = false;

+		        for (var j = 0; j < ts.length; j++) {

+		            if (ts[j] === type) {

+		                typeAllowed = true;

+                    }

+		        }

+		    }

+			if (typeAllowed && testMediaQuery(mqs[i])) {

+				t[type] = true;

+			}

+		}

+		var s = [], c = 0;

+		for (var n in t) {

+			if (t.hasOwnProperty(n)) {

+				if (c > 0) {

+					s[c++] = ',';

+				}

+				s[c++] = n;

+			}

+		}

+		if (s.length > 0) {

+			styles[styles.length] = cssHelper.addStyle('@media ' + s.join('') + '{' + mql.getCssText() + '}', ts, false);

+		}

+	};

+

+	var testMediaQueryLists = function (mqls, ts) {

+		for (var i = 0; i < mqls.length; i++) {

+			testMediaQueryList(mqls[i], ts);

+		}

+	};

+

+	var testStylesheet = function (stsh) {

+	    var amqs = stsh.getAttrMediaQueries();

+	    var allPassed = false;

+	    var t = {};

+		for (var i = 0; i < amqs.length; i++) {

+			if (testMediaQuery(amqs[i])) {

+				t[amqs[i].getMediaType()] = amqs[i].getExpressions().length > 0;

+			}

+		}

+		var ts = [], tswe = [];

+		for (var n in t) {

+			if (t.hasOwnProperty(n)) {

+				ts[ts.length] = n;

+				if (t[n]) {

+				    tswe[tswe.length] = n

+				}

+			    if (n === 'all') {

+			        allPassed = true;

+                }

+			}

+		}

+		if (tswe.length > 0) { // types with query expressions that passed the test

+		    styles[styles.length] = cssHelper.addStyle(stsh.getCssText(), tswe, false);

+		}

+		var mqls = stsh.getMediaQueryLists();

+		if (allPassed) {

+		    // If 'all' in media attribute passed the test, then test all @media types in linked CSS and create style with those types.

+		    testMediaQueryLists(mqls);

+		}

+		else {

+		    // Or else, test only media attribute types that passed the test and also 'all'.

+		    // For positive '@media all', create style with attribute types that passed their test.

+		    testMediaQueryLists(mqls, ts);

+	    }

+    };

+

+	var testStylesheets = function (stshs) {

+	    for (var i = 0; i < stshs.length; i++) {

+	        testStylesheet(stshs[i]);

+	    }

+	    if (ua.ie) {

+			// force repaint in IE

+			document.documentElement.style.display = 'block';

+			setTimeout(function () {

+				document.documentElement.style.display = '';

+			}, 0);

+			// delay broadcast somewhat for IE

+			setTimeout(function () {

+				cssHelper.broadcast('cssMediaQueriesTested');

+			}, 100);

+		}

+		else {

+			cssHelper.broadcast('cssMediaQueriesTested');

+		}

+	};

+

+	var test = function () {

+		for (var i = 0; i < styles.length; i++) {

+			cssHelper.removeStyle(styles[i]);

+		}

+		styles = [];

+		cssHelper.stylesheets(testStylesheets);

+	};

+

+	var scrollbarWidth = 0;

+	var checkForResize = function () {

+		var cvpw = cssHelper.getViewportWidth();

+		var cvph = cssHelper.getViewportHeight();

+

+		// determine scrollbar width in IE, see resizeHandler

+		if (ua.ie) {

+			var el = document.createElement('div');

+			el.style.position = 'absolute';

+			el.style.top = '-9999em';

+			el.style.overflow = 'scroll';

+			document.body.appendChild(el);

+			scrollbarWidth = el.offsetWidth - el.clientWidth;

+			document.body.removeChild(el);

+		}

+

+		var timer;

+		var resizeHandler = function () {

+			var vpw = cssHelper.getViewportWidth();

+			var vph = cssHelper.getViewportHeight();

+			// check whether vp size has really changed, because IE also triggers resize event when body size changes

+			// 20px allowance to accomodate short appearance of scrollbars in IE in some cases

+			if (Math.abs(vpw - cvpw) > scrollbarWidth || Math.abs(vph - cvph) > scrollbarWidth) {

+				cvpw = vpw;

+				cvph = vph;

+				clearTimeout(timer);

+				timer = setTimeout(function () {

+					if (!nativeSupport()) {

+						test();

+					}

+					else {

+						cssHelper.broadcast('cssMediaQueriesTested');

+					}

+				}, 500);

+			}

+		};

+

+		window.onresize = function () {

+			var x = window.onresize || function () {}; // save original

+			return function () {

+				x();

+				resizeHandler();

+			};

+		}();

+	};

+

+	// prevent jumping of layout by hiding everything before painting <body>

+    var docEl = document.documentElement;

+	docEl.style.marginLeft = '-32767px';

+

+	// make sure it comes back after a while

+	setTimeout(function () {

+		docEl.style.marginLeft = '';

+	}, 5000);

+

+	return function () {

+		if (!nativeSupport()) { // if browser doesn't support media queries

+			cssHelper.addListener('newStyleParsed', function (el) {

+				testStylesheet(el.cssHelperParsed.stylesheet);

+			});

+			// return visibility after media queries are tested

+			cssHelper.addListener('cssMediaQueriesTested', function () {

+				// force repaint in IE by changing width

+				if (ua.ie) {

+					docEl.style.width = '1px';

+				}

+				setTimeout(function () {

+					docEl.style.width = ''; // undo width

+					docEl.style.marginLeft = ''; // undo hide

+				}, 0);

+				// remove this listener to prevent following execution

+				cssHelper.removeListener('cssMediaQueriesTested', arguments.callee);

+			});

+			createMeter();

+			test();

+		}

+		else {

+			docEl.style.marginLeft = ''; // undo visibility hidden

+		}

+		checkForResize();

+	};

+}());

+

+

+// bonus: hotfix for IE6 SP1 (bug KB823727)

+try {

+	document.execCommand('BackgroundImageCache', false, true);

+} catch (e) {}

diff --git a/sphinx/themes/bizstyle/theme.conf b/sphinx/themes/bizstyle/theme.conf
new file mode 100644
index 0000000..724eb12
--- /dev/null
+++ b/sphinx/themes/bizstyle/theme.conf
@@ -0,0 +1,9 @@
+[theme]
+inherit = basic
+stylesheet = bizstyle.css
+pygments_style = friendly
+
+[options]
+rightsidebar = false
+
+maincolor = #336699
diff --git a/sphinx/themes/default/static/default.css_t b/sphinx/themes/default/static/default.css_t
index cbdc7fb..137a9e7 100644
--- a/sphinx/themes/default/static/default.css_t
+++ b/sphinx/themes/default/static/default.css_t
@@ -281,7 +281,7 @@
     border-right: none;
 }
 
-tt {
+code {
     background-color: #ecf0f3;
     padding: 0 1px 0 1px;
     font-size: 0.95em;
@@ -291,11 +291,11 @@
     background-color: #ede;
 }
 
-.warning tt {
+.warning code {
     background: #efc2c2;
 }
 
-.note tt {
+.note code {
     background: #d6d6d6;
 }
 
@@ -308,3 +308,8 @@
     border-top: 1px solid #ac9;
     border-bottom: 1px solid #ac9;
 }
+
+div.code-block-caption {
+    color: #efefef;
+    background-color: #1c4e63;
+}
diff --git a/sphinx/themes/epub/static/epub.css b/sphinx/themes/epub/static/epub.css
index 30912b9..a03c062 100644
--- a/sphinx/themes/epub/static/epub.css
+++ b/sphinx/themes/epub/static/epub.css
@@ -363,6 +363,10 @@
     font-size: 130%;
 }
 
+.sig-paren {
+    font-size: larger;
+}
+
 .versionmodified {
     font-style: italic;
 }
@@ -429,26 +433,26 @@
     padding: 0 0.5em 0 0.5em;
 }
 
-tt {
+code {
     font-family: monospace;
 }
 
-tt.descname {
+code.descname {
     background-color: transparent;
     font-weight: bold;
     font-size: 1.2em;
 }
 
-tt.descclassname {
+code.descclassname {
     background-color: transparent;
 }
 
-tt.xref, a tt {
+code.xref, a code {
     background-color: transparent;
     font-weight: bold;
 }
 
-h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
     background-color: transparent;
 }
 
@@ -531,4 +535,4 @@
     src: url("res:///Data/fonts/LiberationNarrow-BoldItalic.otf")
         format("opentype");
 }
-*/
\ No newline at end of file
+*/
diff --git a/sphinx/themes/haiku/layout.html b/sphinx/themes/haiku/layout.html
index 569763b..20d5d3f 100644
--- a/sphinx/themes/haiku/layout.html
+++ b/sphinx/themes/haiku/layout.html
@@ -32,7 +32,7 @@
 {% endmacro %}
 
 {% block content %}
-      <div class="header">
+      <div class="header" role="banner">
         {%- block haikuheader %}
         {%- if theme_full_logo != "false" %}
         <a href="{{ pathto('index') }}">
@@ -48,7 +48,7 @@
         {%- endif %}
         {%- endblock %}
       </div>
-      <div class="topnav">
+      <div class="topnav" role="navigation" aria-label="top navigation">
       {{ nav() }}
       </div>
       <div class="content">
@@ -60,7 +60,7 @@
         {%- endif %}#}
         {% block body %}{% endblock %}
       </div>
-      <div class="bottomnav">
+      <div class="bottomnav" role="navigation" aria-label="bottom navigation">
       {{ nav() }}
       </div>
 {% endblock %}
diff --git a/sphinx/themes/haiku/static/bg-page.png b/sphinx/themes/haiku/static/bg-page.png
index c6f3bc4..0103ee1 100644
--- a/sphinx/themes/haiku/static/bg-page.png
+++ b/sphinx/themes/haiku/static/bg-page.png
Binary files differ
diff --git a/sphinx/themes/haiku/static/haiku.css_t b/sphinx/themes/haiku/static/haiku.css_t
index bd81db0..c6cb42d 100644
--- a/sphinx/themes/haiku/static/haiku.css_t
+++ b/sphinx/themes/haiku/static/haiku.css_t
@@ -307,7 +307,7 @@
     vertical-align: top;
 }
 
-tt {
+code {
     background-color: #e2e2e2;
     font-size: 1.0em;
     font-family: monospace;
diff --git a/sphinx/themes/nature/static/nature.css_t b/sphinx/themes/nature/static/nature.css_t
index ff89148..8818e44 100644
--- a/sphinx/themes/nature/static/nature.css_t
+++ b/sphinx/themes/nature/static/nature.css_t
@@ -226,7 +226,7 @@
     -moz-box-shadow: 1px 1px 1px #d8d8d8;
 }
  
-tt {
+code {
     background-color: #ecf0f3;
     color: #222;
     /* padding: 1px 2px; */
@@ -243,3 +243,9 @@
     border-top: 1px solid #ac9;
     border-bottom: 1px solid #ac9;
 }
+
+div.code-block-caption {
+    background-color: #ddd;
+    color: #222;
+    border: 1px solid #C6C9CB;
+}
diff --git a/sphinx/themes/pyramid/layout.html b/sphinx/themes/pyramid/layout.html
index 8780cea..318a366 100644
--- a/sphinx/themes/pyramid/layout.html
+++ b/sphinx/themes/pyramid/layout.html
@@ -10,7 +10,7 @@
 
 {% block header %}
 {%- if logo %}
-<div class="header">
+<div class="header" role="banner">
   <div class="logo">
     <a href="{{ pathto(master_doc) }}">
       <img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/>
diff --git a/sphinx/themes/pyramid/static/dialog-note.png b/sphinx/themes/pyramid/static/dialog-note.png
index 263fbd5..7086821 100644
--- a/sphinx/themes/pyramid/static/dialog-note.png
+++ b/sphinx/themes/pyramid/static/dialog-note.png
Binary files differ
diff --git a/sphinx/themes/pyramid/static/dialog-seealso.png b/sphinx/themes/pyramid/static/dialog-seealso.png
index 3eb7b05..a27a0fc 100644
--- a/sphinx/themes/pyramid/static/dialog-seealso.png
+++ b/sphinx/themes/pyramid/static/dialog-seealso.png
Binary files differ
diff --git a/sphinx/themes/pyramid/static/dialog-todo.png b/sphinx/themes/pyramid/static/dialog-todo.png
index babc4b6..9caa91e 100644
--- a/sphinx/themes/pyramid/static/dialog-todo.png
+++ b/sphinx/themes/pyramid/static/dialog-todo.png
Binary files differ
diff --git a/sphinx/themes/pyramid/static/dialog-warning.png b/sphinx/themes/pyramid/static/dialog-warning.png
index 7233d45..4f598b1 100644
--- a/sphinx/themes/pyramid/static/dialog-warning.png
+++ b/sphinx/themes/pyramid/static/dialog-warning.png
Binary files differ
diff --git a/sphinx/themes/pyramid/static/epub.css b/sphinx/themes/pyramid/static/epub.css
index 7465a42..6038375 100644
--- a/sphinx/themes/pyramid/static/epub.css
+++ b/sphinx/themes/pyramid/static/epub.css
@@ -281,7 +281,7 @@
     border-right: none;
 }
 
-tt {
+code {
     background-color: #ecf0f3;
     padding: 0 1px 0 1px;
     font-size: 0.95em;
@@ -291,11 +291,11 @@
     background-color: #ede;
 }
 
-.warning tt {
+.warning code {
     background: #efc2c2;
 }
 
-.note tt {
+.note code {
     background: #d6d6d6;
 }
 
diff --git a/sphinx/themes/pyramid/static/middlebg.png b/sphinx/themes/pyramid/static/middlebg.png
index 2369cfb..b3a89f4 100644
--- a/sphinx/themes/pyramid/static/middlebg.png
+++ b/sphinx/themes/pyramid/static/middlebg.png
Binary files differ
diff --git a/sphinx/themes/pyramid/static/pyramid.css_t b/sphinx/themes/pyramid/static/pyramid.css_t
index 168e52d..f60f82d 100644
--- a/sphinx/themes/pyramid/static/pyramid.css_t
+++ b/sphinx/themes/pyramid/static/pyramid.css_t
@@ -295,7 +295,7 @@
     border-left-style: none;
 }
  
-tt {
+code {
     background-color: transparent;
     color: #222;
     font-size: 1.1em;
@@ -336,7 +336,12 @@
     font-style: normal;
 }
 
-tt.xref {
+code.xref {
     font-weight: normal;
     font-style: normal;
 }
+
+div.code-block-caption {
+    background-color: #ddd;
+    color: #222;
+}
diff --git a/sphinx/themes/scrolls/layout.html b/sphinx/themes/scrolls/layout.html
index a27f60a..0940d22 100644
--- a/sphinx/themes/scrolls/layout.html
+++ b/sphinx/themes/scrolls/layout.html
@@ -20,7 +20,7 @@
         <h1 class="heading"><a href="{{ pathto('index') }}"
           title="back to the documentation overview"><span>{{ title|striptags|e }}</span></a></h1>
       </div>
-      <div class="relnav">
+      <div class="relnav" role="navigation" aria-label="related navigation">
         {%- if prev %}
         <a href="{{ prev.link|e }}">&laquo; {{ prev.title }}</a> |
         {%- endif %}
@@ -31,7 +31,7 @@
       </div>
       <div id="contentwrapper">
         {%- if display_toc %}
-        <div id="toc">
+        <div id="toc" role="navigation" aria-label="table of contents navigation">
           <h3>{{ _('Table Of Contents') }}</h3>
           {{ toc }}
         </div>
diff --git a/sphinx/themes/scrolls/static/darkmetal.png b/sphinx/themes/scrolls/static/darkmetal.png
index e8c9ff6..3ed486d 100644
--- a/sphinx/themes/scrolls/static/darkmetal.png
+++ b/sphinx/themes/scrolls/static/darkmetal.png
Binary files differ
diff --git a/sphinx/themes/scrolls/static/logo.png b/sphinx/themes/scrolls/static/logo.png
index d1961cf..3dc573e 100644
--- a/sphinx/themes/scrolls/static/logo.png
+++ b/sphinx/themes/scrolls/static/logo.png
Binary files differ
diff --git a/sphinx/themes/scrolls/static/metal.png b/sphinx/themes/scrolls/static/metal.png
index 97166f1..e51010b 100644
--- a/sphinx/themes/scrolls/static/metal.png
+++ b/sphinx/themes/scrolls/static/metal.png
Binary files differ
diff --git a/sphinx/themes/scrolls/static/navigation.png b/sphinx/themes/scrolls/static/navigation.png
index 1e248d4..5be5b31 100644
--- a/sphinx/themes/scrolls/static/navigation.png
+++ b/sphinx/themes/scrolls/static/navigation.png
Binary files differ
diff --git a/sphinx/themes/scrolls/static/scrolls.css_t b/sphinx/themes/scrolls/static/scrolls.css_t
index 197aef2..9591f04 100644
--- a/sphinx/themes/scrolls/static/scrolls.css_t
+++ b/sphinx/themes/scrolls/static/scrolls.css_t
@@ -195,7 +195,7 @@
     font-family: 'Bitstream Vera Sans Mono', 'Monaco', monospace;
 }
 
-tt {
+code {
     font-size: 13px;
     font-family: 'Bitstream Vera Sans Mono', 'Monaco', monospace;
     color: black;
@@ -204,7 +204,7 @@
     border-bottom: 1px solid #eee;
 }
 
-a.reference:hover tt {
+a.reference:hover code {
     border-bottom-color: #aaa;
 }
 
@@ -305,6 +305,10 @@
     margin-right: 4px;
 }
 
+dt .sig-paren {
+    font-size: larger;
+}
+
 dt .descname, dt .descclassname {
     padding: 0;
     background: transparent;
diff --git a/sphinx/themes/scrolls/static/watermark.png b/sphinx/themes/scrolls/static/watermark.png
index eb1b6be..903a96e 100644
--- a/sphinx/themes/scrolls/static/watermark.png
+++ b/sphinx/themes/scrolls/static/watermark.png
Binary files differ
diff --git a/sphinx/themes/scrolls/static/watermark_blur.png b/sphinx/themes/scrolls/static/watermark_blur.png
index 563f6cd..0226900 100644
--- a/sphinx/themes/scrolls/static/watermark_blur.png
+++ b/sphinx/themes/scrolls/static/watermark_blur.png
Binary files differ
diff --git a/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t b/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t
index 0f3b9aa..90b5d23 100644
--- a/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t
+++ b/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t
@@ -204,20 +204,20 @@
     color: white!important;
 }
 
-cite, code, tt {
+cite, code, code {
     font-family: 'Consolas', 'Deja Vu Sans Mono',
                  'Bitstream Vera Sans Mono', monospace;
     font-size: 0.95em;
     letter-spacing: 0.01em;
 }
 
-tt {
+code {
     background-color: #f2f2f2;
     border-bottom: 1px solid #ddd;
     color: #333;
 }
 
-tt.descname, tt.descclassname, tt.xref {
+code.descname, code.descclassname, code.xref {
     border: 0;
 }
 
@@ -226,12 +226,12 @@
     margin: 2em;
 }
 
-a tt {
+a code {
     border: 0;
     color: #CA7900;
 }
 
-a tt:hover {
+a code:hover {
     color: #2491CF;
 }
 
@@ -337,3 +337,9 @@
     border-top: 1px solid #ac9;
     border-bottom: 1px solid #ac9;
 }
+
+div.code-block-caption {
+    background-color: #ddd;
+    color: #222;
+    border: 1px solid #ccc;
+}
diff --git a/sphinx/themes/traditional/static/traditional.css_t b/sphinx/themes/traditional/static/traditional.css_t
index c0328b2..4efb1ff 100644
--- a/sphinx/themes/traditional/static/traditional.css_t
+++ b/sphinx/themes/traditional/static/traditional.css_t
@@ -318,7 +318,7 @@
 }
 
 div#comments div.comment pre,
-div#comments div.comment tt {
+div#comments div.comment code {
     background-color: #ddd;
     color: #111;
     border: none;
@@ -616,23 +616,23 @@
     border-right: none;
 }
 
-tt {
+code {
     font-family: monospace;
     background-color: #ecf0f3;
     padding: 0 1px 0 1px;
 }
 
-tt.descname {
+code.descname {
     background-color: transparent;
     font-weight: bold;
     font-size: 1.2em;
 }
 
-tt.descclassname {
+code.descclassname {
     background-color: transparent;
 }
 
-tt.xref, a tt {
+code.xref, a code {
     background-color: transparent;
     font-weight: bold;
 }
@@ -651,7 +651,7 @@
     margin-left: 1.5em;
 }
 
-h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
     background-color: transparent;
 }
 
@@ -659,6 +659,10 @@
     font-size: 1.3em;
 }
 
+.sig-paren {
+    font-size: larger;
+}
+
 .versionmodified {
     font-style: italic;
 }
@@ -698,3 +702,7 @@
     margin: -1px -10px;
     padding: 0 10px;
 }
+
+div.code-block-caption {
+    background-color: #cceeff;
+}
diff --git a/sphinx/theming.py b/sphinx/theming.py
index abc09c1..41cbcae 100644
--- a/sphinx/theming.py
+++ b/sphinx/theming.py
@@ -13,9 +13,11 @@
 import shutil
 import zipfile
 import tempfile
-import ConfigParser
 from os import path
 
+from six import string_types, iteritems
+from six.moves import configparser
+
 try:
     import pkg_resources
 except ImportError:
@@ -100,12 +102,12 @@
                 fp.write(tinfo.read(name))
                 fp.close()
 
-        self.themeconf = ConfigParser.RawConfigParser()
+        self.themeconf = configparser.RawConfigParser()
         self.themeconf.read(path.join(self.themedir, THEMECONF))
 
         try:
             inherit = self.themeconf.get('theme', 'inherit')
-        except ConfigParser.NoOptionError:
+        except configparser.NoOptionError:
             raise ThemeError('theme %r doesn\'t have "inherit" setting' % name)
         if inherit == 'none':
             self.base = None
@@ -121,7 +123,7 @@
         """
         try:
             return self.themeconf.get(section, name)
-        except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
+        except (configparser.NoOptionError, configparser.NoSectionError):
             if self.base is not None:
                 return self.base.get_confstr(section, name, default)
             if default is NODEFAULT:
@@ -141,9 +143,9 @@
         for conf in reversed(chain):
             try:
                 options.update(conf.items('options'))
-            except ConfigParser.NoSectionError:
+            except configparser.NoSectionError:
                 pass
-        for option, value in overrides.iteritems():
+        for option, value in iteritems(overrides):
             if option not in options:
                 raise ThemeError('unsupported theme option %r given' % option)
             options[option] = value
@@ -188,7 +190,7 @@
         except:
             path = func_or_path
 
-        if isinstance(path, basestring):
+        if isinstance(path, string_types):
             theme_paths.append(path)
         else:
             raise ThemeError('Plugin %r does not response correctly.' %
diff --git a/sphinx/transforms.py b/sphinx/transforms.py
index 0e103ac..0e0f833 100644
--- a/sphinx/transforms.py
+++ b/sphinx/transforms.py
@@ -22,8 +22,6 @@
 from sphinx.util import split_index_msg
 from sphinx.util.nodes import traverse_translatable_index, extract_messages
 from sphinx.util.osutil import ustrftime, find_catalog
-from sphinx.util.compat import docutils_version
-from sphinx.util.pycompat import all
 from sphinx.domains.std import (
     make_term_from_paragraph_node,
     make_termnodes_from_paragraph_node,
@@ -70,7 +68,7 @@
         for node in self.document.traverse(nodes.target):
             if not node['ids']:
                 continue
-            if (node.has_key('ismod') and
+            if ('ismod' in node and
                 node.parent.__class__ is nodes.section and
                 # index 0 is the section title node
                 node.parent.index(node) == 1):
@@ -143,10 +141,7 @@
         self.source, self.line = source, line
 
     def set_reporter(self, document):
-        if docutils_version < (0, 9):
-            document.reporter.locator = self.get_source_and_line
-        else:
-            document.reporter.get_source_and_line = self.get_source_and_line
+        document.reporter.get_source_and_line = self.get_source_and_line
 
     def get_source_and_line(self, lineno=None):
         return self.source, self.line
diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py
index 91b7111..3a4334e 100644
--- a/sphinx/util/__init__.py
+++ b/sphinx/util/__init__.py
@@ -21,6 +21,8 @@
 from codecs import open, BOM_UTF8
 from collections import deque
 
+from six import iteritems, text_type, binary_type
+from six.moves import range
 import docutils
 from docutils.utils import relative_path
 
@@ -28,7 +30,6 @@
 
 import sphinx
 from sphinx.errors import PycodeError
-from sphinx.util.pycompat import bytes
 from sphinx.util.console import strip_colors
 
 # import other utilities; partly for backwards compatibility, so don't
@@ -54,7 +55,7 @@
 def path_stabilize(filepath):
     "normalize path separater and unicode string"
     newpath = filepath.replace(os.path.sep, SEP)
-    if isinstance(newpath, unicode):
+    if isinstance(newpath, text_type):
         newpath = unicodedata.normalize('NFC', newpath)
     return newpath
 
@@ -122,7 +123,7 @@
         return uniquename
 
     def purge_doc(self, docname):
-        for filename, (docs, unique) in self.items():
+        for filename, (docs, unique) in list(self.items()):
             docs.discard(docname)
             if not docs:
                 del self[filename]
@@ -198,9 +199,10 @@
                    jinja2.__version__,
                    last_msgs)).encode('utf-8'))
     if app is not None:
-        for extname, extmod in app._extensions.iteritems():
-            os.write(fd, ('#   %s from %s\n' % (
-                extname, getattr(extmod, '__file__', 'unknown'))
+        for extname, extmod in iteritems(app._extensions):
+            os.write(fd, ('#   %s (%s) from %s\n' % (
+                extname, app._extension_versions[extname],
+                getattr(extmod, '__file__', 'unknown'))
                 ).encode('utf-8'))
     os.write(fd, exc.encode('utf-8'))
     os.close(fd)
@@ -216,7 +218,7 @@
     if modname not in sys.modules:
         try:
             __import__(modname)
-        except Exception, err:
+        except Exception as err:
             raise PycodeError('error importing %r' % modname, err)
     mod = sys.modules[modname]
     filename = getattr(mod, '__file__', None)
@@ -224,12 +226,12 @@
     if loader and getattr(loader, 'get_filename', None):
         try:
             filename = loader.get_filename(modname)
-        except Exception, err:
+        except Exception as err:
             raise PycodeError('error getting filename for %r' % filename, err)
     if filename is None and loader:
         try:
             return 'string', loader.get_source(modname)
-        except Exception, err:
+        except Exception as err:
             raise PycodeError('error getting source for %r' % modname, err)
     if filename is None:
         raise PycodeError('no source found for module %r' % modname)
@@ -246,6 +248,20 @@
     return 'file', filename
 
 
+def get_full_modname(modname, attribute):
+    __import__(modname)
+    module = sys.modules[modname]
+
+    # Allow an attribute to have multiple parts and incidentially allow
+    # repeated .s in the attribute.
+    value = module
+    for attr in attribute.split('.'):
+        if attr:
+            value = getattr(value, attr)
+
+    return getattr(value, '__module__', None)
+
+
 # a regex to recognize coding cookies
 _coding_re = re.compile(r'coding[:=]\s*([-\w.]+)')
 
@@ -336,7 +352,7 @@
             else:
                 start = (begend[0] == '') and 0 or int(begend[0])-1
                 end = (begend[1] == '') and total or int(begend[1])
-                items.extend(xrange(start, end))
+                items.extend(range(start, end))
         except Exception:
             raise ValueError('invalid line number spec: %r' % spec)
     return items
@@ -344,7 +360,7 @@
 
 def force_decode(string, encoding):
     """Forcibly get a unicode string out of a bytestring."""
-    if isinstance(string, bytes):
+    if isinstance(string, binary_type):
         try:
             if encoding:
                 string = string.decode(encoding)
@@ -376,7 +392,7 @@
 
 def split_into(n, type, value):
     """Split an index entry into a given number of parts at semicolons."""
-    parts = map(lambda x: x.strip(), value.split(';', n-1))
+    parts = [x.strip() for x in value.split(';', n-1)]
     if sum(1 for part in parts if part) < n:
         raise ValueError('invalid %s index entry %r' % (type, value))
     return parts
@@ -428,11 +444,13 @@
     def __iter__(self):
         return self
 
-    def next(self):
+    def __next__(self):
         """Return the next item from the iterator."""
         if self.remaining:
             return self.remaining.popleft()
-        return self._iterator.next()
+        return next(self._iterator)
+
+    next = __next__  # Python 2 compatibility
 
     def push(self, item):
         """Push the `item` on the internal stack, it will be returned on the
@@ -442,6 +460,6 @@
 
     def peek(self):
         """Return the next item without changing the state of the iterator."""
-        item = self.next()
+        item = next(self)
         self.push(item)
         return item
diff --git a/sphinx/util/console.py b/sphinx/util/console.py
index 24a22d7..fa7a4a9 100644
--- a/sphinx/util/console.py
+++ b/sphinx/util/console.py
@@ -13,6 +13,12 @@
 import sys
 import re
 
+try:
+    # check if colorama is installed to support color on Windows
+    import colorama
+except ImportError:
+    colorama = None
+
 _ansi_re = re.compile('\x1b\\[(\\d\\d;){0,2}\\d\\dm')
 codes = {}
 
@@ -42,6 +48,9 @@
         return text.ljust(_tw + len(text) - len(_ansi_re.sub('', text))) + '\r'
 
 def color_terminal():
+    if sys.platform == 'win32' and colorama is not None:
+        colorama.init()
+        return True
     if not hasattr(sys.stdout, 'isatty'):
         return False
     if not sys.stdout.isatty():
@@ -55,6 +64,8 @@
 
 
 def nocolor():
+    if sys.platform == 'win32' and colorama is not None:
+        colorama.deinit()
     codes.clear()
 
 def coloron():
diff --git a/sphinx/util/docfields.py b/sphinx/util/docfields.py
index d6f46ab..abb7328 100644
--- a/sphinx/util/docfields.py
+++ b/sphinx/util/docfields.py
@@ -99,7 +99,8 @@
             return Field.make_field(self, types, domain, items[0])
         for fieldarg, content in items:
             par = nodes.paragraph()
-            par += self.make_xref(self.rolename, domain, fieldarg, nodes.strong)
+            par += self.make_xref(self.rolename, domain, fieldarg,
+                                  addnodes.literal_strong)
             par += nodes.Text(' -- ')
             par += content
             listnode += nodes.list_item('', par)
@@ -137,7 +138,8 @@
     def make_field(self, types, domain, items):
         def handle_item(fieldarg, content):
             par = nodes.paragraph()
-            par += self.make_xref(self.rolename, domain, fieldarg, nodes.strong)
+            par += self.make_xref(self.rolename, domain, fieldarg,
+                                  addnodes.literal_strong)
             if fieldarg in types:
                 par += nodes.Text(' (')
                 # NOTE: using .pop() here to prevent a single type node to be
@@ -238,10 +240,8 @@
             if is_typefield:
                 # filter out only inline nodes; others will result in invalid
                 # markup being written out
-                content = filter(
-                    lambda n: isinstance(n, nodes.Inline) or
-                              isinstance(n, nodes.Text),
-                    content)
+                content = [n for n in content if isinstance(n, nodes.Inline) or
+                           isinstance(n, nodes.Text)]
                 if content:
                     types.setdefault(typename, {})[fieldarg] = content
                 continue
diff --git a/sphinx/util/docstrings.py b/sphinx/util/docstrings.py
index 7138130..6b66eee 100644
--- a/sphinx/util/docstrings.py
+++ b/sphinx/util/docstrings.py
@@ -23,7 +23,7 @@
     """
     lines = s.expandtabs().splitlines()
     # Find minimum indentation of any non-blank lines after ignored lines.
-    margin = sys.maxint
+    margin = sys.maxsize
     for line in lines[ignore:]:
         content = len(line.lstrip())
         if content:
@@ -33,7 +33,7 @@
     for i in range(ignore):
         if i < len(lines):
             lines[i] = lines[i].lstrip()
-    if margin < sys.maxint:
+    if margin < sys.maxsize:
         for i in range(ignore, len(lines)): lines[i] = lines[i][margin:]
     # Remove any leading blank lines.
     while lines and not lines[0]:
diff --git a/sphinx/util/i18n.py b/sphinx/util/i18n.py
new file mode 100644
index 0000000..8e61c12
--- /dev/null
+++ b/sphinx/util/i18n.py
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-

+"""

+    sphinx.util.i18n

+    ~~~~~~~~~~~~~~~~

+

+    Builder superclass for all builders.

+

+    :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.

+    :license: BSD, see LICENSE for details.

+"""

+

+from os import path

+from collections import namedtuple

+

+from babel.messages.pofile import read_po

+from babel.messages.mofile import write_mo

+

+from sphinx.util.osutil import walk

+

+

+LocaleFileInfoBase = namedtuple('CatalogInfo', 'base_dir,domain')

+

+

+class CatalogInfo(LocaleFileInfoBase):

+

+    @property

+    def po_file(self):

+        return self.domain + '.po'

+

+    @property

+    def mo_file(self):

+        return self.domain + '.mo'

+

+    @property

+    def po_path(self):

+        return path.join(self.base_dir, self.po_file)

+

+    @property

+    def mo_path(self):

+        return path.join(self.base_dir, self.mo_file)

+

+    def is_outdated(self):

+        return (

+            not path.exists(self.mo_path) or

+            path.getmtime(self.mo_path) < path.getmtime(self.po_path))

+

+    def write_mo(self, locale):

+        with open(self.po_path, 'rt') as po:

+            with open(self.mo_path, 'wb') as mo:

+                write_mo(mo, read_po(po, locale))

+

+

+def get_catalogs(locale_dirs, locale, gettext_compact=False, force_all=False):

+    """

+    :param list locale_dirs:

+       list of path as `['locale_dir1', 'locale_dir2', ...]` to find

+       translation catalogs. Each path contains a structure such as

+       `<locale>/LC_MESSAGES/domain.po`.

+    :param str locale: a language as `'en'`

+    :param boolean gettext_compact:

+       * False: keep domains directory structure (default).

+       * True: domains in the sub directory will be merged into 1 file.

+    :param boolean force_all:

+       Set True if you want to get all catalogs rather than updated catalogs.

+       default is False.

+    :return: [CatalogInfo(), ...]

+    """

+    if not locale:

+        return []  # locale is not specified

+

+    catalogs = set()

+    for locale_dir in locale_dirs:

+        base_dir = path.join(locale_dir, locale, 'LC_MESSAGES')

+

+        if not path.exists(base_dir):

+            continue  # locale path is not found

+

+        for dirpath, dirnames, filenames in walk(base_dir, followlinks=True):

+            filenames = [f for f in filenames if f.endswith('.po')]

+            for filename in filenames:

+                base = path.splitext(filename)[0]

+                domain = path.relpath(path.join(dirpath, base), base_dir)

+                if gettext_compact and path.sep in domain:

+                    domain = path.split(domain)[0]

+                cat = CatalogInfo(base_dir, domain)

+                if force_all or cat.is_outdated():

+                    catalogs.add(cat)

+

+    return catalogs

diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py
index cdbfea7..f82f1f4 100644
--- a/sphinx/util/inspect.py
+++ b/sphinx/util/inspect.py
@@ -9,17 +9,17 @@
     :license: BSD, see LICENSE for details.
 """
 
-import sys
-
 # this imports the standard library inspect module without resorting to
 # relatively import this module
 inspect = __import__('inspect')
 
+from six import PY3, binary_type
+from six.moves import builtins
+
 from sphinx.util import force_decode
-from sphinx.util.pycompat import bytes, builtins
 
 
-if sys.version_info >= (3, 0):
+if PY3:
     from functools import partial
     def getargspec(func):
         """Like inspect.getargspec but supports functools.partial as well."""
@@ -55,12 +55,12 @@
             raise TypeError('%r is not a Python function' % func)
         return inspect.getfullargspec(func)
 
-elif sys.version_info >= (2, 5):
+else:  # 2.6, 2.7
     from functools import partial
     def getargspec(func):
         """Like inspect.getargspec but supports functools.partial as well."""
         if inspect.ismethod(func):
-            func = func.im_func
+            func = func.__func__
         parts = 0, ()
         if type(func) is partial:
             keywords = func.keywords
@@ -70,8 +70,8 @@
             func = func.func
         if not inspect.isfunction(func):
             raise TypeError('%r is not a Python function' % func)
-        args, varargs, varkw = inspect.getargs(func.func_code)
-        func_defaults = func.func_defaults
+        args, varargs, varkw = inspect.getargs(func.__code__)
+        func_defaults = func.__defaults__
         if func_defaults is None:
             func_defaults = []
         else:
@@ -86,12 +86,7 @@
                     del func_defaults[i]
                 except IndexError:
                     pass
-        if sys.version_info >= (2, 6):
-            return inspect.ArgSpec(args, varargs, varkw, func_defaults)
-        else:
-            return (args, varargs, varkw, func_defaults)
-else:
-    getargspec = inspect.getargspec
+        return inspect.ArgSpec(args, varargs, varkw, func_defaults)
 
 
 def isdescriptor(x):
@@ -134,7 +129,7 @@
         s = repr(object)
     except Exception:
         raise ValueError
-    if isinstance(s, bytes):
+    if isinstance(s, binary_type):
         return force_decode(s, None).replace('\n', ' ')
     return s.replace('\n', ' ')
 
diff --git a/sphinx/util/jsdump.py b/sphinx/util/jsdump.py
index 85845a7..ede4ae7 100644
--- a/sphinx/util/jsdump.py
+++ b/sphinx/util/jsdump.py
@@ -12,6 +12,8 @@
 
 import re
 
+from six import iteritems, integer_types, string_types
+
 from sphinx.util.pycompat import u
 
 _str_re  = re.compile(r'"(\\\\|\\"|[^"])*"')
@@ -74,7 +76,7 @@
 
 def dumps(obj, key=False):
     if key:
-        if not isinstance(obj, basestring):
+        if not isinstance(obj, string_types):
             obj = str(obj)
         if _nameonly_re.match(obj) and obj not in reswords:
             return obj  # return it as a bare word
@@ -84,16 +86,16 @@
         return 'null'
     elif obj is True or obj is False:
         return obj and 'true' or 'false'
-    elif isinstance(obj, (int, long, float)):
+    elif isinstance(obj, integer_types + (float,)):
         return str(obj)
     elif isinstance(obj, dict):
         return '{%s}' % ','.join('%s:%s' % (
             dumps(key, True),
             dumps(value)
-        ) for key, value in obj.iteritems())
+        ) for key, value in iteritems(obj))
     elif isinstance(obj, (tuple, list, set)):
         return '[%s]' % ','.join(dumps(x) for x in obj)
-    elif isinstance(obj, basestring):
+    elif isinstance(obj, string_types):
         return encode_string(obj)
     raise TypeError(type(obj))
 
diff --git a/sphinx/util/jsonimpl.py b/sphinx/util/jsonimpl.py
index 8ccbf0c..ac5c54a 100644
--- a/sphinx/util/jsonimpl.py
+++ b/sphinx/util/jsonimpl.py
@@ -9,28 +9,18 @@
     :license: BSD, see LICENSE for details.
 """
 
-import UserString
+import json
 
-try:
-    import json
-    # json-py's json module has no JSONEncoder; this will raise AttributeError
-    # if json-py is imported instead of the built-in json module
-    JSONEncoder = json.JSONEncoder
-except (ImportError, AttributeError):
-    try:
-        import simplejson as json
-        JSONEncoder = json.JSONEncoder
-    except ImportError:
-        json = None
-        JSONEncoder = object
+from six import text_type
+from six.moves import UserString
 
 
-class SphinxJSONEncoder(JSONEncoder):
+class SphinxJSONEncoder(json.JSONEncoder):
     """JSONEncoder subclass that forces translation proxies."""
     def default(self, obj):
-        if isinstance(obj, UserString.UserString):
-            return unicode(obj)
-        return JSONEncoder.default(self, obj)
+        if isinstance(obj, UserString):
+            return text_type(obj)
+        return json.JSONEncoder.default(self, obj)
 
 
 def dump(obj, fp, *args, **kwds):
diff --git a/sphinx/util/matching.py b/sphinx/util/matching.py
index 51b2056..da8cfa3 100644
--- a/sphinx/util/matching.py
+++ b/sphinx/util/matching.py
@@ -77,4 +77,4 @@
     if pat not in _pat_cache:
         _pat_cache[pat] = re.compile(_translate_pattern(pat))
     match = _pat_cache[pat].match
-    return filter(match, names)
+    return list(filter(match, names))
diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py
index eb3b86b..681046f 100644
--- a/sphinx/util/nodes.py
+++ b/sphinx/util/nodes.py
@@ -10,8 +10,8 @@
 """
 
 import re
-import sys
 
+from six import text_type
 from docutils import nodes
 
 from sphinx import addnodes
@@ -201,7 +201,7 @@
     tree = tree.deepcopy()
     for toctreenode in tree.traverse(addnodes.toctree):
         newnodes = []
-        includefiles = map(unicode, toctreenode['includefiles'])
+        includefiles = map(text_type, toctreenode['includefiles'])
         for includefile in includefiles:
             try:
                 builder.info(colorfunc(includefile) + " ", nonl=1)
@@ -215,6 +215,9 @@
             else:
                 sof = addnodes.start_of_file(docname=includefile)
                 sof.children = subtree.children
+                for sectionnode in sof.traverse(nodes.section):
+                    if 'docname' not in sectionnode:
+                        sectionnode['docname'] = includefile
                 newnodes.append(sof)
         toctreenode.parent.replace(toctreenode, newnodes)
     return tree
@@ -239,12 +242,7 @@
         directive.state_machine.get_source_and_line(directive.lineno)
 
 def set_role_source_info(inliner, lineno, node):
-    try:
-        node.source, node.line = \
-            inliner.reporter.locator(lineno)
-    except AttributeError:
-        # docutils 0.9+
-        node.source, node.line = inliner.reporter.get_source_and_line(lineno)
+    node.source, node.line = inliner.reporter.get_source_and_line(lineno)
 
 # monkey-patch Element.copy to copy the rawsource
 
@@ -252,17 +250,3 @@
     return self.__class__(self.rawsource, **self.attributes)
 
 nodes.Element.copy = _new_copy
-
-# monkey-patch Element.__repr__ to return str if it returns unicode.
-# Was fixed in docutils since 0.10. See sf.net/p/docutils/bugs/218/.
-
-if sys.version_info < (3,):
-    _element_repr_orig = nodes.Element.__repr__
-
-    def _new_repr(self):
-        s = _element_repr_orig(self)
-        if isinstance(s, unicode):
-            return s.encode('utf-8')
-        return s
-
-    nodes.Element.__repr__ = _new_repr
diff --git a/sphinx/util/osutil.py b/sphinx/util/osutil.py
index d7b292b..9b5f58b 100644
--- a/sphinx/util/osutil.py
+++ b/sphinx/util/osutil.py
@@ -8,6 +8,7 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
+from __future__ import print_function
 
 import os
 import re
@@ -19,6 +20,8 @@
 import gettext
 from os import path
 
+from six import PY2, text_type
+
 # Errnos that we need.
 EEXIST = getattr(errno, 'EEXIST', 0)
 ENOENT = getattr(errno, 'ENOENT', 0)
@@ -63,12 +66,15 @@
     """Ensure that a path exists."""
     try:
         os.makedirs(path)
-    except OSError, err:
+    except OSError as err:
         # 0 for Jython/Win32
         if err.errno not in [0, EEXIST]:
             raise
 
 
+# This function is same as os.walk of Python2.6, 2.7, 3.2, 3.3 except a
+# customization that check UnicodeError.
+# The customization obstacle to replace the function with the os.walk.
 def walk(top, topdown=True, followlinks=False):
     """Backport of os.walk from 2.6, where the *followlinks* argument was
     added.
@@ -80,9 +86,9 @@
         try:
             fullpath = path.join(top, name)
         except UnicodeError:
-            print >>sys.stderr, (
-                '%s:: ERROR: non-ASCII filename not supported on this '
-                'filesystem encoding %r, skipped.' % (name, fs_encoding))
+            print('%s:: ERROR: non-ASCII filename not supported on this '
+                  'filesystem encoding %r, skipped.' % (name, fs_encoding),
+                  file=sys.stderr)
             continue
         if path.isdir(fullpath):
             dirs.append(name)
@@ -143,21 +149,20 @@
 def make_filename(string):
     return no_fn_re.sub('', string) or 'sphinx'
 
-if sys.version_info < (3, 0):
+if PY2:
     # strftime for unicode strings
     def ustrftime(format, *args):
         # if a locale is set, the time strings are encoded in the encoding
         # given by LC_TIME; if that is available, use it
         enc = locale.getlocale(locale.LC_TIME)[1] or 'utf-8'
-        return time.strftime(unicode(format).encode(enc), *args).decode(enc)
+        return time.strftime(text_type(format).encode(enc), *args).decode(enc)
 else:
     ustrftime = time.strftime
 
 
 def safe_relpath(path, start=None):
-    from sphinx.util.pycompat import relpath
     try:
-        return relpath(path, start)
+        return os.path.relpath(path, start)
     except ValueError:
         return path
 
@@ -171,26 +176,19 @@
 
 
 def find_catalog_files(docname, srcdir, locale_dirs, lang, compaction):
-    from sphinx.util.pycompat import relpath
     if not(lang and locale_dirs):
         return []
 
     domain = find_catalog(docname, compaction)
     files = [gettext.find(domain, path.join(srcdir, dir_), [lang])
              for dir_ in locale_dirs]
-    files = [relpath(f, srcdir) for f in files if f]
+    files = [path.relpath(f, srcdir) for f in files if f]
     return files
 
 
 fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
 
 
-if sys.version_info < (3, 0):
-    bytes = str
-else:
-    bytes = bytes
-
-
 def abspath(pathdir):
     pathdir = path.abspath(pathdir)
     if isinstance(pathdir, bytes):
diff --git a/sphinx/util/png.py b/sphinx/util/png.py
index 65fc4d8..397adb2 100644
--- a/sphinx/util/png.py
+++ b/sphinx/util/png.py
@@ -12,14 +12,13 @@
 import struct
 import binascii
 
-from sphinx.util.pycompat import b
 
 LEN_IEND = 12
 LEN_DEPTH = 22
 
 DEPTH_CHUNK_LEN = struct.pack('!i', 10)
-DEPTH_CHUNK_START = b('tEXtDepth\x00')
-IEND_CHUNK = b('\x00\x00\x00\x00IEND\xAE\x42\x60\x82')
+DEPTH_CHUNK_START = b'tEXtDepth\x00'
+IEND_CHUNK = b'\x00\x00\x00\x00IEND\xAE\x42\x60\x82'
 
 
 def read_png_depth(filename):
diff --git a/sphinx/util/pycompat.py b/sphinx/util/pycompat.py
index 17f8871..5031dd9 100644
--- a/sphinx/util/pycompat.py
+++ b/sphinx/util/pycompat.py
@@ -11,22 +11,17 @@
 
 import sys
 import codecs
-import encodings
+
+from six import PY3, text_type, exec_
 
 # ------------------------------------------------------------------------------
 # Python 2/3 compatibility
 
-if sys.version_info >= (3, 0):
+if PY3:
     # Python 3
-    class_types = (type,)
-    # the ubiquitous "bytes" helper functions
-    def b(s):
-        return s.encode('utf-8')
-    bytes = bytes
     # prefix for Unicode strings
     u = ''
-    # StringIO/BytesIO classes
-    from io import StringIO, BytesIO, TextIOWrapper
+    from io import TextIOWrapper
     # safely encode a string for printing to the terminal
     def terminal_safe(s):
         return s.encode('ascii', 'backslashreplace').decode('ascii')
@@ -42,24 +37,24 @@
         source = refactoring_tool._read_python_source(filepath)[0]
         try:
             tree = refactoring_tool.refactor_string(source, 'conf.py')
-        except ParseError, err:
+        except ParseError as err:
             # do not propagate lib2to3 exceptions
             lineno, offset = err.context[1]
             # try to match ParseError details with SyntaxError details
             raise SyntaxError(err.msg, (filepath, lineno, offset, err.value))
-        return unicode(tree)
-    from itertools import zip_longest  # Python 3 name
-    import builtins
+        return text_type(tree)
+    from html import escape as htmlescape  # >= Python 3.2
+
+    class UnicodeMixin:
+      """Mixin class to handle defining the proper __str__/__unicode__
+      methods in Python 2 or 3."""
+
+      def __str__(self):
+          return self.__unicode__()
 
 else:
     # Python 2
-    from types import ClassType
-    class_types = (type, ClassType)
-    b = str
-    bytes = str
     u = 'u'
-    from StringIO import StringIO
-    BytesIO = StringIO
     # no need to refactor on 2.x versions
     convert_with_2to3 = None
     def TextIOWrapper(stream, encoding):
@@ -69,11 +64,16 @@
         return s.encode('ascii', 'backslashreplace')
     # some kind of default system encoding; should be used with a lenient
     # error handler
-    import locale
-    sys_encoding = locale.getpreferredencoding()
+    sys_encoding = __import__('locale').getpreferredencoding()
     # use Python 3 name
-    from itertools import izip_longest as zip_longest
-    import __builtin__ as builtins
+    from cgi import escape as htmlescape  # 2.6, 2.7
+
+    class UnicodeMixin(object):
+        """Mixin class to handle defining the proper __str__/__unicode__
+        methods in Python 2 or 3."""
+
+        def __str__(self):
+            return self.__unicode__().encode('utf8')
 
 
 def execfile_(filepath, _globals):
@@ -86,9 +86,9 @@
     finally:
         f.close()
 
-    # py25,py26,py31 accept only LF eol instead of CRLF
-    if sys.version_info[:2] in ((2, 5), (2, 6), (3, 1)):
-        source = source.replace(b('\r\n'), b('\n'))
+    # py26 accept only LF eol instead of CRLF
+    if sys.version_info[:2] == (2, 6):
+        source = source.replace(b'\r\n', b'\n')
 
     # compile to a code object, handle syntax errors
     filepath_enc = filepath.encode(fs_encoding)
@@ -102,181 +102,4 @@
             code = compile(source, filepath_enc, 'exec')
         else:
             raise
-    exec code in _globals
-
-
-try:
-    from html import escape as htmlescape
-except ImportError:
-    from cgi import escape as htmlescape
-
-# ------------------------------------------------------------------------------
-# Missing builtins and itertools in Python < 2.6
-
-if sys.version_info >= (2, 6):
-    # Python >= 2.6
-    next = next
-
-    from itertools import product
-    try:
-        from itertools import zip_longest  # Python 3 name
-    except ImportError:
-        from itertools import izip_longest as zip_longest
-
-    import os
-    relpath = os.path.relpath
-    del os
-
-    import io
-    open = io.open
-
-else:
-    # Python < 2.6
-    from itertools import izip, repeat, chain
-
-    # this is on Python 2, where the method is called "next" (it is refactored
-    # to __next__ by 2to3, but in that case never executed)
-    def next(iterator):
-        return iterator.next()
-
-    # These replacement functions have been taken from the Python 2.6
-    # itertools documentation.
-    def product(*args, **kwargs):
-        pools = map(tuple, args) * kwargs.get('repeat', 1)
-        result = [[]]
-        for pool in pools:
-            result = [x + [y] for x in result for y in pool]
-        for prod in result:
-            yield tuple(prod)
-
-    def zip_longest(*args, **kwds):
-        # zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
-        fillvalue = kwds.get('fillvalue')
-        def sentinel(counter = ([fillvalue]*(len(args)-1)).pop):
-            yield counter()   # yields the fillvalue, or raises IndexError
-        fillers = repeat(fillvalue)
-        iters = [chain(it, sentinel(), fillers) for it in args]
-        try:
-            for tup in izip(*iters):
-                yield tup
-        except IndexError:
-            pass
-
-    from os.path import curdir
-    def relpath(path, start=curdir):
-        """Return a relative version of a path"""
-        from os.path import sep, abspath, commonprefix, join, pardir
-
-        if not path:
-            raise ValueError("no path specified")
-
-        start_list = abspath(start).split(sep)
-        path_list = abspath(path).split(sep)
-
-        # Work out how much of the filepath is shared by start and path.
-        i = len(commonprefix([start_list, path_list]))
-
-        rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
-        if not rel_list:
-            return start
-        return join(*rel_list)
-    del curdir
-
-    from types import MethodType
-    def open(filename, mode='r', *args, **kw):
-        newline = kw.pop('newline', None)
-        mode = mode.replace('t', '')
-        f = codecs.open(filename, mode, *args, **kw)
-        if newline is not None:
-            f._write = f.write
-            def write(self, text):
-                text = text.replace(u'\r\n', u'\n').replace(u'\n', newline)
-                self._write(text)
-            f.write = MethodType(write, f)
-        return f
-
-
-# ------------------------------------------------------------------------------
-# Missing builtins and codecs in Python < 2.5
-
-if sys.version_info >= (2, 5):
-    # Python >= 2.5
-    base_exception = BaseException
-    any = any
-    all = all
-
-else:
-    # Python 2.4
-    base_exception = Exception
-
-    def all(gen):
-        for i in gen:
-            if not i:
-                return False
-        return True
-
-    def any(gen):
-        for i in gen:
-            if i:
-                return True
-        return False
-
-    # Python 2.4 doesn't know the utf-8-sig encoding, so deliver it here
-
-    def my_search_function(encoding):
-        norm_encoding = encodings.normalize_encoding(encoding)
-        if norm_encoding != 'utf_8_sig':
-            return None
-        return (encode, decode, StreamReader, StreamWriter)
-
-    codecs.register(my_search_function)
-
-    # begin code copied from utf_8_sig.py in Python 2.6
-
-    def encode(input, errors='strict'):
-        return (codecs.BOM_UTF8 +
-                codecs.utf_8_encode(input, errors)[0], len(input))
-
-    def decode(input, errors='strict'):
-        prefix = 0
-        if input[:3] == codecs.BOM_UTF8:
-            input = input[3:]
-            prefix = 3
-        (output, consumed) = codecs.utf_8_decode(input, errors, True)
-        return (output, consumed+prefix)
-
-    class StreamWriter(codecs.StreamWriter):
-        def reset(self):
-            codecs.StreamWriter.reset(self)
-            try:
-                del self.encode
-            except AttributeError:
-                pass
-
-        def encode(self, input, errors='strict'):
-            self.encode = codecs.utf_8_encode
-            return encode(input, errors)
-
-    class StreamReader(codecs.StreamReader):
-        def reset(self):
-            codecs.StreamReader.reset(self)
-            try:
-                del self.decode
-            except AttributeError:
-                pass
-
-        def decode(self, input, errors='strict'):
-            if len(input) < 3:
-                if codecs.BOM_UTF8.startswith(input):
-                    # not enough data to decide if this is a BOM
-                    # => try again on the next call
-                    return (u"", 0)
-            elif input[:3] == codecs.BOM_UTF8:
-                self.decode = codecs.utf_8_decode
-                (output, consumed) = codecs.utf_8_decode(input[3:],errors)
-                return (output, consumed+3)
-            # (else) no BOM present
-            self.decode = codecs.utf_8_decode
-            return codecs.utf_8_decode(input, errors)
-
-    # end code copied from utf_8_sig.py
+    exec_(code, _globals)
diff --git a/sphinx/util/tags.py b/sphinx/util/tags.py
index 2a9b2a0..d514158 100644
--- a/sphinx/util/tags.py
+++ b/sphinx/util/tags.py
@@ -35,9 +35,9 @@
                 node = nodes.Const(None, lineno=token.lineno)
             else:
                 node = nodes.Name(token.value, 'load', lineno=token.lineno)
-            self.stream.next()
+            next(self.stream)
         elif token.type == 'lparen':
-            self.stream.next()
+            next(self.stream)
             node = self.parse_expression()
             self.stream.expect('rparen')
         else:
diff --git a/sphinx/util/texescape.py b/sphinx/util/texescape.py
index c0619f4..6fcf9ff 100644
--- a/sphinx/util/texescape.py
+++ b/sphinx/util/texescape.py
@@ -9,93 +9,95 @@
     :license: BSD, see LICENSE for details.
 """
 
+from __future__ import unicode_literals
+
 tex_replacements = [
     # map TeX special chars
-    (u'$', ur'\$'),
-    (u'%', ur'\%'),
-    (u'&', ur'\&'),
-    (u'#', ur'\#'),
-    (u'_', ur'\_'),
-    (u'{', ur'\{'),
-    (u'}', ur'\}'),
-    (u'[', ur'{[}'),
-    (u']', ur'{]}'),
-    (u'`', ur'{}`'),
-    (u'\\',ur'\textbackslash{}'),
-    (u'~', ur'\textasciitilde{}'),
-    (u'<', ur'\textless{}'),
-    (u'>', ur'\textgreater{}'),
-    (u'^', ur'\textasciicircum{}'),
+    ('$', r'\$'),
+    ('%', r'\%'),
+    ('&', r'\&'),
+    ('#', r'\#'),
+    ('_', r'\_'),
+    ('{', r'\{'),
+    ('}', r'\}'),
+    ('[', r'{[}'),
+    (']', r'{]}'),
+    ('`', r'{}`'),
+    ('\\',r'\textbackslash{}'),
+    ('~', r'\textasciitilde{}'),
+    ('<', r'\textless{}'),
+    ('>', r'\textgreater{}'),
+    ('^', r'\textasciicircum{}'),
     # map special Unicode characters to TeX commands
-    (u'¶', ur'\P{}'),
-    (u'§', ur'\S{}'),
-    (u'€', ur'\texteuro{}'),
-    (u'∞', ur'\(\infty\)'),
-    (u'±', ur'\(\pm\)'),
-    (u'→', ur'\(\rightarrow\)'),
-    (u'‣', ur'\(\rightarrow\)'),
+    ('¶', r'\P{}'),
+    ('§', r'\S{}'),
+    ('€', r'\texteuro{}'),
+    ('∞', r'\(\infty\)'),
+    ('±', r'\(\pm\)'),
+    ('→', r'\(\rightarrow\)'),
+    ('‣', r'\(\rightarrow\)'),
     # used to separate -- in options
-    (u'', ur'{}'),
+    ('', r'{}'),
     # map some special Unicode characters to similar ASCII ones
-    (u'─', ur'-'),
-    (u'⎽', ur'\_'),
-    (u'╲', ur'\textbackslash{}'),
-    (u'|', ur'\textbar{}'),
-    (u'│', ur'\textbar{}'),
-    (u'ℯ', ur'e'),
-    (u'ⅈ', ur'i'),
-    (u'₁', ur'1'),
-    (u'₂', ur'2'),
+    ('─', r'-'),
+    ('⎽', r'\_'),
+    ('╲', r'\textbackslash{}'),
+    ('|', r'\textbar{}'),
+    ('│', r'\textbar{}'),
+    ('ℯ', r'e'),
+    ('ⅈ', r'i'),
+    ('₁', r'1'),
+    ('₂', r'2'),
     # map Greek alphabet
-    (u'α', ur'\(\alpha\)'),
-    (u'β', ur'\(\beta\)'),
-    (u'γ', ur'\(\gamma\)'),
-    (u'δ', ur'\(\delta\)'),
-    (u'ε', ur'\(\epsilon\)'),
-    (u'ζ', ur'\(\zeta\)'),
-    (u'η', ur'\(\eta\)'),
-    (u'θ', ur'\(\theta\)'),
-    (u'ι', ur'\(\iota\)'),
-    (u'κ', ur'\(\kappa\)'),
-    (u'λ', ur'\(\lambda\)'),
-    (u'μ', ur'\(\mu\)'),
-    (u'ν', ur'\(\nu\)'),
-    (u'ξ', ur'\(\xi\)'),
-    (u'ο', ur'o'),
-    (u'π', ur'\(\pi\)'),
-    (u'ρ', ur'\(\rho\)'),
-    (u'σ', ur'\(\sigma\)'),
-    (u'τ', ur'\(\tau\)'),
-    (u'υ', u'\\(\\upsilon\\)'),
-    (u'φ', ur'\(\phi\)'),
-    (u'χ', ur'\(\chi\)'),
-    (u'ψ', ur'\(\psi\)'),
-    (u'ω', ur'\(\omega\)'),
-    (u'Α', ur'A'),
-    (u'Β', ur'B'),
-    (u'Γ', ur'\(\Gamma\)'),
-    (u'Δ', ur'\(\Delta\)'),
-    (u'Ε', ur'E'),
-    (u'Ζ', ur'Z'),
-    (u'Η', ur'H'),
-    (u'Θ', ur'\(\Theta\)'),
-    (u'Ι', ur'I'),
-    (u'Κ', ur'K'),
-    (u'Λ', ur'\(\Lambda\)'),
-    (u'Μ', ur'M'),
-    (u'Ν', ur'N'),
-    (u'Ξ', ur'\(\Xi\)'),
-    (u'Ο', ur'O'),
-    (u'Π', ur'\(\Pi\)'),
-    (u'Ρ', ur'P'),
-    (u'Σ', ur'\(\Sigma\)'),
-    (u'Τ', ur'T'),
-    (u'Υ', u'\\(\\Upsilon\\)'),
-    (u'Φ', ur'\(\Phi\)'),
-    (u'Χ', ur'X'),
-    (u'Ψ', ur'\(\Psi\)'),
-    (u'Ω', ur'\(\Omega\)'),
-    (u'Ω', ur'\(\Omega\)'),
+    ('α', r'\(\alpha\)'),
+    ('β', r'\(\beta\)'),
+    ('γ', r'\(\gamma\)'),
+    ('δ', r'\(\delta\)'),
+    ('ε', r'\(\epsilon\)'),
+    ('ζ', r'\(\zeta\)'),
+    ('η', r'\(\eta\)'),
+    ('θ', r'\(\theta\)'),
+    ('ι', r'\(\iota\)'),
+    ('κ', r'\(\kappa\)'),
+    ('λ', r'\(\lambda\)'),
+    ('μ', r'\(\mu\)'),
+    ('ν', r'\(\nu\)'),
+    ('ξ', r'\(\xi\)'),
+    ('ο', r'o'),
+    ('π', r'\(\pi\)'),
+    ('ρ', r'\(\rho\)'),
+    ('σ', r'\(\sigma\)'),
+    ('τ', r'\(\tau\)'),
+    ('υ', '\\(\\upsilon\\)'),
+    ('φ', r'\(\phi\)'),
+    ('χ', r'\(\chi\)'),
+    ('ψ', r'\(\psi\)'),
+    ('ω', r'\(\omega\)'),
+    ('Α', r'A'),
+    ('Β', r'B'),
+    ('Γ', r'\(\Gamma\)'),
+    ('Δ', r'\(\Delta\)'),
+    ('Ε', r'E'),
+    ('Ζ', r'Z'),
+    ('Η', r'H'),
+    ('Θ', r'\(\Theta\)'),
+    ('Ι', r'I'),
+    ('Κ', r'K'),
+    ('Λ', r'\(\Lambda\)'),
+    ('Μ', r'M'),
+    ('Ν', r'N'),
+    ('Ξ', r'\(\Xi\)'),
+    ('Ο', r'O'),
+    ('Π', r'\(\Pi\)'),
+    ('Ρ', r'P'),
+    ('Σ', r'\(\Sigma\)'),
+    ('Τ', r'T'),
+    ('Υ', '\\(\\Upsilon\\)'),
+    ('Φ', r'\(\Phi\)'),
+    ('Χ', r'X'),
+    ('Ψ', r'\(\Psi\)'),
+    ('Ω', r'\(\Omega\)'),
+    ('Ω', r'\(\Omega\)'),
 ]
 
 tex_escape_map = {}
@@ -105,8 +107,8 @@
 def init():
     for a, b in tex_replacements:
         tex_escape_map[ord(a)] = b
-        tex_replace_map[ord(a)] = u'_'
+        tex_replace_map[ord(a)] = '_'
 
     for a, b in tex_replacements:
-        if a in u'[]{}\\': continue
+        if a in '[]{}\\': continue
         tex_hl_escape_map_new[ord(a)] = b
diff --git a/sphinx/versioning.py b/sphinx/versioning.py
index f10e0f2..8d34802 100644
--- a/sphinx/versioning.py
+++ b/sphinx/versioning.py
@@ -11,8 +11,10 @@
 """
 from uuid import uuid4
 from operator import itemgetter
+from itertools import product
 
-from sphinx.util.pycompat import product, zip_longest, all
+from six import iteritems
+from six.moves import range, zip_longest
 
 
 # anything below that ratio is considered equal/changed
@@ -80,7 +82,7 @@
     # choose the old node with the best ratio for each new node and set the uid
     # as long as the ratio is under a certain value, in which case we consider
     # them not changed but different
-    ratios = sorted(ratios.iteritems(), key=itemgetter(1))
+    ratios = sorted(iteritems(ratios), key=itemgetter(1))
     for (old_node, new_node), ratio in ratios:
         if new_node in seen:
             continue
@@ -115,7 +117,7 @@
         a, b = b, a
     if not a:
         return len(b)
-    previous_row = xrange(len(b) + 1)
+    previous_row = range(len(b) + 1)
     for i, column1 in enumerate(a):
         current_row = [i + 1]
         for j, column2 in enumerate(b):
diff --git a/sphinx/websupport/__init__.py b/sphinx/websupport/__init__.py
index 0e9131d..4cdedc0 100644
--- a/sphinx/websupport/__init__.py
+++ b/sphinx/websupport/__init__.py
@@ -10,12 +10,11 @@
 """
 
 import sys
-import cPickle as pickle
 import posixpath
 from os import path
 
+from six.moves import cPickle as pickle
 from jinja2 import Environment, FileSystemLoader
-
 from docutils.core import publish_parts
 
 from sphinx.application import Sphinx
diff --git a/sphinx/websupport/search/__init__.py b/sphinx/websupport/search/__init__.py
index 45068d2..f2a67b4 100644
--- a/sphinx/websupport/search/__init__.py
+++ b/sphinx/websupport/search/__init__.py
@@ -11,6 +11,8 @@
 
 import re
 
+from six import text_type
+
 
 class BaseSearch(object):
     def __init__(self, path):
@@ -109,7 +111,7 @@
                            context_end < len(text) and '...' or ''])
 
         try:
-            return unicode(context, errors='ignore')
+            return text_type(context, errors='ignore')
         except TypeError:
             return context
 
diff --git a/sphinx/websupport/search/whooshsearch.py b/sphinx/websupport/search/whooshsearch.py
index 6d1f9de..17adf05 100644
--- a/sphinx/websupport/search/whooshsearch.py
+++ b/sphinx/websupport/search/whooshsearch.py
@@ -14,6 +14,8 @@
 from whoosh.qparser import QueryParser
 from whoosh.analysis import StemmingAnalyzer
 
+from six import text_type
+
 from sphinx.util.osutil import ensuredir
 from sphinx.websupport.search import BaseSearch
 
@@ -43,7 +45,7 @@
         self.index_writer.commit()
 
     def add_document(self, pagename, title, text):
-        self.index_writer.add_document(path=unicode(pagename),
+        self.index_writer.add_document(path=text_type(pagename),
                                        title=title,
                                        text=text)
 
diff --git a/sphinx/websupport/storage/sqlalchemy_db.py b/sphinx/websupport/storage/sqlalchemy_db.py
index 7baf883..afabead 100644
--- a/sphinx/websupport/storage/sqlalchemy_db.py
+++ b/sphinx/websupport/storage/sqlalchemy_db.py
@@ -131,7 +131,7 @@
     proposal_diff = Column(Text)
     path = Column(String(256), index=True)
 
-    node_id = Column(String, ForeignKey(db_prefix + 'nodes.id'))
+    node_id = Column(String(32), ForeignKey(db_prefix + 'nodes.id'))
     node = relation(Node, backref="comments")
 
     votes = relation(CommentVote, backref="comment",
diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py
index c69c2e0..14b11fc 100644
--- a/sphinx/writers/html.py
+++ b/sphinx/writers/html.py
@@ -14,6 +14,7 @@
 import os
 import copy
 
+from six import string_types
 from docutils import nodes
 from docutils.writers.html4css1 import Writer, HTMLTranslator as BaseTranslator
 
@@ -70,11 +71,11 @@
         self.no_smarty = 0
         self.builder = builder
         self.highlightlang = builder.config.highlight_language
-        self.highlightlinenothreshold = sys.maxint
+        self.highlightlinenothreshold = sys.maxsize
         self.protect_literal_text = 0
         self.permalink_text = builder.config.html_add_permalinks
         # support backwards-compatible setting to a bool
-        if not isinstance(self.permalink_text, basestring):
+        if not isinstance(self.permalink_text, string_types):
             self.permalink_text = self.permalink_text and u'\u00B6' or ''
         self.permalink_text = self.encode(self.permalink_text)
         self.secnumber_suffix = builder.config.html_secnumber_suffix
@@ -110,9 +111,9 @@
         self.body.append('</dt>\n')
 
     def visit_desc_addname(self, node):
-        self.body.append(self.starttag(node, 'tt', '', CLASS='descclassname'))
+        self.body.append(self.starttag(node, 'code', '', CLASS='descclassname'))
     def depart_desc_addname(self, node):
-        self.body.append('</tt>')
+        self.body.append('</code>')
 
     def visit_desc_type(self, node):
         pass
@@ -125,12 +126,12 @@
         pass
 
     def visit_desc_name(self, node):
-        self.body.append(self.starttag(node, 'tt', '', CLASS='descname'))
+        self.body.append(self.starttag(node, 'code', '', CLASS='descname'))
     def depart_desc_name(self, node):
-        self.body.append('</tt>')
+        self.body.append('</code>')
 
     def visit_desc_parameterlist(self, node):
-        self.body.append('<big>(</big>')
+        self.body.append('<span class="sig-paren">(</span>')
         self.first_param = 1
         self.optional_param_level = 0
         # How many required parameters are left.
@@ -138,7 +139,7 @@
                                          for c in node.children])
         self.param_separator = node.child_text_separator
     def depart_desc_parameterlist(self, node):
-        self.body.append('<big>)</big>')
+        self.body.append('<span class="sig-paren">)</span>')
 
     # If required parameters are still to come, then put the comma after
     # the parameter.  Otherwise, put the comma before.  This ensures that
@@ -233,9 +234,17 @@
             self.body.append('.'.join(map(str, node['secnumber'])) +
                              self.secnumber_suffix)
         elif isinstance(node.parent, nodes.section):
-            anchorname = '#' + node.parent['ids'][0]
-            if anchorname not in self.builder.secnumbers:
-                anchorname = ''  # try first heading which has no anchor
+            if self.builder.name == 'singlehtml':
+                docname = node.parent.get('docname')
+                anchorname = '#' + node.parent['ids'][0]
+                if (docname, anchorname) not in self.builder.secnumbers:
+                    anchorname = (docname, '')  # try first heading which has no anchor
+                else:
+                    anchorname = (docname, anchorname)
+            else:
+                anchorname = '#' + node.parent['ids'][0]
+                if anchorname not in self.builder.secnumbers:
+                    anchorname = ''  # try first heading which has no anchor
             if self.builder.secnumbers.get(anchorname):
                 numbers = self.builder.secnumbers[anchorname]
                 self.body.append('.'.join(map(str, numbers)) +
@@ -261,11 +270,11 @@
         linenos = node.rawsource.count('\n') >= \
                   self.highlightlinenothreshold - 1
         highlight_args = node.get('highlight_args', {})
-        if node.has_key('language'):
+        if 'language' in node:
             # code-block directives
             lang = node['language']
             highlight_args['force'] = True
-        if node.has_key('linenos'):
+        if 'linenos' in node:
             linenos = node['linenos']
         def warner(msg):
             self.builder.warn(msg, (self.builder.current_docname, node.line))
@@ -274,6 +283,9 @@
             **highlight_args)
         starttag = self.starttag(node, 'div', suffix='',
                                  CLASS='highlight-%s' % lang)
+        if 'caption' in node:
+            starttag += '<div class="code-block-caption"><code>%s</code></div>' % (
+                node['caption'],)
         self.body.append(starttag + highlighted + '</div>\n')
         raise nodes.SkipNode
 
@@ -288,12 +300,12 @@
 
     # overwritten
     def visit_literal(self, node):
-        self.body.append(self.starttag(node, 'tt', '',
+        self.body.append(self.starttag(node, 'code', '',
                                        CLASS='docutils literal'))
         self.protect_literal_text += 1
     def depart_literal(self, node):
         self.protect_literal_text -= 1
-        self.body.append('</tt>')
+        self.body.append('</code>')
 
     def visit_productionlist(self, node):
         self.body.append(self.starttag(node, 'pre'))
@@ -371,13 +383,13 @@
         if node['uri'].lower().endswith('svg') or \
            node['uri'].lower().endswith('svgz'):
             atts = {'src': node['uri']}
-            if node.has_key('width'):
+            if 'width' in node:
                 atts['width'] = node['width']
-            if node.has_key('height'):
+            if 'height' in node:
                 atts['height'] = node['height']
-            if node.has_key('alt'):
+            if 'alt' in node:
                 atts['alt'] = node['alt']
-            if node.has_key('align'):
+            if 'align' in node:
                 self.body.append('<div align="%s" class="align-%s">' %
                                  (node['align'], node['align']))
                 self.context.append('</div>\n')
@@ -386,21 +398,21 @@
             self.body.append(self.emptytag(node, 'img', '', **atts))
             return
 
-        if node.has_key('scale'):
+        if 'scale' in node:
             # Try to figure out image height and width.  Docutils does that too,
             # but it tries the final file name, which does not necessarily exist
             # yet at the time the HTML file is written.
-            if Image and not (node.has_key('width')
-                              and node.has_key('height')):
+            if Image and not ('width' in node
+                              and 'height' in node):
                 try:
                     im = Image.open(os.path.join(self.builder.srcdir, olduri))
                 except (IOError, # Source image can't be found or opened
                         UnicodeError):  # PIL doesn't like Unicode paths.
                     pass
                 else:
-                    if not node.has_key('width'):
+                    if 'width' not in node:
                         node['width'] = str(im.size[0])
-                    if not node.has_key('height'):
+                    if 'height' not in node:
                         node['height'] = str(im.size[1])
                     try:
                         im.fp.close()
@@ -518,6 +530,11 @@
     def depart_literal_emphasis(self, node):
         return self.depart_emphasis(node)
 
+    def visit_literal_strong(self, node):
+        return self.visit_strong(node)
+    def depart_literal_strong(self, node):
+        return self.depart_strong(node)
+
     def visit_abbreviation(self, node):
         attrs = {}
         if node.hasattr('explanation'):
@@ -628,6 +645,14 @@
         self.depart_emphasis(node)
         self.no_smarty -= 1
 
+    def visit_literal_strong(self, node):
+        self.no_smarty += 1
+        self.visit_strong(node)
+
+    def depart_literal_strong(self, node):
+        self.depart_strong(node)
+        self.no_smarty -= 1
+
     def visit_desc_signature(self, node):
         self.no_smarty += 1
         HTMLTranslator.visit_desc_signature(self, node)
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index 8c9b1f5..a7459c9 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -16,6 +16,7 @@
 import sys
 from os import path
 
+from six import itervalues, text_type
 from docutils import nodes, writers
 from docutils.writers.latex2e import Babel
 
@@ -25,7 +26,6 @@
 from sphinx.locale import admonitionlabels, _
 from sphinx.util import split_into
 from sphinx.util.osutil import ustrftime
-from sphinx.util.pycompat import any
 from sphinx.util.texescape import tex_escape_map, tex_replace_map
 from sphinx.util.smartypants import educate_quotes_latex
 
@@ -89,9 +89,11 @@
     def __init__(self, builder):
         writers.Writer.__init__(self)
         self.builder = builder
+        self.translator_class = (
+            self.builder.translator_class or LaTeXTranslator)
 
     def translate(self):
-        visitor = LaTeXTranslator(self.document, self.builder)
+        visitor = self.translator_class(self.document, self.builder)
         self.document.walkabout(visitor)
         self.output = visitor.astext()
 
@@ -165,6 +167,7 @@
         'footer':          '',
         'printindex':      '\\printindex',
         'transition':      '\n\n\\bigskip\\hrule{}\\bigskip\n\n',
+        'figure_align':    'htbp',
     }
 
     # sphinx specific document classes
@@ -249,7 +252,7 @@
         # the second item is the default for the master file and can be changed
         # by .. highlight:: directive in the master file
         self.hlsettingstack = 2 * [[builder.config.highlight_language,
-                                    sys.maxint]]
+                                    sys.maxsize]]
         self.footnotestack = []
         self.curfilestack = []
         self.handled_abbrs = set()
@@ -306,7 +309,7 @@
         return '\\autopageref*{%s}' % self.idescape(id)
 
     def idescape(self, id):
-        return unicode(id).translate(tex_replace_map).\
+        return text_type(id).translate(tex_replace_map).\
             encode('ascii', 'backslashreplace').decode('ascii').\
             replace('\\', '_')
 
@@ -319,7 +322,7 @@
                 if i > 0:
                     ret.append('\\indexspace\n')
                 ret.append('\\bigletter{%s}\n' %
-                           unicode(letter).translate(tex_escape_map))
+                           text_type(letter).translate(tex_escape_map))
                 for entry in entries:
                     if not entry[3]:
                         continue
@@ -335,7 +338,7 @@
         # latex_domain_indices can be False/True or a list of index names
         indices_config = self.builder.config.latex_domain_indices
         if indices_config:
-            for domain in self.builder.env.domains.itervalues():
+            for domain in itervalues(self.builder.env.domains):
                 for indexcls in domain.indices:
                     indexname = '%s-%s' % (domain.name, indexcls.name)
                     if isinstance(indices_config, list):
@@ -381,7 +384,7 @@
                 target = self.hypertarget(bi[2] + ':' + bi[3],
                                           withdoc=False)
                 self.body.append(u'\\bibitem[%s]{%s}{%s %s}\n' %
-                    (bi[0], self.idescape(bi[0]), target, bi[1]))
+                    (self.encode(bi[0]), self.idescape(bi[0]), target, bi[1]))
             self.body.append(u'\\end{thebibliography}\n')
             self.bibitems = []
 
@@ -710,7 +713,7 @@
             self.body.append('\n\\hline\n')
             self.body.extend(self.tableheaders)
             self.body.append('\\endhead\n\n')
-            self.body.append(ur'\hline \multicolumn{%s}{|r|}{{\textsf{%s}}} \\ \hline'
+            self.body.append(r'\hline \multicolumn{%s}{|r|}{{\textsf{%s}}} \\ \hline'
                              % (self.table.colcount,
                                 _('Continued on next page')))
             self.body.append('\n\\endfoot\n\n')
@@ -743,14 +746,14 @@
         # Redirect head output until header is finished. see visit_tbody.
         self.body = self.tableheaders
     def depart_thead(self, node):
-        self.body.append('\\hline')
+        pass
 
     def visit_tbody(self, node):
         if not self.table.had_head:
             self.visit_thead(node)
         self.body = self.tablebody
     def depart_tbody(self, node):
-        self.body.append('\\hline')
+        pass
 
     def visit_row(self, node):
         self.table.col = 0
@@ -758,6 +761,7 @@
         if self.previous_spanning_row == 1:
             self.previous_spanning_row = 0
         self.body.append('\\\\\n')
+        self.body.append('\\hline')
         self.table.rowcount += 1
 
     def visit_entry(self, node):
@@ -1006,7 +1010,8 @@
                 # TODO non vertical space for other alignments.
                 align = '\\begin{flush%s}' % node.attributes['align']
                 align_end = '\\end{flush%s}' % node.attributes['align']
-            self.body.append('\\begin{figure}[htbp]%s\n' % align)
+            self.body.append('\\begin{figure}[%s]%s\n' % (
+                self.elements['figure_align'], align))
             if any(isinstance(child, nodes.caption) for child in node):
                 self.body.append('\\capstart\n')
             self.context.append(ids + align_end + '\\end{figure}\n')
@@ -1134,26 +1139,26 @@
                     p = scre.sub('!', self.encode(string))
                     self.body.append(r'\index{%s%s}' % (p, m))
                 elif type == 'pair':
-                    p1, p2 = map(self.encode, split_into(2, 'pair', string))
+                    p1, p2 = [self.encode(x) for x in split_into(2, 'pair', string)]
                     self.body.append(r'\index{%s!%s%s}\index{%s!%s%s}' %
                                      (p1, p2, m,  p2, p1, m))
                 elif type == 'triple':
-                    p1, p2, p3 = map(self.encode,
-                                     split_into(3, 'triple', string))
+                    p1, p2, p3 = [self.encode(x)
+                                  for x in split_into(3, 'triple', string)]
                     self.body.append(
                         r'\index{%s!%s %s%s}\index{%s!%s, %s%s}'
                         r'\index{%s!%s %s%s}' %
                         (p1, p2, p3, m,  p2, p3, p1, m,  p3, p1, p2, m))
                 elif type == 'see':
-                    p1, p2 = map(self.encode, split_into(2, 'see', string))
+                    p1, p2 = [self.encode(x) for x in split_into(2, 'see', string)]
                     self.body.append(r'\index{%s|see{%s}}' % (p1, p2))
                 elif type == 'seealso':
-                    p1, p2 = map(self.encode, split_into(2, 'seealso', string))
+                    p1, p2 = [self.encode(x) for x in split_into(2, 'seealso', string)]
                     self.body.append(r'\index{%s|see{%s}}' % (p1, p2))
                 else:
                     self.builder.warn(
                         'unknown index entry type %s found' % type)
-            except ValueError, err:
+            except ValueError as err:
                 self.builder.warn(str(err))
         raise nodes.SkipNode
 
@@ -1163,6 +1168,8 @@
         raise nodes.SkipNode
 
     def visit_reference(self, node):
+        for id in node.get('ids'):
+            self.body += self.hypertarget(id, anchor=True)
         uri = node.get('refuri', '')
         if not uri and node.get('refid'):
             uri = '%' + self.curfilestack[-1] + '#' + node['refid']
@@ -1247,6 +1254,13 @@
     def depart_strong(self, node):
         self.body.append('}')
 
+    def visit_literal_strong(self, node):
+        self.body.append(r'\textbf{\texttt{')
+        self.no_contractions += 1
+    def depart_literal_strong(self, node):
+        self.body.append('}}')
+        self.no_contractions -= 1
+
     def visit_abbreviation(self, node):
         abbr = node.astext()
         self.body.append(r'\textsc{')
@@ -1331,6 +1345,11 @@
                 highlight_args['force'] = True
             if 'linenos' in node:
                 linenos = node['linenos']
+            caption = node.get('caption')
+            if caption:
+                self.body.append('\n{\\colorbox[rgb]{0.9,0.9,0.9}'
+                                 '{\\makebox[\\textwidth][l]'
+                                 '{\\small\\texttt{%s}}}}\n' % (caption,))
             def warner(msg):
                 self.builder.warn(msg, (self.curfilestack[-1], node.line))
             hlcode = self.highlighter.highlight_block(code, lang, warn=warner,
@@ -1498,7 +1517,7 @@
     # text handling
 
     def encode(self, text):
-        text = unicode(text).translate(tex_escape_map)
+        text = text_type(text).translate(tex_escape_map)
         if self.literal_whitespace:
             # Insert a blank before the newline, to avoid
             # ! LaTeX Error: There's no line here to end.
diff --git a/sphinx/writers/manpage.py b/sphinx/writers/manpage.py
index 4b51588..8d49f80 100644
--- a/sphinx/writers/manpage.py
+++ b/sphinx/writers/manpage.py
@@ -10,14 +10,11 @@
 """
 
 from docutils import nodes
-try:
-    from docutils.writers.manpage import MACRO_DEF, Writer, \
-         Translator as BaseTranslator
-    has_manpage_writer = True
-except ImportError:
-    # define the classes in any case, sphinx.application needs it
-    Writer = BaseTranslator = object
-    has_manpage_writer = False
+from docutils.writers.manpage import (
+    MACRO_DEF,
+    Writer,
+    Translator as BaseTranslator
+)
 
 from sphinx import addnodes
 from sphinx.locale import admonitionlabels, _
@@ -29,9 +26,11 @@
     def __init__(self, builder):
         Writer.__init__(self)
         self.builder = builder
+        self.translator_class = (
+            self.builder.translator_class or ManualPageTranslator)
 
     def translate(self):
-        visitor = ManualPageTranslator(self.builder, self.document)
+        visitor = self.translator_class(self.builder, self.document)
         self.visitor = visitor
         self.document.walkabout(visitor)
         self.output = visitor.astext()
@@ -304,6 +303,11 @@
     def depart_literal_emphasis(self, node):
         return self.depart_emphasis(node)
 
+    def visit_literal_strong(self, node):
+        return self.visit_strong(node)
+    def depart_literal_strong(self, node):
+        return self.depart_strong(node)
+
     def visit_abbreviation(self, node):
         pass
     def depart_abbreviation(self, node):
diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py
index fcfce03..a1051eb 100644
--- a/sphinx/writers/texinfo.py
+++ b/sphinx/writers/texinfo.py
@@ -10,10 +10,11 @@
 """
 
 import re
-import string
 import textwrap
 from os import path
 
+from six import itervalues
+from six.moves import range
 from docutils import nodes, writers
 
 from sphinx import addnodes, __version__
@@ -119,9 +120,12 @@
     def __init__(self, builder):
         writers.Writer.__init__(self)
         self.builder = builder
+        self.translator_class = (
+            self.builder.translator_class or TexinfoTranslator)
 
     def translate(self):
-        self.visitor = visitor = TexinfoTranslator(self.document, self.builder)
+        self.visitor = visitor = self.translator_class(
+            self.document, self.builder)
         self.document.walkabout(visitor)
         visitor.finish()
         for attr in self.visitor_attributes:
@@ -457,7 +461,7 @@
 
         indices_config = self.builder.config.texinfo_domain_indices
         if indices_config:
-            for domain in self.builder.env.domains.itervalues():
+            for domain in itervalues(self.builder.env.domains):
                 for indexcls in domain.indices:
                     indexname = '%s-%s' % (domain.name, indexcls.name)
                     if isinstance(indices_config, list):
@@ -655,7 +659,7 @@
     def visit_reference(self, node):
         # an xref's target is displayed in Info so we ignore a few
         # cases for the sake of appearance
-        if isinstance(node.parent, (nodes.title, addnodes.desc_type,)):
+        if isinstance(node.parent, (nodes.title, addnodes.desc_type)):
             return
         if isinstance(node[0], nodes.image):
             return
@@ -974,7 +978,7 @@
         self.body.append('\n%s\n' % self.entry_sep)
         self.entry_sep = '@tab'
     def depart_entry(self, node):
-        for i in xrange(node.get('morecols', 0)):
+        for i in range(node.get('morecols', 0)):
             self.body.append('\n@tab\n')
 
     ## Field Lists
@@ -1207,6 +1211,11 @@
     def depart_literal_emphasis(self, node):
         self.body.append('}')
 
+    def visit_literal_strong(self, node):
+        self.body.append('@code{')
+    def depart_literal_strong(self, node):
+        self.body.append('}')
+
     def visit_index(self, node):
         # terminate the line but don't prevent paragraph breaks
         if isinstance(node.parent, nodes.paragraph):
diff --git a/sphinx/writers/text.py b/sphinx/writers/text.py
index 82b0f45..5b32b05 100644
--- a/sphinx/writers/text.py
+++ b/sphinx/writers/text.py
@@ -11,7 +11,9 @@
 import os
 import re
 import textwrap
-from itertools import groupby, izip_longest
+from itertools import groupby
+
+from six.moves import zip_longest
 
 from docutils import nodes, writers
 from docutils.utils import column_width
@@ -140,9 +142,10 @@
     def __init__(self, builder):
         writers.Writer.__init__(self)
         self.builder = builder
+        self.translator_class = self.builder.translator_class or TextTranslator
 
     def translate(self):
-        visitor = TextTranslator(self.document, self.builder)
+        visitor = self.translator_class(self.document, self.builder)
         self.document.walkabout(visitor)
         self.output = visitor.body
 
@@ -459,7 +462,7 @@
         pass
 
     def visit_entry(self, node):
-        if node.has_key('morerows') or node.has_key('morecols'):
+        if 'morerows' in node or 'morecols' in node:
             raise NotImplementedError('Column or row spanning cells are '
                                       'not implemented.')
         self.new_state(0)
@@ -488,7 +491,7 @@
                 for i, cell in enumerate(line):
                     par = my_wrap(cell, width=colwidths[i])
                     if par:
-                        maxwidth = max(map(column_width, par))
+                        maxwidth = max(column_width(x) for x in par)
                     else:
                         maxwidth = 0
                     realwidths[i] = max(realwidths[i], maxwidth)
@@ -503,7 +506,7 @@
             self.add_text(''.join(out) + self.nl)
 
         def writerow(row):
-            lines = izip_longest(*row)
+            lines = zip_longest(*row)
             for line in lines:
                 out = ['|']
                 for i, cell in enumerate(line):
@@ -765,6 +768,11 @@
     def depart_strong(self, node):
         self.add_text('**')
 
+    def visit_literal_strong(self, node):
+        self.add_text('**')
+    def depart_literal_strong(self, node):
+        self.add_text('**')
+
     def visit_abbreviation(self, node):
         self.add_text('')
     def depart_abbreviation(self, node):
diff --git a/sphinx/writers/xml.py b/sphinx/writers/xml.py
index cfae484..179a9ab 100644
--- a/sphinx/writers/xml.py
+++ b/sphinx/writers/xml.py
@@ -18,6 +18,8 @@
     def __init__(self, builder):
         BaseXMLWriter.__init__(self)
         self.builder = builder
+        if self.builder.translator_class:
+            self.translator_class = self.builder.translator_class
 
     def translate(self, *args, **kwargs):
         self.document.settings.newlines = \
diff --git a/tests/coverage.py b/tests/coverage.py
index 95f6f84..f9341d8 100755
--- a/tests/coverage.py
+++ b/tests/coverage.py
@@ -52,7 +52,9 @@
   e.g. python coverage.py -i -r -o c:\python23,lib\enthought\traits
 
 Coverage data is saved in the file .coverage by default.  Set the
-COVERAGE_FILE environment variable to save it somewhere else."""
+COVERAGE_FILE environment variable to save it somewhere else.
+"""
+from __future__ import print_function
 
 __version__ = "2.85.20080914"    # see detailed history at the end of this file.
 
@@ -64,17 +66,14 @@
 import string
 import symbol
 import sys
+import atexit
 import threading
 import token
-import types
 import zipimport
 from socket import gethostname
 
-# Python version compatibility
-try:
-    strclass = basestring   # new to 2.3
-except:
-    strclass = str
+from six import string_types
+
 
 # 2. IMPLEMENTATION
 #
@@ -187,9 +186,9 @@
                 return 0
             # If this line is excluded, or suite_spots maps this line to
             # another line that is exlcuded, then we're excluded.
-            elif self.excluded.has_key(lineno) or \
-                 self.suite_spots.has_key(lineno) and \
-                 self.excluded.has_key(self.suite_spots[lineno][1]):
+            elif lineno in self.excluded or \
+                 lineno in self.suite_spots and \
+                 self.suite_spots[lineno][1] in self.excluded:
                 return 0
             # Otherwise, this is an executable line.
             else:
@@ -218,8 +217,8 @@
         lastprev = self.getLastLine(prevsuite)
         firstelse = self.getFirstLine(suite)
         for l in range(lastprev+1, firstelse):
-            if self.suite_spots.has_key(l):
-                self.doSuite(None, suite, exclude=self.excluded.has_key(l))
+            if l in self.suite_spots:
+                self.doSuite(None, suite, exclude=l in self.excluded)
                 break
         else:
             self.doSuite(None, suite)
@@ -328,9 +327,9 @@
 
     def help(self, error=None):     #pragma: no cover
         if error:
-            print error
-            print
-        print __doc__
+            print(error)
+            print()
+        print(__doc__)
         sys.exit(1)
 
     def command_line(self, argv, help_fn=None):
@@ -354,9 +353,9 @@
         long_opts = optmap.values()
         options, args = getopt.getopt(argv, short_opts, long_opts)
         for o, a in options:
-            if optmap.has_key(o):
+            if o in optmap:
                 settings[optmap[o]] = 1
-            elif optmap.has_key(o + ':'):
+            elif o + ':' in optmap:
                 settings[optmap[o + ':']] = a
             elif o[2:] in long_opts:
                 settings[o[2:]] = 1
@@ -398,11 +397,11 @@
             self.start()
             import __main__
             sys.path[0] = os.path.dirname(sys.argv[0])
-            execfile(sys.argv[0], __main__.__dict__)
+            exec(compile(open(sys.argv[0]).read(), sys.argv[0], 'exec'), __main__.__dict__)
         if settings.get('collect'):
             self.collect()
         if not args:
-            args = self.cexecuted.keys()
+            args = list(self.cexecuted.keys())
 
         ignore_errors = settings.get('ignore-errors')
         show_missing = settings.get('show-missing')
@@ -493,7 +492,7 @@
             import marshal
             cexecuted = marshal.load(cache)
             cache.close()
-            if isinstance(cexecuted, types.DictType):
+            if isinstance(cexecuted, dict):
                 return cexecuted
             else:
                 return {}
@@ -514,14 +513,14 @@
 
     def merge_data(self, new_data):
         for file_name, file_data in new_data.items():
-            if self.cexecuted.has_key(file_name):
+            if file_name in self.cexecuted:
                 self.merge_file_data(self.cexecuted[file_name], file_data)
             else:
                 self.cexecuted[file_name] = file_data
 
     def merge_file_data(self, cache_data, new_data):
         for line_number in new_data.keys():
-            if not cache_data.has_key(line_number):
+            if line_number not in cache_data:
                 cache_data[line_number] = new_data[line_number]
 
     def abs_file(self, filename):
@@ -554,7 +553,7 @@
     # normalized case).  See [GDR 2001-12-04b, 3.3].
 
     def canonical_filename(self, filename):
-        if not self.canonical_filename_cache.has_key(filename):
+        if filename not in self.canonical_filename_cache:
             f = filename
             if os.path.isabs(f) and not os.path.exists(f):
                 if not self.get_zip_data(f):
@@ -578,7 +577,7 @@
                 # Can't do anything useful with exec'd strings, so skip them.
                 continue
             f = self.canonical_filename(filename)
-            if not self.cexecuted.has_key(f):
+            if f not in self.cexecuted:
                 self.cexecuted[f] = {}
             self.cexecuted[f][lineno] = 1
         self.c = {}
@@ -601,7 +600,7 @@
     # statements that cross lines.
 
     def analyze_morf(self, morf):
-        if self.analysis_cache.has_key(morf):
+        if morf in self.analysis_cache:
             return self.analysis_cache[morf]
         filename = self.morf_filename(morf)
         ext = os.path.splitext(filename)[1]
@@ -621,7 +620,7 @@
             lines, excluded_lines, line_map = self.find_executable_statements(
                 source, exclude=self.exclude_re
                 )
-        except SyntaxError, synerr:
+        except SyntaxError as synerr:
             raise CoverageException(
                 "Couldn't parse '%s' as Python source: '%s' at line %d" %
                     (filename, synerr.msg, synerr.lineno)
@@ -744,10 +743,8 @@
         visitor = StatementFindingAstVisitor(statements, excluded, suite_spots)
         compiler.walk(ast, visitor, walker=visitor)
 
-        lines = statements.keys()
-        lines.sort()
-        excluded_lines = excluded.keys()
-        excluded_lines.sort()
+        lines = sorted(statements.keys())
+        excluded_lines = sorted(excluded.keys())
         return lines, excluded_lines, suite_spots
 
     # format_lines(statements, lines).  Format a list of line numbers
@@ -792,13 +789,13 @@
     def analysis2(self, morf):
         filename, statements, excluded, line_map = self.analyze_morf(morf)
         self.canonicalize_filenames()
-        if not self.cexecuted.has_key(filename):
+        if filename not in self.cexecuted:
             self.cexecuted[filename] = {}
         missing = []
         for line in statements:
             lines = line_map.get(line, [line, line])
             for l in range(lines[0], lines[1]+1):
-                if self.cexecuted[filename].has_key(l):
+                if l in self.cexecuted[filename]:
                     break
             else:
                 missing.append(line)
@@ -837,12 +834,12 @@
 
     def report(self, morfs, show_missing=1, ignore_errors=0, file=None,
                omit_prefixes=[]):
-        if not isinstance(morfs, types.ListType):
+        if not isinstance(morfs, list):
             morfs = [morfs]
         # On windows, the shell doesn't expand wildcards.  Do it here.
         globbed = []
         for morf in morfs:
-            if isinstance(morf, strclass):
+            if isinstance(morf, string_types):
                 globbed.extend(glob.glob(morf))
             else:
                 globbed.append(morf)
@@ -851,7 +848,7 @@
         morfs = self.filter_by_prefix(morfs, omit_prefixes)
         morfs.sort(self.morf_name_compare)
 
-        max_name = max([5,] + map(len, map(self.morf_name, morfs)))
+        max_name = max(5, *map(len, map(self.morf_name, morfs)))
         fmt_name = "%%- %ds  " % max_name
         fmt_err = fmt_name + "%s: %s"
         header = fmt_name % "Name" + " Stmts   Exec  Cover"
@@ -861,8 +858,8 @@
             fmt_coverage = fmt_coverage + "   %s"
         if not file:
             file = sys.stdout
-        print >>file, header
-        print >>file, "-" * len(header)
+        print(header, file=file)
+        print("-" * len(header), file=file)
         total_statements = 0
         total_executed = 0
         for morf in morfs:
@@ -878,7 +875,7 @@
                 args = (name, n, m, pc)
                 if show_missing:
                     args = args + (readable,)
-                print >>file, fmt_coverage % args
+                print(fmt_coverage % args, file=file)
                 total_statements = total_statements + n
                 total_executed = total_executed + m
             except KeyboardInterrupt:                       #pragma: no cover
@@ -886,9 +883,9 @@
             except:
                 if not ignore_errors:
                     typ, msg = sys.exc_info()[:2]
-                    print >>file, fmt_err % (name, typ, msg)
+                    print(fmt_err % (name, typ, msg), file=file)
         if len(morfs) > 1:
-            print >>file, "-" * len(header)
+            print("-" * len(header), file=file)
             if total_statements > 0:
                 pc = 100.0 * total_executed / total_statements
             else:
@@ -896,7 +893,7 @@
             args = ("TOTAL", total_statements, total_executed, pc)
             if show_missing:
                 args = args + ("",)
-            print >>file, fmt_coverage % args
+            print(fmt_coverage % args, file=file)
 
     # annotate(morfs, ignore_errors).
 
@@ -1006,14 +1003,7 @@
 def annotate_file(*args, **kw):
     return the_coverage.annotate_file(*args, **kw)
 
-# Save coverage data when Python exits.  (The atexit module wasn't
-# introduced until Python 2.0, so use sys.exitfunc when it's not
-# available.)
-try:
-    import atexit
-    atexit.register(the_coverage.save)
-except ImportError:
-    sys.exitfunc = the_coverage.save
+atexit.register(the_coverage.save)
 
 def main():
     the_coverage.command_line(sys.argv[1:])
diff --git a/tests/etree13/ElementPath.py b/tests/etree13/ElementPath.py
index b097d81..d26a0d7 100644
--- a/tests/etree13/ElementPath.py
+++ b/tests/etree13/ElementPath.py
@@ -177,7 +177,7 @@
 
 def find(elem, path):
     try:
-        return findall(elem, path).next()
+        return next(findall(elem, path))
     except StopIteration:
         return None
 
@@ -194,17 +194,17 @@
         if path[:1] == "/":
             raise SyntaxError("cannot use absolute path on element")
         stream = iter(xpath_tokenizer(path))
-        next = stream.next; token = next()
+        next_ = lambda: next(stream); token = next_()
         selector = []
         while 1:
             try:
-                selector.append(ops[token[0]](next, token))
+                selector.append(ops[token[0]](next_, token))
             except StopIteration:
                 raise SyntaxError("invalid path")
             try:
-                token = next()
+                token = next_()
                 if token[0] == "/":
-                    token = next()
+                    token = next_()
             except StopIteration:
                 break
         _cache[path] = selector
@@ -220,7 +220,7 @@
 
 def findtext(elem, path, default=None):
     try:
-        elem = findall(elem, path).next()
+        elem = next(findall(elem, path))
         return elem.text
     except StopIteration:
         return default
diff --git a/tests/etree13/ElementTree.py b/tests/etree13/ElementTree.py
index f459c7f..0dd12dd 100644
--- a/tests/etree13/ElementTree.py
+++ b/tests/etree13/ElementTree.py
@@ -79,6 +79,10 @@
 # --------------------------------------------------------------------
 
 from __future__ import generators
+from __future__ import absolute_import
+
+from six import string_types
+
 
 __all__ = [
     # public symbols
@@ -144,7 +148,7 @@
         return result
 
 try:
-    import ElementPath
+    from . import ElementPath
 except ImportError:
     # FIXME: issue warning in this case?
     ElementPath = _SimpleElementPath()
@@ -242,7 +246,7 @@
     def __len__(self):
         return len(self._children)
 
-    def __nonzero__(self):
+    def __bool__(self):
         import warnings
         warnings.warn(
             "The behavior of this method will change in future versions. "
@@ -250,6 +254,7 @@
             FutureWarning
             )
         return len(self._children) != 0 # emulate old behaviour
+    __nonzero__ = __bool__  # for python2 compatibility
 
     ##
     # Returns the given subelement.
@@ -827,7 +832,7 @@
         tag = elem.tag
         if isinstance(tag, QName) and tag.text not in qnames:
             add_qname(tag.text)
-        elif isinstance(tag, basestring):
+        elif isinstance(tag, string_types):
             if tag not in qnames:
                 add_qname(tag)
         elif tag is not None and tag is not Comment and tag is not PI:
@@ -862,7 +867,7 @@
             write("<" + tag)
             items = elem.items()
             if items or namespaces:
-                items.sort() # lexical order
+                items = sorted(items) # lexical order
                 for k, v in items:
                     if isinstance(k, QName):
                         k = k.text
@@ -873,7 +878,7 @@
                     write(" %s=\"%s\"" % (qnames[k], v))
                 if namespaces:
                     items = namespaces.items()
-                    items.sort(key=lambda x: x[1]) # sort on prefix
+                    items = sorted(items, key=lambda x: x[1]) # sort on prefix
                     for v, k in items:
                         if k:
                             k = ":" + k
@@ -919,7 +924,7 @@
             write("<" + tag)
             items = elem.items()
             if items or namespaces:
-                items.sort() # lexical order
+                items = sorted(items) # lexical order
                 for k, v in items:
                     if isinstance(k, QName):
                         k = k.text
@@ -931,7 +936,7 @@
                     write(" %s=\"%s\"" % (qnames[k], v))
                 if namespaces:
                     items = namespaces.items()
-                    items.sort(key=lambda x: x[1]) # sort on prefix
+                    items = sorted(items, key=lambda x: x[1]) # sort on prefix
                     for v, k in items:
                         if k:
                             k = ":" + k
@@ -1183,7 +1188,7 @@
                     append((event, None))
                 parser.EndNamespaceDeclHandler = handler
 
-    def next(self):
+    def __next__(self):
         while 1:
             try:
                 item = self._events[self._index]
@@ -1204,6 +1209,8 @@
                 self._index = self._index + 1
                 return item
 
+    next = __next__  # Python 2 compatibility
+
     def __iter__(self):
         return self
 
@@ -1524,7 +1531,7 @@
     def feed(self, data):
         try:
             self._parser.Parse(data, 0)
-        except self._error, v:
+        except self._error as v:
             self._raiseerror(v)
 
     ##
@@ -1536,7 +1543,7 @@
     def close(self):
         try:
             self._parser.Parse("", 1) # end of data
-        except self._error, v:
+        except self._error as v:
             self._raiseerror(v)
         tree = self.target.close()
         del self.target, self._parser # get rid of circular references
diff --git a/tests/etree13/HTMLTreeBuilder.py b/tests/etree13/HTMLTreeBuilder.py
index 4c5a24f..cf332c7 100644
--- a/tests/etree13/HTMLTreeBuilder.py
+++ b/tests/etree13/HTMLTreeBuilder.py
@@ -1,3 +1,4 @@
+from __future__ import absolute_import
 #
 # ElementTree
 # $Id$
@@ -53,7 +54,9 @@
 import re, string, sys
 import mimetools, StringIO
 
-import ElementTree
+from six import text_type
+
+from . import ElementTree
 
 AUTOCLOSE = "p", "li", "tr", "th", "td", "head", "body"
 IGNOREEND = "img", "hr", "meta", "link", "br"
@@ -198,7 +201,7 @@
     def handle_data(self, data):
         if isinstance(data, type('')) and is_not_ascii(data):
             # convert to unicode, but only if necessary
-            data = unicode(data, self.encoding, "ignore")
+            data = text_type(data, self.encoding, "ignore")
         self.__builder.data(data)
 
     ##
diff --git a/tests/path.py b/tests/path.py
index fa90a6f..3e2c8f8 100755
--- a/tests/path.py
+++ b/tests/path.py
@@ -12,20 +12,22 @@
 import shutil
 from codecs import open
 
+from six import PY2, text_type
+
 
 FILESYSTEMENCODING = sys.getfilesystemencoding() or sys.getdefaultencoding()
 
 
-class path(unicode):
+class path(text_type):
     """
     Represents a path which behaves like a string.
     """
-    if sys.version_info < (3, 0):
+    if PY2:
         def __new__(cls, s, encoding=FILESYSTEMENCODING, errors='strict'):
             if isinstance(s, str):
                 s = s.decode(encoding, errors)
-                return unicode.__new__(cls, s)
-            return unicode.__new__(cls, s)
+                return text_type.__new__(cls, s)
+            return text_type.__new__(cls, s)
 
     @property
     def parent(self):
@@ -34,6 +36,9 @@
         """
         return self.__class__(os.path.dirname(self))
 
+    def basename(self):
+        return os.path.basename(self)
+
     def abspath(self):
         """
         Returns the absolute path.
@@ -178,7 +183,7 @@
         """
         return os.path.lexists(self)
 
-    def makedirs(self, mode=0777):
+    def makedirs(self, mode=0o777):
         """
         Recursively create directories.
         """
@@ -193,4 +198,4 @@
     __div__ = __truediv__ = joinpath
 
     def __repr__(self):
-        return '%s(%s)' % (self.__class__.__name__, unicode.__repr__(self))
+        return '%s(%s)' % (self.__class__.__name__, text_type.__repr__(self))
diff --git a/tests/root/autodoc.txt b/tests/root/autodoc.txt
index d4b3404..aa0dffb 100644
--- a/tests/root/autodoc.txt
+++ b/tests/root/autodoc.txt
@@ -45,3 +45,5 @@
    :members: ca1, ia1
 
    Specific members (2 total)
+
+.. automodule:: autodoc_missing_imports
diff --git a/tests/root/autodoc_missing_imports.py b/tests/root/autodoc_missing_imports.py
new file mode 100644
index 0000000..7a71734
--- /dev/null
+++ b/tests/root/autodoc_missing_imports.py
@@ -0,0 +1,9 @@
+
+import missing_module
+from missing_module import missing_name
+import missing_package1.missing_module1
+from missing_package2 import missing_module2
+from missing_package3.missing_module3 import missing_name
+
+class TestAutodoc(object):
+    """TestAutodoc docstring."""
diff --git a/tests/root/conf.py b/tests/root/conf.py
index 8025ba3..f0d4014 100644
--- a/tests/root/conf.py
+++ b/tests/root/conf.py
@@ -8,7 +8,7 @@
 extensions = ['sphinx.ext.autodoc', 'sphinx.ext.jsmath', 'sphinx.ext.todo',
               'sphinx.ext.coverage', 'sphinx.ext.autosummary',
               'sphinx.ext.doctest', 'sphinx.ext.extlinks',
-              'sphinx.ext.viewcode', 'sphinx.ext.oldcmarkup', 'ext']
+              'sphinx.ext.viewcode', 'ext']
 
 jsmath_path = 'dummy.js'
 
@@ -23,7 +23,6 @@
 version = '0.6'
 release = '0.6alpha1'
 today_fmt = '%B %d, %Y'
-# unused_docs = []
 exclude_patterns = ['_build', '**/excluded.*']
 keep_warnings = True
 pygments_style = 'sphinx'
@@ -71,6 +70,13 @@
 extlinks = {'issue': ('http://bugs.python.org/issue%s', 'issue '),
             'pyurl': ('http://python.org/%s', None)}
 
+autodoc_mock_imports = [
+    'missing_module',
+    'missing_package1.missing_module1',
+    'missing_package2.missing_module2',
+    'missing_package3.missing_module3',
+]
+
 # modify tags from conf.py
 tags.add('confpytag')
 
diff --git a/tests/root/contents.txt b/tests/root/contents.txt
index 7486750..c6b75c6 100644
--- a/tests/root/contents.txt
+++ b/tests/root/contents.txt
@@ -43,3 +43,4 @@
 ==========
 
 .. [Ref1] Reference target.
+.. [Ref_1] Reference target 2.
diff --git a/tests/root/img.png b/tests/root/img.png
index 72c12d1..4c8f899 100644
--- a/tests/root/img.png
+++ b/tests/root/img.png
Binary files differ
diff --git a/tests/root/includes.txt b/tests/root/includes.txt
index 904f067..e84cec0 100644
--- a/tests/root/includes.txt
+++ b/tests/root/includes.txt
@@ -40,6 +40,7 @@
 .. cssclass:: inc-lines
 .. literalinclude:: literal.inc
    :lines: 6-7,9
+   :lineno-start: 6
 
 .. cssclass:: inc-startend
 .. literalinclude:: literal.inc
@@ -57,6 +58,9 @@
 .. literalinclude:: literal.inc
    :end-before: class Foo
 
+.. literalinclude:: literal.inc
+   :diff: literal_orig.inc
+
 .. cssclass:: inc-tab3
 .. literalinclude:: tabs.inc
    :tab-width: 3
diff --git a/tests/root/literal_orig.inc b/tests/root/literal_orig.inc
new file mode 100644
index 0000000..14fd214
--- /dev/null
+++ b/tests/root/literal_orig.inc
@@ -0,0 +1,13 @@
+# Literally included file using Python highlighting
+# -*- coding: utf-8 -*-
+
+foo = "Including Unicode characters: üöä"  # This will be changed
+
+class FooOrig:
+    pass
+
+class BarOrig:
+    def baz():
+        pass
+
+def bar(): pass
diff --git a/tests/root/markup.txt b/tests/root/markup.txt
index 34e8fdb..f6f955e 100644
--- a/tests/root/markup.txt
+++ b/tests/root/markup.txt
@@ -132,7 +132,9 @@
 *Linking inline markup*
 
 * :pep:`8`
+* :pep:`Python Enhancement Proposal #8 <8>`
 * :rfc:`1`
+* :rfc:`Request for Comments #1 <1>`
 * :envvar:`HOME`
 * :keyword:`with`
 * :token:`try statement <try_stmt>`
@@ -240,6 +242,7 @@
 Stuff [#]_
 
 Reference lookup: [Ref1]_ (defined in another file).
+Reference lookup underscore: [Ref_1]_
 
 .. seealso:: something, something else, something more
 
diff --git a/tests/root/metadata.txt b/tests/root/metadata.txt
index 9b3044b..821816a 100644
--- a/tests/root/metadata.txt
+++ b/tests/root/metadata.txt
@@ -32,6 +32,10 @@
     language, containing examples of all basic reStructuredText
     constructs and many advanced constructs.
 
+:nocomments:
+:orphan:
+:tocdepth: 1
+
 .. meta::
    :keywords: reStructuredText, demonstration, demo, parser
    :description lang=en: A demonstration of the reStructuredText
diff --git a/tests/root/objects.txt b/tests/root/objects.txt
index 57e8221..73661d2 100644
--- a/tests/root/objects.txt
+++ b/tests/root/objects.txt
@@ -101,6 +101,7 @@
    :type hour: DuplicateType
    :param hour: Duplicate param.  Should not lead to crashes.
    :type hour: DuplicateType
+   :param .Cls extcls: A class from another module.
 
 
 C items
@@ -117,14 +118,6 @@
 .. c:var:: sphinx_global
 
 
-Old C items (from oldcmarkup ext)
----------------------------------
-
-.. cfunction:: Sphinx_Func()
-
-Refer to :cfunc:`Sphinx_Func`.
-
-
 Javascript items
 ================
 
diff --git a/tests/root/special/code.py b/tests/root/special/code.py
index 70c48d2..b7934b2 100644
--- a/tests/root/special/code.py
+++ b/tests/root/special/code.py
@@ -1,2 +1,2 @@
-print "line 1"
-print "line 2"
+print("line 1")
+print("line 2")
diff --git a/tests/root/subdir/img.png b/tests/root/subdir/img.png
index 72c12d1..4c8f899 100644
--- a/tests/root/subdir/img.png
+++ b/tests/root/subdir/img.png
Binary files differ
diff --git a/tests/root/subdir/simg.png b/tests/root/subdir/simg.png
index 72c12d1..4c8f899 100644
--- a/tests/root/subdir/simg.png
+++ b/tests/root/subdir/simg.png
Binary files differ
diff --git a/tests/roots/test-api-set-translator/conf.py b/tests/roots/test-api-set-translator/conf.py
new file mode 100644
index 0000000..ab458e6
--- /dev/null
+++ b/tests/roots/test-api-set-translator/conf.py
@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-

+## set this by test

+# import os

+# import sys

+# sys.path.insert(0, os.path.abspath('.'))

+

+from sphinx.writers.html import HTMLTranslator

+from sphinx.writers.latex import LaTeXTranslator

+from sphinx.writers.manpage import ManualPageTranslator

+from sphinx.writers.texinfo import TexinfoTranslator

+from sphinx.writers.text import TextTranslator

+from sphinx.writers.websupport import WebSupportTranslator

+from docutils.writers.docutils_xml import XMLTranslator

+

+

+project = 'test'

+master_doc = 'index'

+

+

+class ConfHTMLTranslator(HTMLTranslator):

+    pass

+

+

+class ConfDirHTMLTranslator(HTMLTranslator):

+    pass

+

+

+class ConfSingleHTMLTranslator(HTMLTranslator):

+    pass

+

+

+class ConfPickleTranslator(HTMLTranslator):

+    pass

+

+

+class ConfJsonTranslator(HTMLTranslator):

+    pass

+

+

+class ConfLaTeXTranslator(LaTeXTranslator):

+    pass

+

+

+class ConfManualPageTranslator(ManualPageTranslator):

+    pass

+

+

+class ConfTexinfoTranslator(TexinfoTranslator):

+    pass

+

+

+class ConfTextTranslator(TextTranslator):

+    pass

+

+

+class ConfWebSupportTranslator(WebSupportTranslator):

+    pass

+

+

+class ConfXMLTranslator(XMLTranslator):

+    pass

+

+

+class ConfPseudoXMLTranslator(XMLTranslator):

+    pass

+

+

+def setup(app):

+    app.set_translator('html', ConfHTMLTranslator)

+    app.set_translator('dirhtml', ConfDirHTMLTranslator)

+    app.set_translator('singlehtml', ConfSingleHTMLTranslator)

+    app.set_translator('pickle', ConfPickleTranslator)

+    app.set_translator('json', ConfJsonTranslator)

+    app.set_translator('latex', ConfLaTeXTranslator)

+    app.set_translator('man', ConfManualPageTranslator)

+    app.set_translator('texinfo', ConfTexinfoTranslator)

+    app.set_translator('text', ConfTextTranslator)

+    app.set_translator('websupport', ConfWebSupportTranslator)

+    app.set_translator('xml', ConfXMLTranslator)

+    app.set_translator('pseudoxml', ConfPseudoXMLTranslator)

diff --git a/tests/roots/test-api-set-translator/index.rst b/tests/roots/test-api-set-translator/index.rst
new file mode 100644
index 0000000..101bd39
--- /dev/null
+++ b/tests/roots/test-api-set-translator/index.rst
@@ -0,0 +1,3 @@
+=======================

+Test API set_translator

+=======================
\ No newline at end of file
diff --git a/tests/roots/test-api-set-translator/nonext/conf.py b/tests/roots/test-api-set-translator/nonext/conf.py
new file mode 100644
index 0000000..a07b3c2
--- /dev/null
+++ b/tests/roots/test-api-set-translator/nonext/conf.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-

+

+import os

+import sys

+

+sys.path.insert(0, os.path.dirname(os.path.abspath('.')))

+

+project = 'test'

+master_doc = 'index'

diff --git a/tests/roots/test-api-set-translator/translator.py b/tests/roots/test-api-set-translator/translator.py
new file mode 100644
index 0000000..d5c23d3
--- /dev/null
+++ b/tests/roots/test-api-set-translator/translator.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-

+

+from sphinx.writers.html import HTMLTranslator

+

+class ExtHTMLTranslator(HTMLTranslator):

+    pass

diff --git a/tests/roots/test-autosummary/contents.rst b/tests/roots/test-autosummary/contents.rst
index 3f16af9..32390a3 100644
--- a/tests/roots/test-autosummary/contents.rst
+++ b/tests/roots/test-autosummary/contents.rst
@@ -1,6 +1,6 @@
-
-.. autosummary::
-   :nosignatures:
-   :toctree:
-
-   dummy_module
+

+.. autosummary::

+   :nosignatures:

+   :toctree:

+   

+   dummy_module

diff --git a/tests/roots/test-directive-code/caption.rst b/tests/roots/test-directive-code/caption.rst
new file mode 100644
index 0000000..274d0f1
--- /dev/null
+++ b/tests/roots/test-directive-code/caption.rst
@@ -0,0 +1,21 @@
+Dedent
+======
+
+Code blocks
+-----------
+
+.. code-block:: ruby
+   :caption: caption-test.rb
+
+   def ruby?
+       false
+   end
+
+
+Literal Include
+---------------
+
+.. literalinclude:: literal.inc
+   :language: python
+   :caption: caption-test.py
+   :lines: 10-11
diff --git a/tests/roots/test-directive-code/conf.py b/tests/roots/test-directive-code/conf.py
new file mode 100644
index 0000000..f81c30b
--- /dev/null
+++ b/tests/roots/test-directive-code/conf.py
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+master_doc = 'index'
diff --git a/tests/roots/test-directive-code/dedent.rst b/tests/roots/test-directive-code/dedent.rst
new file mode 100644
index 0000000..d29e2cf
--- /dev/null
+++ b/tests/roots/test-directive-code/dedent.rst
@@ -0,0 +1,22 @@
+Dedent
+======
+
+Code blocks
+-----------
+
+.. code-block:: ruby
+   :linenos:
+   :dedent: 4
+
+       def ruby?
+           false
+       end
+
+
+Literal Include
+---------------
+
+.. literalinclude:: literal.inc
+   :language: python
+   :lines: 10-11
+   :dedent: 4
diff --git a/tests/roots/test-directive-code/index.rst b/tests/roots/test-directive-code/index.rst
new file mode 100644
index 0000000..dab6b70
--- /dev/null
+++ b/tests/roots/test-directive-code/index.rst
@@ -0,0 +1,25 @@
+test-directive-code
+===================
+
+.. toctree::
+   :glob:
+
+   *
+
+
+Code blocks
+-----------
+
+.. code-block:: ruby
+   :linenos:
+
+       def ruby?
+           false
+       end
+
+
+Literal Includes
+----------------
+
+.. literalinclude:: literal.inc
+   :language: python
diff --git a/tests/roots/test-directive-code/literal.inc b/tests/roots/test-directive-code/literal.inc
new file mode 100644
index 0000000..694f15e
--- /dev/null
+++ b/tests/roots/test-directive-code/literal.inc
@@ -0,0 +1,13 @@
+# Literally included file using Python highlighting
+# -*- coding: utf-8 -*-
+
+foo = "Including Unicode characters: üöä"
+
+class Foo:
+    pass
+
+class Bar:
+    def baz():
+        pass
+
+def bar(): pass
diff --git a/tests/roots/test-directive-only/conf.py b/tests/roots/test-directive-only/conf.py
new file mode 100644
index 0000000..eb3a3d0
--- /dev/null
+++ b/tests/roots/test-directive-only/conf.py
@@ -0,0 +1,2 @@
+
+project = 'test-directive-only'
diff --git a/tests/roots/test-only-directive/contents.rst b/tests/roots/test-directive-only/contents.rst
similarity index 68%
rename from tests/roots/test-only-directive/contents.rst
rename to tests/roots/test-directive-only/contents.rst
index 9a93be9..80ec003 100644
--- a/tests/roots/test-only-directive/contents.rst
+++ b/tests/roots/test-directive-only/contents.rst
@@ -1,4 +1,4 @@
-test-only-directive
+test-directive-only
 ===================
 
 .. toctree::
diff --git a/tests/roots/test-only-directive/only.rst b/tests/roots/test-directive-only/only.rst
similarity index 100%
rename from tests/roots/test-only-directive/only.rst
rename to tests/roots/test-directive-only/only.rst
diff --git a/tests/roots/test-ext-viewcode/conf.py b/tests/roots/test-ext-viewcode/conf.py
new file mode 100644
index 0000000..946cb78
--- /dev/null
+++ b/tests/roots/test-ext-viewcode/conf.py
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-

+

+import sys

+import os

+

+sys.path.insert(0, os.path.abspath('.'))

+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode']

+master_doc = 'index'

diff --git a/tests/roots/test-ext-viewcode/index.rst b/tests/roots/test-ext-viewcode/index.rst
new file mode 100644
index 0000000..72e9432
--- /dev/null
+++ b/tests/roots/test-ext-viewcode/index.rst
@@ -0,0 +1,29 @@
+viewcode

+========

+

+.. py:module:: spam

+

+.. autofunction:: func1

+

+.. autofunction:: func2

+

+.. autofunction:: spam.mod1.func1

+

+.. autofunction:: spam.mod2.func2

+

+.. autofunction:: Class1

+

+.. autofunction:: Class2

+

+.. autofunction:: spam.mod1.Class1

+

+.. autofunction:: spam.mod2.Class2

+

+

+.. literalinclude:: spam/__init__.py

+   :language: python

+   :pyobject: func1

+

+.. literalinclude:: spam/mod1.py

+   :language: python

+   :pyobject: func1

diff --git a/tests/roots/test-ext-viewcode/spam/__init__.py b/tests/roots/test-ext-viewcode/spam/__init__.py
new file mode 100644
index 0000000..980e9b8
--- /dev/null
+++ b/tests/roots/test-ext-viewcode/spam/__init__.py
@@ -0,0 +1,7 @@
+from __future__ import absolute_import

+

+from .mod1 import func1, Class1

+from .mod2 import (

+    func2,

+    Class2,

+)

diff --git a/tests/roots/test-ext-viewcode/spam/mod1.py b/tests/roots/test-ext-viewcode/spam/mod1.py
new file mode 100644
index 0000000..e5eb0d4
--- /dev/null
+++ b/tests/roots/test-ext-viewcode/spam/mod1.py
@@ -0,0 +1,15 @@
+"""

+mod1

+"""

+

+def func1(a, b):

+    """

+    this is func1

+    """

+    return a, b

+

+

+class Class1(object):

+    """

+    this is Class1

+    """

diff --git a/tests/roots/test-ext-viewcode/spam/mod2.py b/tests/roots/test-ext-viewcode/spam/mod2.py
new file mode 100644
index 0000000..1841db1
--- /dev/null
+++ b/tests/roots/test-ext-viewcode/spam/mod2.py
@@ -0,0 +1,15 @@
+"""

+mod2

+"""

+

+def func2(a, b):

+    """

+    this is func2

+    """

+    return a, b

+

+

+class Class2(object):

+    """

+    this is Class2

+    """

diff --git a/tests/roots/test-intl/admonitions.po b/tests/roots/test-intl/admonitions.po
index 0dd1637..bc722e5 100644
--- a/tests/roots/test-intl/admonitions.po
+++ b/tests/roots/test-intl/admonitions.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: sphinx 1.2\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-07-03 12:00\n"
+"POT-Creation-Date: 2013-07-03 12:00+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/tests/roots/test-intl/definition_terms.po b/tests/roots/test-intl/definition_terms.po
index 2c3a3bc..a147fe5 100644
--- a/tests/roots/test-intl/definition_terms.po
+++ b/tests/roots/test-intl/definition_terms.po
@@ -8,7 +8,7 @@
 msgstr ""

 "Project-Id-Version: sphinx 1.0\n"

 "Report-Msgid-Bugs-To: \n"

-"POT-Creation-Date: 2013-01-01 05:00\n"

+"POT-Creation-Date: 2013-01-01 05:00+0000\n"

 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"

 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"

 "Language-Team: LANGUAGE <LL@li.org>\n"

diff --git a/tests/roots/test-intl/docfields.po b/tests/roots/test-intl/docfields.po
index f906ca1..8c3b8f9 100644
--- a/tests/roots/test-intl/docfields.po
+++ b/tests/roots/test-intl/docfields.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: Sphinx <Tests> 0.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-12-16 14:11\n"
+"POT-Creation-Date: 2012-12-16 14:11+0000\n"
 "PO-Revision-Date: 2012-12-18 06:14+0900\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/tests/roots/test-intl/external_links.po b/tests/roots/test-intl/external_links.po
index e4e6764..8c53abb 100644
--- a/tests/roots/test-intl/external_links.po
+++ b/tests/roots/test-intl/external_links.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: sphinx 1.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-11-22 08:28\n"
+"POT-Creation-Date: 2012-11-22 08:28+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/tests/roots/test-intl/figure_caption.po b/tests/roots/test-intl/figure_caption.po
index 2b85aea..2fb1e5a 100644
--- a/tests/roots/test-intl/figure_caption.po
+++ b/tests/roots/test-intl/figure_caption.po
@@ -8,7 +8,7 @@
 msgstr ""

 "Project-Id-Version: sphinx 1.0\n"

 "Report-Msgid-Bugs-To: \n"

-"POT-Creation-Date: 2013-01-04 7:00\n"

+"POT-Creation-Date: 2013-01-04 07:00+0000\n"

 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"

 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"

 "Language-Team: LANGUAGE <LL@li.org>\n"

diff --git a/tests/roots/test-intl/footnote.po b/tests/roots/test-intl/footnote.po
index b3876f5..3dfd358 100644
--- a/tests/roots/test-intl/footnote.po
+++ b/tests/roots/test-intl/footnote.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: sphinx 1.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-11-22 08:28\n"
+"POT-Creation-Date: 2012-11-22 08:28+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/tests/roots/test-intl/glossary_terms.po b/tests/roots/test-intl/glossary_terms.po
index 1ffcaeb..2746655 100644
--- a/tests/roots/test-intl/glossary_terms.po
+++ b/tests/roots/test-intl/glossary_terms.po
@@ -8,7 +8,7 @@
 msgstr ""

 "Project-Id-Version: sphinx 1.0\n"

 "Report-Msgid-Bugs-To: \n"

-"POT-Creation-Date: 2013-01-29 14:10\n"

+"POT-Creation-Date: 2013-01-29 14:10+0000\n"

 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"

 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"

 "Language-Team: LANGUAGE <LL@li.org>\n"

diff --git a/tests/roots/test-intl/glossary_terms_inconsistency.po b/tests/roots/test-intl/glossary_terms_inconsistency.po
index 5e30165..ef2bf30 100644
--- a/tests/roots/test-intl/glossary_terms_inconsistency.po
+++ b/tests/roots/test-intl/glossary_terms_inconsistency.po
@@ -8,7 +8,7 @@
 msgstr ""

 "Project-Id-Version: sphinx 1.0\n"

 "Report-Msgid-Bugs-To: \n"

-"POT-Creation-Date: 2013-01-29 14:10\n"

+"POT-Creation-Date: 2013-01-29 14:10+0000\n"

 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"

 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"

 "Language-Team: LANGUAGE <LL@li.org>\n"

diff --git a/tests/roots/test-intl/i18n.png b/tests/roots/test-intl/i18n.png
index 72c12d1..4c8f899 100644
--- a/tests/roots/test-intl/i18n.png
+++ b/tests/roots/test-intl/i18n.png
Binary files differ
diff --git a/tests/roots/test-intl/index_entries.po b/tests/roots/test-intl/index_entries.po
index 6da9a81..83619b4 100644
--- a/tests/roots/test-intl/index_entries.po
+++ b/tests/roots/test-intl/index_entries.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: foo foo\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-01-05 18:10\n"
+"POT-Creation-Date: 2013-01-05 18:10+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/tests/roots/test-intl/literalblock.po b/tests/roots/test-intl/literalblock.po
index 8ea83b3..5b5f71e 100644
--- a/tests/roots/test-intl/literalblock.po
+++ b/tests/roots/test-intl/literalblock.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: sphinx 1.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-11-22 08:28\n"
+"POT-Creation-Date: 2012-11-22 08:28+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/tests/roots/test-intl/refs_inconsistency.po b/tests/roots/test-intl/refs_inconsistency.po
index 9cab687..cb2de9a 100644
--- a/tests/roots/test-intl/refs_inconsistency.po
+++ b/tests/roots/test-intl/refs_inconsistency.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: sphinx 1.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-12-05 08:28\n"
+"POT-Creation-Date: 2012-12-05 08:28+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/tests/roots/test-intl/role_xref.po b/tests/roots/test-intl/role_xref.po
index 8730c49..5b6d114 100644
--- a/tests/roots/test-intl/role_xref.po
+++ b/tests/roots/test-intl/role_xref.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: sphinx 1.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-02-04 14:00\n"
+"POT-Creation-Date: 2013-02-04 14:00+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/tests/roots/test-intl/rubric.po b/tests/roots/test-intl/rubric.po
index 2c1214b..9137623 100644
--- a/tests/roots/test-intl/rubric.po
+++ b/tests/roots/test-intl/rubric.po
@@ -8,7 +8,7 @@
 msgstr ""

 "Project-Id-Version: sphinx 1.0\n"

 "Report-Msgid-Bugs-To: \n"

-"POT-Creation-Date: 2013-11-12 7:00\n"

+"POT-Creation-Date: 2013-11-12 07:00+0000\n"

 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"

 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"

 "Language-Team: LANGUAGE <LL@li.org>\n"

diff --git a/tests/roots/test-intl/seealso.po b/tests/roots/test-intl/seealso.po
index d3b27e5..86a1c73 100644
--- a/tests/roots/test-intl/seealso.po
+++ b/tests/roots/test-intl/seealso.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: Sphinx <Tests> 0.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-12-16 06:06\n"
+"POT-Creation-Date: 2012-12-16 06:06+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/tests/roots/test-intl/sphinx.po b/tests/roots/test-intl/sphinx.po
index cac5d4a..a236f2f 100644
--- a/tests/roots/test-intl/sphinx.po
+++ b/tests/roots/test-intl/sphinx.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: sphinx 1.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-11-22 08:28\n"
+"POT-Creation-Date: 2012-11-22 08:28+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/tests/roots/test-intl/versionchange.po b/tests/roots/test-intl/versionchange.po
index 911d3d9..5a8df38 100644
--- a/tests/roots/test-intl/versionchange.po
+++ b/tests/roots/test-intl/versionchange.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: sphinx 1.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-12-15 03:17\n"
+"POT-Creation-Date: 2012-12-15 03:17+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/tests/roots/test-intl/warnings.po b/tests/roots/test-intl/warnings.po
index bf82510..7963a0a 100644
--- a/tests/roots/test-intl/warnings.po
+++ b/tests/roots/test-intl/warnings.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: Sphinx <Tests> 0.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-02-04 13:06\n"
+"POT-Creation-Date: 2013-02-04 13:06+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/tests/roots/test-only-directive/conf.py b/tests/roots/test-only-directive/conf.py
deleted file mode 100644
index bcb4305..0000000
--- a/tests/roots/test-only-directive/conf.py
+++ /dev/null
@@ -1,2 +0,0 @@
-
-project = 'test-only-directive'
diff --git a/tests/roots/test-tocdepth/bar.rst b/tests/roots/test-tocdepth/bar.rst
new file mode 100644
index 0000000..d70dec9
--- /dev/null
+++ b/tests/roots/test-tocdepth/bar.rst
@@ -0,0 +1,27 @@
+:tocdepth: 2
+
+===
+Bar
+===
+
+should be 2
+
+Bar A
+=====
+
+should be 2.1
+
+.. toctree::
+
+   baz
+
+Bar B
+=====
+
+should be 2.2
+
+Bar B1
+------
+
+should be 2.2.1
+
diff --git a/tests/roots/test-tocdepth/baz.rst b/tests/roots/test-tocdepth/baz.rst
new file mode 100644
index 0000000..b07fa05
--- /dev/null
+++ b/tests/roots/test-tocdepth/baz.rst
@@ -0,0 +1,5 @@
+Baz A
+-----
+
+should be 2.1.1
+
diff --git a/tests/roots/test-tocdepth/conf.py b/tests/roots/test-tocdepth/conf.py
new file mode 100644
index 0000000..f81c30b
--- /dev/null
+++ b/tests/roots/test-tocdepth/conf.py
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+master_doc = 'index'
diff --git a/tests/roots/test-tocdepth/foo.rst b/tests/roots/test-tocdepth/foo.rst
new file mode 100644
index 0000000..61fd539
--- /dev/null
+++ b/tests/roots/test-tocdepth/foo.rst
@@ -0,0 +1,26 @@
+===
+Foo
+===
+
+should be 1
+
+Foo A
+=====
+
+should be 1.1
+
+Foo A1
+------
+
+should be 1.1.1
+
+Foo B
+=====
+
+should be 1.2
+
+Foo B1
+------
+
+should be 1.2.1
+
diff --git a/tests/roots/test-tocdepth/index.rst b/tests/roots/test-tocdepth/index.rst
new file mode 100644
index 0000000..0b651d4
--- /dev/null
+++ b/tests/roots/test-tocdepth/index.rst
@@ -0,0 +1,8 @@
+test-tocdepth
+=============
+
+.. toctree::
+   :numbered:
+
+   foo
+   bar
diff --git a/tests/run.py b/tests/run.py
index 37922f3..b903165 100755
--- a/tests/run.py
+++ b/tests/run.py
@@ -9,11 +9,13 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
+from __future__ import print_function
 
 import sys
 from os import path, chdir, listdir, environ
 import shutil
 
+
 testroot = path.dirname(__file__) or '.'
 if 'BUILD_TEST_PATH' in environ:
     # for tox testing
@@ -24,15 +26,9 @@
     newroot = path.join(newroot, listdir(newroot)[0], 'tests')
 
 shutil.rmtree(newroot, ignore_errors=True)
-
-if sys.version_info >= (3, 0):
-    print('Copying and converting sources to build/lib/tests...')
-    from distutils.util import copydir_run_2to3
-    copydir_run_2to3(testroot, newroot)
-else:
-    # just copying test directory to parallel testing
-    print('Copying sources to build/lib/tests...')
-    shutil.copytree(testroot, newroot)
+# just copying test directory to parallel testing
+print('Copying sources to build/lib/tests...')
+shutil.copytree(testroot, newroot)
 
 # always test the sphinx package from build/lib/
 sys.path.insert(0, path.abspath(path.join(newroot, path.pardir)))
diff --git a/tests/test_api_translator.py b/tests/test_api_translator.py
new file mode 100644
index 0000000..9fa1b3e
--- /dev/null
+++ b/tests/test_api_translator.py
@@ -0,0 +1,203 @@
+# -*- coding: utf-8 -*-
+"""
+    test_api_translator
+    ~~~~~~~~~~~~~~~~~~~
+
+    Test the Sphinx API for translator.
+
+    :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+import sys
+
+from nose.tools import with_setup
+
+from util import with_app, test_roots
+
+
+def setup_module():
+    sys.path.insert(0, test_roots / 'test-api-set-translator')
+
+
+def teardown_module():
+    sys.path.remove(test_roots / 'test-api-set-translator')
+
+
+def teardown_websupport():
+    (test_roots / 'test-api-set-translator' / 'generated').rmtree(True)
+    (test_roots / 'test-api-set-translator' / 'websupport').rmtree(True)
+
+
+@with_app(
+    buildername='html',
+    srcdir=(test_roots / 'test-api-set-translator'),
+    confdir=(test_roots / 'test-api-set-translator' / 'nonext'),
+)
+def test_html_translator(app):
+    # no set_translator(), no html_translator_class
+    translator_class = app.builder.translator_class
+    assert translator_class
+    assert translator_class.__name__ == 'SmartyPantsHTMLTranslator'
+
+
+@with_app(
+    buildername='html',
+    srcdir=(test_roots / 'test-api-set-translator'),
+    confdir=(test_roots / 'test-api-set-translator' / 'nonext'),
+    confoverrides={
+        'html_translator_class': 'translator.ExtHTMLTranslator'},
+)
+def test_html_with_html_translator_class(app):
+    # no set_translator(), but html_translator_class
+    translator_class = app.builder.translator_class
+    assert translator_class
+    assert translator_class.__name__ == 'ExtHTMLTranslator'
+
+
+@with_app(
+    buildername='html',
+    srcdir=(test_roots / 'test-api-set-translator'),
+    confdir=(test_roots / 'test-api-set-translator' / 'nonext'),
+    confoverrides={'html_use_smartypants': False},
+)
+def test_html_with_smartypants(app):
+    # no set_translator(), html_use_smartypants=False
+    translator_class = app.builder.translator_class
+    assert translator_class
+    assert translator_class.__name__ == 'HTMLTranslator'
+
+
+@with_app(
+    buildername='html',
+    srcdir=(test_roots / 'test-api-set-translator'),
+)
+def test_html_with_set_translator_for_html_(app):
+    # use set_translator(), no html_translator_class
+    translator_class = app.builder.translator_class
+    assert translator_class
+    assert translator_class.__name__ == 'ConfHTMLTranslator'
+
+
+@with_app(
+    buildername='html',
+    srcdir=(test_roots / 'test-api-set-translator'),
+    confoverrides={'html_translator_class': 'ext.ExtHTMLTranslator'},
+)
+def test_html_with_set_translator_for_html_and_html_translator_class(app):
+    # use set_translator() and html_translator_class.
+    # set_translator() is given priority over html_translator_clas.
+    translator_class = app.builder.translator_class
+    assert translator_class
+    assert translator_class.__name__ == 'ConfHTMLTranslator'
+
+
+## this test break test_websupport.test_comments test. why?
+# @with_app(
+#     buildername='dirhtml',
+#     srcdir=(test_roots / 'test-api-set-translator'),
+# )
+# def test_dirhtml_set_translator_for_dirhtml(app):
+#     translator_class = app.builder.translator_class
+#     assert translator_class
+#     assert translator_class.__name__ == 'ConfDirHTMLTranslator'
+
+
+@with_app(
+    buildername='singlehtml',
+    srcdir=(test_roots / 'test-api-set-translator'),
+)
+def test_singlehtml_set_translator_for_singlehtml(app):
+    translator_class = app.builder.translator_class
+    assert translator_class
+    assert translator_class.__name__ == 'ConfSingleHTMLTranslator'
+
+
+@with_app(
+    buildername='pickle',
+    srcdir=(test_roots / 'test-api-set-translator'),
+)
+def test_pickle_set_translator_for_pickle(app):
+    translator_class = app.builder.translator_class
+    assert translator_class
+    assert translator_class.__name__ == 'ConfPickleTranslator'
+
+
+@with_app(
+    buildername='json',
+    srcdir=(test_roots / 'test-api-set-translator'),
+)
+def test_json_set_translator_for_json(app):
+    translator_class = app.builder.translator_class
+    assert translator_class
+    assert translator_class.__name__ == 'ConfJsonTranslator'
+
+
+@with_app(
+    buildername='latex',
+    srcdir=(test_roots / 'test-api-set-translator'),
+)
+def test_html_with_set_translator_for_latex(app):
+    translator_class = app.builder.translator_class
+    assert translator_class
+    assert translator_class.__name__ == 'ConfLaTeXTranslator'
+
+
+@with_app(
+    buildername='man',
+    srcdir=(test_roots / 'test-api-set-translator'),
+)
+def test_html_with_set_translator_for_man(app):
+    translator_class = app.builder.translator_class
+    assert translator_class
+    assert translator_class.__name__ == 'ConfManualPageTranslator'
+
+
+@with_app(
+    buildername='texinfo',
+    srcdir=(test_roots / 'test-api-set-translator'),
+)
+def test_html_with_set_translator_for_texinfo(app):
+    translator_class = app.builder.translator_class
+    assert translator_class
+    assert translator_class.__name__ == 'ConfTexinfoTranslator'
+
+
+@with_app(
+    buildername='text',
+    srcdir=(test_roots / 'test-api-set-translator'),
+)
+def test_html_with_set_translator_for_text(app):
+    translator_class = app.builder.translator_class
+    assert translator_class
+    assert translator_class.__name__ == 'ConfTextTranslator'
+
+
+@with_setup(teardown=teardown_websupport)
+@with_app(
+    buildername='websupport',
+    srcdir=(test_roots / 'test-api-set-translator'),
+)
+def test_html_with_set_translator_for_websupport(app):
+    translator_class = app.builder.translator_class
+    assert translator_class
+    assert translator_class.__name__ == 'ConfWebSupportTranslator'
+
+
+@with_app(
+    buildername='xml',
+    srcdir=(test_roots / 'test-api-set-translator'),
+)
+def test_html_with_set_translator_for_xml(app):
+    translator_class = app.builder.translator_class
+    assert translator_class
+    assert translator_class.__name__ == 'ConfXMLTranslator'
+
+
+@with_app(
+    buildername='pseudoxml',
+    srcdir=(test_roots / 'test-api-set-translator'),
+)
+def test_html_with_set_translator_for_pseudoxml(app):
+    translator_class = app.builder.translator_class
+    assert translator_class
+    assert translator_class.__name__ == 'ConfPseudoXMLTranslator'
diff --git a/tests/test_application.py b/tests/test_application.py
index 3d464eb..49c2745 100644
--- a/tests/test_application.py
+++ b/tests/test_application.py
@@ -9,9 +9,9 @@
     :license: BSD, see LICENSE for details.
 """
 
-from StringIO import StringIO
-
+from six import StringIO
 from docutils import nodes
+
 from sphinx.application import ExtensionError
 from sphinx.domains import Domain
 
diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py
index a7b2cee..e0d39f0 100644
--- a/tests/test_autodoc.py
+++ b/tests/test_autodoc.py
@@ -10,13 +10,11 @@
     :license: BSD, see LICENSE for details.
 """
 
-import sys
-from StringIO import StringIO
-
 # "raises" imported for usage by autodoc
 from util import TestApp, Struct, raises
 from nose.tools import with_setup
 
+from six import StringIO
 from docutils.statemachine import ViewList
 
 from sphinx.ext.autodoc import AutoDirective, add_documenter, \
@@ -424,6 +422,39 @@
 
 
 @with_setup(setup_test)
+def test_docstring_property_processing():
+    def genarate_docstring(objtype, name, **kw):
+        del processed_docstrings[:]
+        del processed_signatures[:]
+        inst = AutoDirective._registry[objtype](directive, name)
+        inst.generate(**kw)
+        results = list(directive.result)
+        docstrings = inst.get_doc()[0]
+        del directive.result[:]
+        return results, docstrings
+
+    directive.env.config.autodoc_docstring_signature = False
+    results, docstrings = genarate_docstring('attribute', 'test_autodoc.DocstringSig.prop1')
+    assert '.. py:attribute:: DocstringSig.prop1' in results
+    assert 'First line of docstring' in docstrings
+    assert 'DocstringSig.prop1(self)' in docstrings
+    results, docstrings = genarate_docstring('attribute', 'test_autodoc.DocstringSig.prop2')
+    assert '.. py:attribute:: DocstringSig.prop2' in results
+    assert 'First line of docstring' in docstrings
+    assert 'Second line of docstring' in docstrings
+
+    directive.env.config.autodoc_docstring_signature = True
+    results, docstrings = genarate_docstring('attribute', 'test_autodoc.DocstringSig.prop1')
+    assert '.. py:attribute:: DocstringSig.prop1' in results
+    assert 'First line of docstring' in docstrings
+    assert 'DocstringSig.prop1(self)' not in docstrings
+    results, docstrings = genarate_docstring('attribute', 'test_autodoc.DocstringSig.prop2')
+    assert '.. py:attribute:: DocstringSig.prop2' in results
+    assert 'First line of docstring' in docstrings
+    assert 'Second line of docstring' in docstrings
+
+
+@with_setup(setup_test)
 def test_new_documenter():
     class MyDocumenter(ModuleLevelDocumenter):
         objtype = 'integer'
@@ -776,12 +807,8 @@
     some arguments."""
     def template(cls, a, b, c, d=4, e=5, f=6):
         return a, b, c, d, e, f
-    if sys.version_info >= (2, 5):
-        from functools import partial
-        function = partial(template, b=b, c=c, d=d)
-    else:
-        def function(cls, a, e=5, f=6):
-            return template(a, b, c, d, e, f)
+    from functools import partial
+    function = partial(template, b=b, c=c, d=d)
     function.__name__ = name
     function.__doc__ = docstring
     return classmethod(function)
@@ -813,10 +840,9 @@
     #: should be documented -- süß
     attr = 'bar'
 
+    @property
     def prop(self):
         """Property."""
-    # stay 2.4 compatible (docstring!)
-    prop = property(prop, doc="Property.")
 
     docattr = 'baz'
     """should likewise be documented -- süß"""
@@ -886,6 +912,20 @@
             indented line
         """
 
+    @property
+    def prop1(self):
+        """DocstringSig.prop1(self)
+        First line of docstring
+        """
+        return 123
+
+    @property
+    def prop2(self):
+        """First line of docstring
+        Second line of docstring
+        """
+        return 456
+
 class StrRepr(str):
     def __repr__(self):
         return self
diff --git a/tests/test_autosummary.py b/tests/test_autosummary.py
index de26a05..8803f88 100644
--- a/tests/test_autosummary.py
+++ b/tests/test_autosummary.py
@@ -10,7 +10,8 @@
 """
 import sys
 from functools import wraps
-from StringIO import StringIO
+
+from six import iteritems, StringIO
 
 from sphinx.ext.autosummary import mangle_signature
 
@@ -71,7 +72,7 @@
     (a=1, b=<SomeClass: a, b, c>, c=3) :: ([a, b, c])
     """
 
-    TEST = [map(lambda x: x.strip(), x.split("::")) for x in TEST.split("\n")
+    TEST = [[y.strip() for y in x.split("::")] for x in TEST.split("\n")
             if '::' in x]
     for inp, outp in TEST:
         res = mangle_signature(inp).strip().replace(u"\u00a0", " ")
@@ -114,7 +115,7 @@
         'C.prop_attr2': 'This is a attribute docstring',
         'C.C2': 'This is a nested inner class docstring',
     }
-    for key, expected in expected_values.iteritems():
+    for key, expected in iteritems(expected_values):
         assert autosummary_items[key][2] == expected, 'Summary for %s was %r -'\
             ' expected %r' % (key, autosummary_items[key], expected)
 
diff --git a/tests/test_build.py b/tests/test_build.py
index c355b16..56fdf82 100644
--- a/tests/test_build.py
+++ b/tests/test_build.py
@@ -76,6 +76,41 @@
         builder_names.append('man')
 
     for buildername in builder_names:
-        app = TestApp(buildername=buildername, srcdir='(temp)')
+        app = TestApp(buildername=buildername, _copy_to_temp=True)
         yield _test_nonascii_path, app
         app.cleanup()
+
+
+@with_app(buildername='text', srcdir='(empty)')
+def test_circular_toctree(app):
+    contents = (".. toctree::\n"
+                "\n"
+                "   sub\n")
+    (app.srcdir / 'contents.rst').write_text(contents, encoding='utf-8')
+
+    contents = (".. toctree::\n"
+                "\n"
+                "   contents\n")
+    (app.srcdir / 'sub.rst').write_text(contents, encoding='utf-8')
+    app.builder.build_all()
+    warnings = "".join(app._warning.content)
+    assert 'circular toctree references detected, ignoring: sub <- contents <- sub' in warnings
+    assert 'circular toctree references detected, ignoring: contents <- sub <- contents' in warnings
+
+
+@with_app(buildername='text', srcdir='(empty)')
+def test_numbered_circular_toctree(app):
+    contents = (".. toctree::\n"
+                "   :numbered:\n"
+                "\n"
+                "   sub\n")
+    (app.srcdir / 'contents.rst').write_text(contents, encoding='utf-8')
+
+    contents = (".. toctree::\n"
+                "\n"
+                "   contents\n")
+    (app.srcdir / 'sub.rst').write_text(contents, encoding='utf-8')
+    app.builder.build_all()
+    warnings = "\n".join(app._warning.content)
+    assert 'circular toctree references detected, ignoring: sub <- contents <- sub' in warnings
+    assert 'circular toctree references detected, ignoring: contents <- sub <- contents' in warnings
diff --git a/tests/test_build_base.py b/tests/test_build_base.py
new file mode 100644
index 0000000..ee27062
--- /dev/null
+++ b/tests/test_build_base.py
@@ -0,0 +1,77 @@
+# -*- coding: utf-8 -*-

+"""

+    test_build_base

+    ~~~~~~~~~~~~~~~

+

+    Test the base build process.

+

+    :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.

+    :license: BSD, see LICENSE for details.

+"""

+import shutil

+

+from nose.tools import with_setup

+

+from util import test_roots, with_app, find_files

+

+root = test_roots / 'test-intl'

+build_dir = root / '_build'

+locale_dir = build_dir / 'locale'

+

+

+def setup_test():

+    # Delete remnants left over after failed build

+    locale_dir.rmtree(True)

+    # copy all catalogs into locale layout directory

+    for po in find_files(root, '.po'):

+        copy_po = (locale_dir / 'en' / 'LC_MESSAGES' / po)

+        if not copy_po.parent.exists():

+            copy_po.parent.makedirs()

+        shutil.copy(root / po, copy_po)

+

+

+def teardown_test():

+    build_dir.rmtree(True),

+

+

+@with_setup(setup_test, teardown_test)

+@with_app(buildername='html', srcdir=root,

+          confoverrides={'language': 'en', 'locale_dirs': [locale_dir]})

+def test_compile_all_catalogs(app):

+    app.builder.compile_all_catalogs()

+

+    catalog_dir = locale_dir / app.config.language / 'LC_MESSAGES'

+    expect = set([

+        x.replace('.po', '.mo')

+        for x in find_files(catalog_dir, '.po')

+    ])

+    actual = set(find_files(catalog_dir, '.mo'))

+    assert actual  # not empty

+    assert actual == expect

+

+

+@with_setup(setup_test, teardown_test)

+@with_app(buildername='html', srcdir=root,

+          confoverrides={'language': 'en', 'locale_dirs': [locale_dir]})

+def test_compile_specific_catalogs(app):

+    app.builder.compile_specific_catalogs(['admonitions'])

+

+    catalog_dir = locale_dir / app.config.language / 'LC_MESSAGES'

+    actual = set(find_files(catalog_dir, '.mo'))

+    assert actual == set(['admonitions.mo'])

+

+

+@with_setup(setup_test, teardown_test)

+@with_app(buildername='html', srcdir=root,

+          confoverrides={'language': 'en', 'locale_dirs': [locale_dir]})

+def test_compile_update_catalogs(app):

+    app.builder.compile_update_catalogs()

+

+    catalog_dir = locale_dir / app.config.language / 'LC_MESSAGES'

+    expect = set([

+        x.replace('.po', '.mo')

+        for x in find_files(catalog_dir, '.po')

+    ])

+    actual = set(find_files(catalog_dir, '.mo'))

+    assert actual  # not empty

+    assert actual == expect

diff --git a/tests/test_build_gettext.py b/tests/test_build_gettext.py
index 9bde44b..e7eda17 100644
--- a/tests/test_build_gettext.py
+++ b/tests/test_build_gettext.py
@@ -8,6 +8,7 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
+from __future__ import print_function
 
 import gettext
 import os
@@ -63,8 +64,8 @@
         else:
             stdout, stderr = p.communicate()
             if p.returncode != 0:
-                print stdout
-                print stderr
+                print(stdout)
+                print(stderr)
                 assert False, 'msginit exited with return code %s' % \
                         p.returncode
         assert (app.outdir / 'en_US.po').isfile(), 'msginit failed'
@@ -77,8 +78,8 @@
         else:
             stdout, stderr = p.communicate()
             if p.returncode != 0:
-                print stdout
-                print stderr
+                print(stdout)
+                print(stderr)
                 assert False, 'msgfmt exited with return code %s' % \
                         p.returncode
         assert (app.outdir / 'en' / 'LC_MESSAGES' / 'test_root.mo').isfile(), \
@@ -106,7 +107,7 @@
         return None
 
     pot = (app.outdir / 'index_entries.pot').text(encoding='utf-8')
-    msgids = filter(None, map(msgid_getter, pot.splitlines()))
+    msgids = [_f for _f in map(msgid_getter, pot.splitlines()) if _f]
 
     expected_msgids = [
         "i18n with index entries",
diff --git a/tests/test_build_html.py b/tests/test_build_html.py
index 0c2efe4..17a09ea 100644
--- a/tests/test_build_html.py
+++ b/tests/test_build_html.py
@@ -11,9 +11,9 @@
 
 import os
 import re
-import sys
-import htmlentitydefs
-from StringIO import StringIO
+
+from six import PY3, iteritems, StringIO
+from six.moves import html_entities
 
 try:
     import pygments
@@ -21,7 +21,7 @@
     pygments = None
 
 from sphinx import __version__
-from util import test_root, remove_unicode_literals, gen_with_app, with_app
+from util import test_root, test_roots, remove_unicode_literals, gen_with_app, with_app
 from etree13 import ElementTree as ET
 
 
@@ -44,9 +44,6 @@
 %(root)s/includes.txt:4: WARNING: download file not readable: .*?nonexisting.png
 %(root)s/markup.txt:\\d+: WARNING: Malformed :option: u'Python c option', does \
 not contain option marker - or -- or /
-%(root)s/objects.txt:\\d*: WARNING: using old C markup; please migrate to \
-new-style markup \(e.g. c:function instead of cfunction\), see \
-http://sphinx-doc.org/domains.html
 """
 
 HTML_WARNINGS = ENV_WARNINGS + """\
@@ -57,7 +54,7 @@
 %(root)s/markup.txt:: WARNING: invalid pair index entry u'keyword; '
 """
 
-if sys.version_info >= (3, 0):
+if PY3:
     ENV_WARNINGS = remove_unicode_literals(ENV_WARNINGS)
     HTML_WARNINGS = remove_unicode_literals(HTML_WARNINGS)
 
@@ -125,21 +122,25 @@
         (".//li/strong", r'^command\\n$'),
         (".//li/strong", r'^program\\n$'),
         (".//li/em", r'^dfn\\n$'),
-        (".//li/tt/span[@class='pre']", r'^kbd\\n$'),
+        (".//li/code/span[@class='pre']", r'^kbd\\n$'),
         (".//li/em", u'File \N{TRIANGULAR BULLET} Close'),
-        (".//li/tt/span[@class='pre']", '^a/$'),
-        (".//li/tt/em/span[@class='pre']", '^varpart$'),
-        (".//li/tt/em/span[@class='pre']", '^i$'),
+        (".//li/code/span[@class='pre']", '^a/$'),
+        (".//li/code/em/span[@class='pre']", '^varpart$'),
+        (".//li/code/em/span[@class='pre']", '^i$'),
         (".//a[@href='http://www.python.org/dev/peps/pep-0008']"
             "[@class='pep reference external']/strong", 'PEP 8'),
+        (".//a[@href='http://www.python.org/dev/peps/pep-0008']"
+            "[@class='pep reference external']/strong", 'Python Enhancement Proposal #8'),
         (".//a[@href='http://tools.ietf.org/html/rfc1.html']"
             "[@class='rfc reference external']/strong", 'RFC 1'),
+        (".//a[@href='http://tools.ietf.org/html/rfc1.html']"
+            "[@class='rfc reference external']/strong", 'Request for Comments #1'),
         (".//a[@href='objects.html#envvar-HOME']"
-            "[@class='reference internal']/tt/span[@class='pre']", 'HOME'),
+            "[@class='reference internal']/code/span[@class='pre']", 'HOME'),
         (".//a[@href='#with']"
-            "[@class='reference internal']/tt/span[@class='pre']", '^with$'),
+            "[@class='reference internal']/code/span[@class='pre']", '^with$'),
         (".//a[@href='#grammar-token-try_stmt']"
-            "[@class='reference internal']/tt/span", '^statement$'),
+            "[@class='reference internal']/code/span", '^statement$'),
         (".//a[@href='subdir/includes.html']"
             "[@class='reference internal']/em", 'Including in subdir'),
         (".//a[@href='objects.html#cmdoption-python-c']"
@@ -168,7 +169,7 @@
         (".//dl/dt[@id='term-boson']", 'boson'),
         # a production list
         (".//pre/strong", 'try_stmt'),
-        (".//pre/a[@href='#grammar-token-try1_stmt']/tt/span", 'try1_stmt'),
+        (".//pre/a[@href='#grammar-token-try1_stmt']/code/span", 'try1_stmt'),
         # tests for ``only`` directive
         (".//p", 'A global substitution.'),
         (".//p", 'In HTML.'),
@@ -178,8 +179,8 @@
     'objects.html': [
         (".//dt[@id='mod.Cls.meth1']", ''),
         (".//dt[@id='errmod.Error']", ''),
-        (".//dt/tt", r'long\(parameter,\s* list\)'),
-        (".//dt/tt", 'another one'),
+        (".//dt/code", r'long\(parameter,\s* list\)'),
+        (".//dt/code", 'another one'),
         (".//a[@href='#mod.Cls'][@class='reference internal']", ''),
         (".//dl[@class='userdesc']", ''),
         (".//dt[@id='userdesc-myobj']", ''),
@@ -191,8 +192,6 @@
         (".//a[@href='#c.SPHINX_USE_PYTHON']", ''),
         (".//a[@href='#c.SphinxType']", ''),
         (".//a[@href='#c.sphinx_global']", ''),
-        # reference from old C markup extension
-        (".//a[@href='#c.Sphinx_Func']", ''),
         # test global TOC created by toctree()
         (".//ul[@class='current']/li[@class='toctree-l1 current']/a[@href='']",
             'Testing object descriptions'),
@@ -271,7 +270,7 @@
         (".//div[@class='inc-lines highlight-text']//pre",
             r'^class Foo:\n    pass\nclass Bar:\n$'),
         (".//div[@class='inc-startend highlight-text']//pre",
-            ur'^foo = "Including Unicode characters: üöä"\n$'),
+            u'^foo = "Including Unicode characters: üöä"\\n$'),
         (".//div[@class='inc-preappend highlight-text']//pre",
             r'(?m)^START CODE$'),
         (".//div[@class='inc-pyobj-dedent highlight-python']//span",
@@ -301,7 +300,7 @@
             return name
 
 
-def check_xpath(etree, fname, path, check):
+def check_xpath(etree, fname, path, check, be_found=True):
     nodes = list(etree.findall(path))
     assert nodes != [], ('did not find any node matching xpath '
                          '%r in file %s' % (path, fname))
@@ -313,7 +312,7 @@
     else:
         rex = re.compile(check)
         for node in nodes:
-            if node.text and rex.search(node.text):
+            if node.text and (bool(rex.search(node.text)) ^ (not be_found)):
                 break
         else:
             assert False, ('%r not found in any node matching '
@@ -349,9 +348,9 @@
            '--- Expected (regex):\n' + html_warnings_exp + \
            '--- Got:\n' + html_warnings
 
-    for fname, paths in HTML_XPATH.iteritems():
+    for fname, paths in iteritems(HTML_XPATH):
         parser = NslessParser()
-        parser.entity.update(htmlentitydefs.entitydefs)
+        parser.entity.update(html_entities.entitydefs)
         fp = open(os.path.join(app.outdir, fname), 'rb')
         try:
             etree = ET.parse(fp, parser)
@@ -376,3 +375,106 @@
             '\n   :hidden:'
             '\n')
     app.builder.build_all()
+
+
+@gen_with_app(buildername='html', srcdir=(test_roots / 'test-tocdepth'))
+def test_tocdepth(app):
+    # issue #1251
+    app.builder.build_all()
+
+    expects = {
+        'index.html': [
+            (".//li[@class='toctree-l3']/a", '1.1.1. Foo A1', True),
+            (".//li[@class='toctree-l3']/a", '1.2.1. Foo B1', True),
+            (".//li[@class='toctree-l3']/a", '2.1.1. Bar A1', False),
+            (".//li[@class='toctree-l3']/a", '2.2.1. Bar B1', False),
+            ],
+        'foo.html': [
+            (".//h1", '1. Foo', True),
+            (".//h2", '1.1. Foo A', True),
+            (".//h3", '1.1.1. Foo A1', True),
+            (".//h2", '1.2. Foo B', True),
+            (".//h3", '1.2.1. Foo B1', True),
+            ],
+        'bar.html': [
+            (".//h1", '2. Bar', True),
+            (".//h2", '2.1. Bar A', True),
+            (".//h2", '2.2. Bar B', True),
+            (".//h3", '2.2.1. Bar B1', True),
+        ],
+        'baz.html': [
+            (".//h1", '2.1.1. Baz A', True),
+        ],
+    }
+
+    for fname, paths in iteritems(expects):
+        parser = NslessParser()
+        parser.entity.update(html_entities.entitydefs)
+        fp = open(os.path.join(app.outdir, fname), 'rb')
+        try:
+            etree = ET.parse(fp, parser)
+        finally:
+            fp.close()
+
+        for xpath, check, be_found in paths:
+            yield check_xpath, etree, fname, xpath, check, be_found
+
+
+@gen_with_app(buildername='singlehtml', srcdir=(test_roots / 'test-tocdepth'))
+def test_tocdepth_singlehtml(app):
+    app.builder.build_all()
+
+    expects = {
+        'index.html': [
+            (".//li[@class='toctree-l3']/a", '1.1.1. Foo A1', True),
+            (".//li[@class='toctree-l3']/a", '1.2.1. Foo B1', True),
+            (".//li[@class='toctree-l3']/a", '2.1.1. Bar A1', False),
+            (".//li[@class='toctree-l3']/a", '2.2.1. Bar B1', False),
+
+            # index.rst
+            (".//h1", 'test-tocdepth', True),
+
+            # foo.rst
+            (".//h2", '1. Foo', True),
+            (".//h3", '1.1. Foo A', True),
+            (".//h4", '1.1.1. Foo A1', True),
+            (".//h3", '1.2. Foo B', True),
+            (".//h4", '1.2.1. Foo B1', True),
+
+            # bar.rst
+            (".//h2", '2. Bar', True),
+            (".//h3", '2.1. Bar A', True),
+            (".//h3", '2.2. Bar B', True),
+            (".//h4", '2.2.1. Bar B1', True),
+
+            # baz.rst
+            (".//h4", '2.1.1. Baz A', True),
+        ],
+    }
+
+    for fname, paths in iteritems(expects):
+        parser = NslessParser()
+        parser.entity.update(html_entities.entitydefs)
+        fp = open(os.path.join(app.outdir, fname), 'rb')
+        try:
+            etree = ET.parse(fp, parser)
+        finally:
+            fp.close()
+
+        for xpath, check, be_found in paths:
+            yield check_xpath, etree, fname, xpath, check, be_found
+
+
+@with_app(buildername='html', srcdir='(empty)')
+def test_url_in_toctree(app):
+    contents = (".. toctree::\n"
+                "\n"
+                "   http://sphinx-doc.org/\n"
+                "   Latest reference <http://sphinx-doc.org/latest/>\n")
+
+    (app.srcdir / 'contents.rst').write_text(contents, encoding='utf-8')
+    app.builder.build_all()
+
+    result = (app.outdir / 'contents.html').text(encoding='utf-8')
+    assert '<a class="reference external" href="http://sphinx-doc.org/">http://sphinx-doc.org/</a>' in result
+    assert '<a class="reference external" href="http://sphinx-doc.org/latest/">Latest reference</a>' in result
diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py
index 78aa71c..41ae03d 100644
--- a/tests/test_build_latex.py
+++ b/tests/test_build_latex.py
@@ -8,13 +8,14 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
+from __future__ import print_function
 
 import os
 import re
-import sys
-from StringIO import StringIO
 from subprocess import Popen, PIPE
 
+from six import PY3, StringIO
+
 from sphinx.writers.latex import LaTeXTranslator
 
 from util import test_root, SkipTest, remove_unicode_literals, with_app
@@ -34,7 +35,7 @@
 WARNING: invalid pair index entry u'keyword; '
 """
 
-if sys.version_info >= (3, 0):
+if PY3:
     LATEX_WARNINGS = remove_unicode_literals(LATEX_WARNINGS)
 
 
@@ -90,8 +91,8 @@
         else:
             stdout, stderr = p.communicate()
             if p.returncode != 0:
-                print stdout
-                print stderr
+                print(stdout)
+                print(stderr)
                 del app.cleanup_trees[:]
                 assert False, 'latex exited with return code %s' % p.returncode
     finally:
diff --git a/tests/test_build_texinfo.py b/tests/test_build_texinfo.py
index 2f51943..fbe8a17 100644
--- a/tests/test_build_texinfo.py
+++ b/tests/test_build_texinfo.py
@@ -8,13 +8,14 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
+from __future__ import print_function
 
 import os
 import re
-import sys
-from StringIO import StringIO
 from subprocess import Popen, PIPE
 
+from six import PY3, StringIO
+
 from sphinx.writers.texinfo import TexinfoTranslator
 
 from util import test_root, SkipTest, remove_unicode_literals, with_app
@@ -33,7 +34,7 @@
 None:None: WARNING: no matching candidate for image URI u'svgimg.\\*'
 """
 
-if sys.version_info >= (3, 0):
+if PY3:
     TEXINFO_WARNINGS = remove_unicode_literals(TEXINFO_WARNINGS)
 
 
@@ -61,8 +62,8 @@
             stdout, stderr = p.communicate()
             retcode = p.returncode
             if retcode != 0:
-                print stdout
-                print stderr
+                print(stdout)
+                print(stderr)
                 del app.cleanup_trees[:]
                 assert False, 'makeinfo exited with return code %s' % retcode
     finally:
diff --git a/tests/test_config.py b/tests/test_config.py
index 1e00091..36a8d95 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -9,17 +9,17 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
-import sys
+from six import PY3
 
-from util import TestApp, with_app, with_tempdir, raises, raises_msg, write_file
+from util import TestApp, with_app, with_tempdir, raises, raises_msg
 
 from sphinx.config import Config
 from sphinx.errors import ExtensionError, ConfigError, VersionRequirementError
-from sphinx.util.pycompat import b
 
 
 @with_app(confoverrides={'master_doc': 'master', 'nonexisting_value': 'True',
-                         'latex_elements.docclass': 'scrartcl'})
+                         'latex_elements.docclass': 'scrartcl',
+                         'modindex_common_prefix': 'path1,path2'})
 def test_core_config(app):
     cfg = app.config
 
@@ -31,6 +31,7 @@
     # overrides
     assert cfg.master_doc == 'master'
     assert cfg.latex_elements['docclass'] == 'scrartcl'
+    assert cfg.modindex_common_prefix == ['path1', 'path2']
 
     # simple default values
     assert 'locale_dirs' not in cfg.__dict__
@@ -85,23 +86,24 @@
 @with_tempdir
 def test_errors_warnings(dir):
     # test the error for syntax errors in the config file
-    write_file(dir / 'conf.py', u'project = \n', 'ascii')
+    (dir / 'conf.py').write_text(u'project = \n', encoding='ascii')
     raises_msg(ConfigError, 'conf.py', Config, dir, 'conf.py', {}, None)
 
     # test the automatic conversion of 2.x only code in configs
-    write_file(dir / 'conf.py', u'# -*- coding: utf-8\n\n'
-               u'project = u"Jägermeister"\n', 'utf-8')
+    (dir / 'conf.py').write_text(
+        u'# -*- coding: utf-8\n\nproject = u"Jägermeister"\n',
+        encoding='utf-8')
     cfg = Config(dir, 'conf.py', {}, None)
-    cfg.init_values()
+    cfg.init_values(lambda warning: 1/0)
     assert cfg.project == u'Jägermeister'
 
     # test the warning for bytestrings with non-ascii content
     # bytestrings with non-ascii content are a syntax error in python3 so we
     # skip the test there
-    if sys.version_info >= (3, 0):
+    if PY3:
         return
-    write_file(dir / 'conf.py', u'# -*- coding: latin-1\nproject = "fooä"\n',
-            'latin-1')
+    (dir / 'conf.py').write_text(
+        u'# -*- coding: latin-1\nproject = "fooä"\n', encoding='latin-1')
     cfg = Config(dir, 'conf.py', {}, None)
     warned = [False]
     def warn(msg):
@@ -126,8 +128,8 @@
 def test_config_eol(tmpdir):
     # test config file's eol patterns: LF, CRLF
     configfile = tmpdir / 'conf.py'
-    for eol in ('\n', '\r\n'):
-        configfile.write_bytes(b('project = "spam"' + eol))
+    for eol in (b'\n', b'\r\n'):
+        configfile.write_bytes(b'project = "spam"' + eol)
         cfg = Config(tmpdir, 'conf.py', {}, None)
-        cfg.init_values()
+        cfg.init_values(lambda warning: 1/0)
         assert cfg.project == u'spam'
diff --git a/tests/test_coverage.py b/tests/test_coverage.py
index e6747b0..bfa76a9 100644
--- a/tests/test_coverage.py
+++ b/tests/test_coverage.py
@@ -38,7 +38,7 @@
     undoc_py, undoc_c = pickle.loads((app.outdir / 'undoc.pickle').bytes())
     assert len(undoc_c) == 1
     # the key is the full path to the header file, which isn't testable
-    assert undoc_c.values()[0] == [('function', 'Py_SphinxTest')]
+    assert list(undoc_c.values())[0] == [('function', 'Py_SphinxTest')]
 
     assert 'test_autodoc' in undoc_py
     assert 'funcs' in undoc_py['test_autodoc']
diff --git a/tests/test_cpp_domain.py b/tests/test_cpp_domain.py
deleted file mode 100644
index 8e1cb22..0000000
--- a/tests/test_cpp_domain.py
+++ /dev/null
@@ -1,157 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-    test_cpp_domain
-    ~~~~~~~~~~~~~~~
-
-    Tests the C++ Domain
-
-    :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
-    :license: BSD, see LICENSE for details.
-"""
-
-from util import raises
-
-from sphinx.domains.cpp import DefinitionParser, DefinitionError
-
-
-def parse(name, string):
-    return getattr(DefinitionParser(string), 'parse_' + name)()
-
-
-def test_type_definitions():
-    rv = parse('member_object', '  const  std::string  &  name = 42')
-    assert unicode(rv) == 'const std::string& name = 42'
-
-    rv = parse('member_object', '  const  std::string  &  name leftover')
-    assert unicode(rv) == 'const std::string& name'
-
-    rv = parse('member_object', '  const  std::string  &  name [n] leftover')
-    assert unicode(rv) == 'const std::string& name[n]'
-
-    rv = parse('member_object', 'const std::vector< unsigned int, long> &name')
-    assert unicode(rv) == 'const std::vector<unsigned int, long>& name'
-
-    x = 'std::vector<std::pair<std::string, int>>& module::test(register ' \
-        'foo, bar, std::string baz="foobar, blah, bleh") const = 0'
-    assert unicode(parse('function', x)) == x
-
-    x = 'module::myclass::operator std::vector<std::string>()'
-    assert unicode(parse('function', x)) == x
-    x = 'explicit module::myclass::foo::foo()'
-    assert unicode(parse('function', x)) == x
-
-    x = 'int printf(const char* fmt, ...)'
-    assert unicode(parse('function', x)) == x
-
-    x = 'int foo(const unsigned int j)'
-    assert unicode(parse('function', x)) == x
-
-    x = 'int foo(const unsigned int const j)'
-    assert unicode(parse('function', x)) == x
-
-    x = 'int foo(const int* const ptr)'
-    assert unicode(parse('function', x)) == x
-
-    x = 'std::vector<std::pair<std::string, long long>> module::blah'
-    assert unicode(parse('type_object', x)) == x
-
-    assert unicode(parse('type_object', 'long long int foo')) == 'long long foo'
-
-    x = 'void operator()(const boost::array<VertexID, 2>& v) const'
-    assert unicode(parse('function', x)) == x
-
-    x = 'void operator()(const boost::array<VertexID, 2, "foo,  bar">& v) const'
-    assert unicode(parse('function', x)) == x
-
-    x = 'MyClass::MyClass(MyClass::MyClass&&)'
-    assert unicode(parse('function', x)) == x
-
-    x = 'constexpr int get_value()'
-    assert unicode(parse('function', x)) == x
-
-    x = 'static constexpr int get_value()'
-    assert unicode(parse('function', x)) == x
-
-    x = 'int get_value() const noexcept'
-    assert unicode(parse('function', x)) == x
-
-    x = 'int get_value() const noexcept = delete'
-    assert unicode(parse('function', x)) == x
-
-    x = 'MyClass::MyClass(MyClass::MyClass&&) = default'
-    assert unicode(parse('function', x)) == x
-
-    x = 'MyClass::a_virtual_function() const override'
-    assert unicode(parse('function', x)) == x
-
-    x = 'MyClass::a_member_function() volatile'
-    assert unicode(parse('function', x)) == x
-
-    x = 'MyClass::a_member_function() const volatile'
-    assert unicode(parse('function', x)) == x
-
-    x = 'MyClass::a_member_function() &&'
-    assert unicode(parse('function', x)) == x
-
-    x = 'MyClass::a_member_function() &'
-    assert unicode(parse('function', x)) == x
-
-    x = 'MyClass::a_member_function() const &'
-    assert unicode(parse('function', x)) == x
-
-    x = 'int main(int argc, char* argv[][])'
-    assert unicode(parse('function', x)) == x
-
-    x = 'std::vector<std::pair<std::string, int>>& module::test(register ' \
-        'foo, bar[n], std::string baz="foobar, blah, bleh") const = 0'
-    assert unicode(parse('function', x)) == x
-
-    x = 'module::myclass foo[n]'
-    assert unicode(parse('member_object', x)) == x
-
-    x = 'int foo(Foo f=Foo(double(), std::make_pair(int(2), double(3.4))))'
-    assert unicode(parse('function', x)) == x
-
-    x = 'int foo(A a=x(a))'
-    assert unicode(parse('function', x)) == x
-
-    x = 'int foo(B b=x(a)'
-    raises(DefinitionError, parse, 'function', x)
-
-    x = 'int foo)C c=x(a))'
-    raises(DefinitionError, parse, 'function', x)
-
-    x = 'int foo(D d=x(a'
-    raises(DefinitionError, parse, 'function', x)
-
-
-def test_bases():
-    x = 'A'
-    assert unicode(parse('class', x)) == x
-
-    x = 'A : B'
-    assert unicode(parse('class', x)) == x
-
-    x = 'A : private B'
-    assert unicode(parse('class', x)) == 'A : B'
-
-    x = 'A : public B'
-    assert unicode(parse('class', x)) == x
-
-    x = 'A : B, C'
-    assert unicode(parse('class', x)) == x
-
-    x = 'A : B, protected C, D'
-    assert unicode(parse('class', x)) == x
-
-
-def test_operators():
-    x = parse('function', 'void operator new [  ] ()')
-    assert unicode(x) == 'void operator new[]()'
-
-    x = parse('function', 'void operator delete ()')
-    assert unicode(x) == 'void operator delete()'
-
-    for op in '*-+=/%!':
-        x = parse('function', 'void operator %s ()' % op)
-        assert unicode(x) == 'void operator%s()' % op
diff --git a/tests/test_directive_code.py b/tests/test_directive_code.py
new file mode 100644
index 0000000..4dbdff8
--- /dev/null
+++ b/tests/test_directive_code.py
@@ -0,0 +1,173 @@
+# -*- coding: utf-8 -*-

+"""

+    test_directive_code

+    ~~~~~~~~~~~~~~~~~~~

+

+    Test the code-block directive.

+

+    :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.

+    :license: BSD, see LICENSE for details.

+"""

+

+import re

+from xml.etree import ElementTree

+

+from util import with_app, test_roots

+

+

+def teardown_module():

+    (test_roots / 'test-directive-code' / '_build').rmtree(True)

+

+

+@with_app(buildername='xml',

+          srcdir=(test_roots / 'test-directive-code'),

+          _copy_to_temp=True)

+def test_code_block(app):

+    app.builder.build('index')

+    et = ElementTree.parse(app.outdir / 'index.xml')

+    secs = et.findall('./section/section')

+    code_block = secs[0].findall('literal_block')

+    assert len(code_block) > 0

+    actual = code_block[0].text

+    expect = (

+        "    def ruby?\n" +

+        "        false\n" +

+        "    end"

+    )

+    assert actual == expect

+

+

+@with_app(buildername='xml',

+          srcdir=(test_roots / 'test-directive-code'),

+          _copy_to_temp=True)

+def test_code_block_dedent(app):

+    outdir = app.outdir

+

+    def get_dedent_actual(dedent):

+        dedent_text = (app.srcdir / 'dedent.rst').text(encoding='utf-8')

+        dedent_text = re.sub(

+            r':dedent: \d', ':dedent: %d' % dedent, dedent_text)

+        (app.srcdir / 'dedent.rst').write_text(dedent_text, encoding='utf-8')

+

+        # use another output dir to force rebuild

+        app.outdir = outdir / str(dedent)

+        app._init_env(freshenv=True)

+        app._init_builder(app.builder.name)

+        app.builder.build(['dedent'], method='specific')

+

+        et = ElementTree.parse(app.outdir / 'dedent.xml')

+        secs = et.findall('./section/section')

+        code_block = secs[0].findall('literal_block')

+

+        assert len(code_block) > 0

+        actual = code_block[0].text

+        return actual

+

+    for i in range(5):  # 0-4

+        actual = get_dedent_actual(i)

+        indent = " " * (4 - i)

+        expect = (

+            indent + "def ruby?\n" +

+            indent + "    false\n" +

+            indent + "end"

+        )

+        assert (i, actual) == (i, expect)

+

+    actual = get_dedent_actual(1000)

+    assert actual == '\n\n'

+

+

+@with_app(buildername='html',

+          srcdir=(test_roots / 'test-directive-code'),

+          _copy_to_temp=True)

+def test_code_block_caption_html(app):

+    app.builder.build('index')

+    html = (app.outdir / 'caption.html').text()

+    caption = '<div class="code-block-caption"><code>caption-test.rb</code></div>'

+    assert caption in html

+

+

+@with_app(buildername='latex',

+          srcdir=(test_roots / 'test-directive-code'),

+          _copy_to_temp=True)

+def test_code_block_caption_latex(app):

+    app.builder.build('index')

+    latex = (app.outdir / 'Python.tex').text()

+    caption = ('{\\colorbox[rgb]{0.9,0.9,0.9}{\\makebox[\\textwidth][l]'

+               '{\\small\\texttt{caption-test.rb}}}}')

+    assert caption in latex

+

+

+@with_app(buildername='xml',

+          srcdir=(test_roots / 'test-directive-code'),

+          _copy_to_temp=True)

+def test_literal_include(app):

+    app.builder.build('index')

+    et = ElementTree.parse(app.outdir / 'index.xml')

+    secs = et.findall('./section/section')

+    literal_include = secs[1].findall('literal_block')

+    literal_src = (app.srcdir / 'literal.inc').text(encoding='utf-8')

+    assert len(literal_include) > 0

+    actual = literal_include[0].text

+    assert actual == literal_src

+

+

+@with_app(buildername='xml',

+          srcdir=(test_roots / 'test-directive-code'),

+          _copy_to_temp=True)

+def test_literal_include_dedent(app):

+    outdir = app.outdir

+    literal_src = (app.srcdir / 'literal.inc').text(encoding='utf-8')

+    literal_lines = [l[4:] for l in literal_src.split('\n')[9:11]]

+

+    def get_dedent_actual(dedent):

+        dedent_text = (app.srcdir / 'dedent.rst').text(encoding='utf-8')

+        dedent_text = re.sub(

+            r':dedent: \d', ':dedent: %d' % dedent, dedent_text)

+        (app.srcdir / 'dedent.rst').write_text(dedent_text, encoding='utf-8')

+

+        # use another output dir to force rebuild

+        app.outdir = outdir / str(dedent)

+        app._init_env(freshenv=True)

+        app._init_builder(app.builder.name)

+        app.builder.build(['dedent'])

+

+        et = ElementTree.parse(app.outdir / 'dedent.xml')

+        secs = et.findall('./section/section')

+        literal_include = secs[1].findall('literal_block')

+

+        assert len(literal_include) > 0

+        actual = literal_include[0].text

+        return actual

+

+

+    for i in range(5):  # 0-4

+        actual = get_dedent_actual(i)

+        indent = " " * (4 - i)

+        expect = '\n'.join(indent + l for l in literal_lines) + '\n'

+        assert (i, actual) == (i, expect)

+

+

+    actual = get_dedent_actual(1000)

+    assert actual == '\n\n'

+

+

+@with_app(buildername='html',

+          srcdir=(test_roots / 'test-directive-code'),

+          _copy_to_temp=True)

+def test_literalinclude_caption_html(app):

+    app.builder.build('index')

+    html = (app.outdir / 'caption.html').text()

+    caption = '<div class="code-block-caption"><code>caption-test.py</code></div>'

+    assert caption in html

+

+

+@with_app(buildername='latex',

+          srcdir=(test_roots / 'test-directive-code'),

+          _copy_to_temp=True)

+def test_literalinclude_caption_latex(app):

+    app.builder.build('index')

+    latex = (app.outdir / 'Python.tex').text()

+    caption = ('{\\colorbox[rgb]{0.9,0.9,0.9}{\\makebox[\\textwidth][l]'

+               '{\\small\\texttt{caption-test.py}}}}')

+    assert caption in latex

diff --git a/tests/test_only_directive.py b/tests/test_directive_only.py
similarity index 86%
rename from tests/test_only_directive.py
rename to tests/test_directive_only.py
index 4717ff9..7fb1f5b 100644
--- a/tests/test_only_directive.py
+++ b/tests/test_directive_only.py
@@ -17,10 +17,10 @@
 
 
 def teardown_module():
-    (test_roots / 'test-only-directive' / '_build').rmtree(True)
+    (test_roots / 'test-directive-only' / '_build').rmtree(True)
 
 
-@with_app(buildername='text', srcdir=(test_roots / 'test-only-directive'))
+@with_app(buildername='text', srcdir=(test_roots / 'test-directive-only'))
 def test_sectioning(app):
 
     def getsects(section):
@@ -53,8 +53,7 @@
     app.env.process_only_nodes(doctree, app.builder)
 
     parts = [getsects(n)
-             for n in filter(lambda n: isinstance(n, nodes.section),
-                             doctree.children)]
+             for n in [_n for _n in doctree.children if isinstance(_n, nodes.section)]]
     for i, s in enumerate(parts):
         testsects(str(i+1) + '.', s, 4)
     assert len(parts) == 4, 'Expected 4 document level headings, got:\n%s' % \
diff --git a/tests/test_doctest.py b/tests/test_doctest.py
index 2aab541..9fb8a2e 100644
--- a/tests/test_doctest.py
+++ b/tests/test_doctest.py
@@ -8,14 +8,16 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
+from __future__ import print_function
 
 import sys
-import StringIO
+
+from six import StringIO
 
 from util import with_app
 
 
-status = StringIO.StringIO()
+status = StringIO()
 cleanup_called = 0
 
 @with_app(buildername='doctest', status=status)
@@ -24,7 +26,7 @@
     cleanup_called = 0
     app.builder.build_all()
     if app.statuscode != 0:
-        print >>sys.stderr, status.getvalue()
+        print(status.getvalue(), file=sys.stderr)
         assert False, 'failures in doctests'
     # in doctest.txt, there are two named groups and the default group,
     # so the cleanup function must be called three times
diff --git a/tests/test_docutilsconf.py b/tests/test_docutilsconf.py
index 4aeaa56..c0ee4a1 100644
--- a/tests/test_docutilsconf.py
+++ b/tests/test_docutilsconf.py
@@ -11,9 +11,10 @@
 
 import os
 import re
-from StringIO import StringIO
 from functools import wraps
 
+from six import StringIO
+
 from util import test_roots, TestApp, path, SkipTest
 
 
diff --git a/tests/test_domain_cpp.py b/tests/test_domain_cpp.py
new file mode 100644
index 0000000..0b4219a
--- /dev/null
+++ b/tests/test_domain_cpp.py
@@ -0,0 +1,127 @@
+# -*- coding: utf-8 -*-
+"""
+    test_domain_cpp
+    ~~~~~~~~~~~~~~~
+
+    Tests the C++ Domain
+
+    :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from six import text_type
+
+from util import raises
+
+from sphinx.domains.cpp import DefinitionParser, DefinitionError
+
+def parse(name, string):
+    parser = DefinitionParser(string)
+    res = getattr(parser, "parse_" + name + "_object")()
+    if not parser.eof:
+        print("Parsing stopped at", parser.pos)
+        print(string)
+        print('-'*parser.pos + '^')
+        raise DefinitionError("")
+    return res
+
+def check(name, input, output=None):
+    # first a simple check of the AST
+    if output == None: output = input
+    ast = parse(name, input)
+    res = text_type(ast)
+    if res != output:
+        print("Input:    ", text_type(input))
+        print("Result:   ", res)
+        print("Expected: ", output)
+        raise DefinitionError("")
+    ast.describe_signature([], 'lastIsName', None)
+    ast.prefixedName = ast.name # otherwise the get_id fails, it would be set in handle_signarue
+    ast.get_id()
+    #print ".. %s:: %s" % (name, input)
+
+def test_type_definitions():
+    check("type", "public bool b", "bool b")
+    check("type", "bool A::b")
+    check("type", "bool *b")
+    check("type", "bool *const b")
+    check("type", "bool *volatile const b")
+    check("type", "bool *volatile const b")
+    check("type", "bool *volatile const *b")
+    check("type", "bool &b")
+    check("type", "bool b[]") 
+    check("type", "std::pair<int, int> coord")
+    check("type", "long long int foo")
+    check("type", 'std::vector<std::pair<std::string, long long>> module::blah')
+    check("type", "std::function<void()> F")
+    check("type", "std::function<R(A1, A2, A3)> F")
+    check("type", "std::function<R(A1, A2, A3, As...)> F")
+    check("type", "MyContainer::const_iterator")
+    check("type", "public MyContainer::const_iterator", "MyContainer::const_iterator")
+    
+    check('member', '  const  std::string  &  name = 42', 'const std::string &name = 42')
+    check('member', '  const  std::string  &  name', 'const std::string &name')
+    check('member', '  const  std::string  &  name [ n ]', 'const std::string &name[n]')
+    check('member', 'const std::vector< unsigned int, long> &name', 'const std::vector<unsigned int, long> &name')
+    check('member', 'module::myclass foo[n]')
+
+    check('function', 'operator bool() const')
+    check('function', 'bool namespaced::theclass::method(arg1, arg2)')
+    x = 'std::vector<std::pair<std::string, int>> &module::test(register ' \
+        'foo, bar, std::string baz = "foobar, blah, bleh") const = 0'
+    check('function', x)
+    check('function', 'explicit module::myclass::foo::foo()')
+    check('function', 'module::myclass::foo::~foo()')
+    check('function', 'int printf(const char *fmt, ...)')
+    check('function', 'int foo(const unsigned int j)')
+    check('function', 'int foo(const int *const ptr)')
+    check('function', 'module::myclass::operator std::vector<std::string>()')
+    check('function', 'void operator()(const boost::array<VertexID, 2> &v) const')
+    check('function', 'void operator()(const boost::array<VertexID, 2, "foo,  bar"> &v) const')
+    check('function', 'MyClass::MyClass(MyClass::MyClass&&)')
+    check('function', 'constexpr int get_value()')
+    check('function', 'static constexpr int get_value()')
+    check('function', 'int get_value() const noexcept')
+    check('function', 'int get_value() const noexcept = delete')
+    check('function', 'MyClass::MyClass(MyClass::MyClass&&) = default')
+    check('function', 'virtual MyClass::a_virtual_function() const override')
+    check('function', 'A B() override')
+    check('function', 'A B() final')
+    check('function', 'A B() final override')
+    check('function', 'A B() override final', 'A B() final override')
+    check('function', 'MyClass::a_member_function() volatile')
+    check('function', 'MyClass::a_member_function() volatile const')
+    check('function', 'MyClass::a_member_function() &&')
+    check('function', 'MyClass::a_member_function() &')
+    check('function', 'MyClass::a_member_function() const &')
+    check('function', 'int main(int argc, char *argv[])')
+    check('function', 'MyClass &MyClass::operator++()')
+    check('function', 'MyClass::pointer MyClass::operator->()')
+
+    x = 'std::vector<std::pair<std::string, int>> &module::test(register ' \
+        'foo, bar[n], std::string baz = "foobar, blah, bleh") const = 0'
+    check('function', x)
+    check('function', 'int foo(Foo f = Foo(double(), std::make_pair(int(2), double(3.4))))')
+    check('function', 'int foo(A a = x(a))')
+    raises(DefinitionError, parse, 'function', 'int foo(B b=x(a)')
+    raises(DefinitionError, parse, 'function', 'int foo)C c=x(a))')
+    raises(DefinitionError, parse, 'function', 'int foo(D d=x(a')
+    check('function', 'int foo(const A&... a)')
+    check('function', 'virtual void f()')
+
+def test_bases():
+    check('class', 'A')
+    check('class', 'A::B::C')
+    check('class', 'A : B')
+    check('class', 'A : private B', 'A : B')
+    check('class', 'A : public B')
+    check('class', 'A : B, C')
+    check('class', 'A : B, protected C, D')
+
+
+def test_operators():
+    check('function', 'void operator new [  ] ()', 'void operator new[]()')
+    check('function', 'void operator delete ()', 'void operator delete()')
+    check('function', 'void operator bool() const', 'void operator bool() const')
+    for op in '*-+=/%!':
+        check('function', 'void operator %s ()' % op, 'void operator%s()' % op)
diff --git a/tests/test_domain_std.py b/tests/test_domain_std.py
new file mode 100644
index 0000000..81dbe6a
--- /dev/null
+++ b/tests/test_domain_std.py
@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-

+"""

+    test_domain_std

+    ~~~~~~~~~~~~~~~

+

+    Tests the std domain

+

+    :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.

+    :license: BSD, see LICENSE for details.

+"""

+

+from docutils import nodes

+

+from sphinx.domains.std import StandardDomain

+from util import mock

+

+

+def test_process_doc_handle_figure_caption():

+    env = mock.Mock(domaindata={})

+    figure_node = nodes.figure(

+        '',

+        nodes.caption('caption text', 'caption text'),

+    )

+    document = mock.Mock(

+        nametypes={'testname': True},

+        nameids={'testname': 'testid'},

+        ids={'testid': figure_node},

+    )

+

+    domain = StandardDomain(env)

+    if 'testname' in domain.data['labels']:

+        del domain.data['labels']['testname']

+    domain.process_doc(env, 'testdoc', document)

+    assert 'testname' in domain.data['labels']

+    assert domain.data['labels']['testname'] == (

+        'testdoc', 'testid', 'caption text')

+

+

+def test_process_doc_handle_image_parent_figure_caption():

+    env = mock.Mock(domaindata={})

+    img_node = nodes.image('', alt='image alt')

+    figure_node = nodes.figure(

+        '',

+        nodes.caption('caption text', 'caption text'),

+        img_node,

+    )

+    document = mock.Mock(

+        nametypes={'testname': True},

+        nameids={'testname': 'testid'},

+        ids={'testid': img_node},

+    )

+

+    domain = StandardDomain(env)

+    if 'testname' in domain.data['labels']:

+        del domain.data['labels']['testname']

+    domain.process_doc(env, 'testdoc', document)

+    assert 'testname' in domain.data['labels']

+    assert domain.data['labels']['testname'] == (

+        'testdoc', 'testid', 'caption text')

+

+

+def test_process_doc_handle_table_title():

+    env = mock.Mock(domaindata={})

+    table_node = nodes.table(

+        '',

+        nodes.title('title text', 'title text'),

+    )

+    document = mock.Mock(

+        nametypes={'testname': True},

+        nameids={'testname': 'testid'},

+        ids={'testid': table_node},

+    )

+

+    domain = StandardDomain(env)

+    if 'testname' in domain.data['labels']:

+        del domain.data['labels']['testname']

+    domain.process_doc(env, 'testdoc', document)

+    assert 'testname' in domain.data['labels']

+    assert domain.data['labels']['testname'] == (

+        'testdoc', 'testid', 'title text')

diff --git a/tests/test_env.py b/tests/test_env.py
index eaaa212..3dc7431 100644
--- a/tests/test_env.py
+++ b/tests/test_env.py
@@ -8,9 +8,9 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
-import sys
+from six import PY3
 
-from util import TestApp, remove_unicode_literals, path
+from util import TestApp, remove_unicode_literals, path, with_app
 
 from sphinx.builders.html import StandaloneHTMLBuilder
 from sphinx.builders.latex import LaTeXBuilder
@@ -20,7 +20,7 @@
 
 def setup_module():
     global app, env
-    app = TestApp(srcdir='(temp)', freshenv=True)
+    app = TestApp(freshenv=True, _copy_to_temp=True)
     env = app.env
     env.set_warnfunc(lambda *args: warnings.append(args))
 
@@ -57,7 +57,7 @@
     htmlbuilder.imgpath = 'dummy'
     htmlbuilder.post_process_images(tree)
     image_uri_message = "no matching candidate for image URI u'foo.*'"
-    if sys.version_info >= (3, 0):
+    if PY3:
         image_uri_message = remove_unicode_literals(image_uri_message)
     assert image_uri_message in app._warning.content[-1]
     assert set(htmlbuilder.images.keys()) == \
@@ -95,6 +95,20 @@
     assert 'autodoc' not in env.all_docs
     assert 'autodoc' not in env.found_docs
 
+
+@with_app(srcdir='(empty)')
+def test_undecodable_source_reading_emit_warnings(app):
+    # issue #1524
+    warnings[:] = []
+    app.env.set_warnfunc(lambda *args: warnings.append(args))
+    (app.srcdir / 'contents.rst').write_bytes(b'1\xbb2')
+    _, _, it = app.env.update(app.config, app.srcdir, app.doctreedir, app)
+    list(it)  # the generator does all the work
+    assert warning_emitted(
+        'contents', 'undecodable source characters, replacing with "?":'
+    )
+
+
 def test_object_inventory():
     refs = env.domaindata['py']['objects']
 
diff --git a/tests/test_ext_viewcode.py b/tests/test_ext_viewcode.py
new file mode 100644
index 0000000..60ab794
--- /dev/null
+++ b/tests/test_ext_viewcode.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-

+"""

+    test_ext_viewcode

+    ~~~~~~~~~~~~~~~~~

+

+    Test sphinx.ext.viewcode extension.

+

+    :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.

+    :license: BSD, see LICENSE for details.

+"""

+

+import re

+

+from six import StringIO

+

+from util import test_roots, with_app

+

+

+warnfile = StringIO()

+root = test_roots / 'test-ext-viewcode'

+doctreedir = root / '_build' / 'doctree'

+

+

+def teardown_module():

+    (root / '_build').rmtree(True)

+

+

+@with_app(srcdir=root, warning=warnfile)

+def test_simple(app):

+    app.builder.build_all()

+

+    warnings = re.sub(r'\\+', '/', warnfile.getvalue())

+    assert re.findall(

+        r"index.rst:\d+: WARNING: Object named 'func1' not found in include " +

+        r"file .*/spam/__init__.py'",

+        warnings

+    )

+

+    result = (app.outdir / 'index.html').text(encoding='utf-8')

+    assert result.count('href="_modules/spam/mod1.html#func1"') == 2

+    assert result.count('href="_modules/spam/mod2.html#func2"') == 2

+    assert result.count('href="_modules/spam/mod1.html#Class1"') == 2

+    assert result.count('href="_modules/spam/mod2.html#Class2"') == 2

diff --git a/tests/test_intersphinx.py b/tests/test_intersphinx.py
index 8f0263b..dd71c6f 100644
--- a/tests/test_intersphinx.py
+++ b/tests/test_intersphinx.py
@@ -11,18 +11,15 @@
 
 import zlib
 import posixpath
-try:
-    from io import BytesIO
-except ImportError:
-    from cStringIO import StringIO as BytesIO
 
+from six import BytesIO
 from docutils import nodes
 
 from sphinx import addnodes
 from sphinx.ext.intersphinx import read_inventory_v1, read_inventory_v2, \
      load_mappings, missing_reference
 
-from util import with_app, with_tempdir, write_file
+from util import with_app, with_tempdir
 
 
 inventory_v1 = '''\
@@ -81,11 +78,11 @@
            '/util/glossary.html#term-a-term'
 
 
-@with_app(confoverrides={'extensions': 'sphinx.ext.intersphinx'})
+@with_app()
 @with_tempdir
 def test_missing_reference(tempdir, app):
     inv_file = tempdir / 'inventory'
-    write_file(inv_file, inventory_v2)
+    inv_file.write_bytes(inventory_v2)
     app.config.intersphinx_mapping = {
         'http://docs.python.org/': inv_file,
         'py3k': ('http://docs.python.org/py3k/', inv_file),
@@ -157,7 +154,7 @@
     assert contnode[0].astext() == 'py3k:unknown'
 
 
-@with_app(confoverrides={'extensions': 'sphinx.ext.intersphinx'})
+@with_app()
 @with_tempdir
 def test_load_mappings_warnings(tempdir, app):
     """
@@ -165,7 +162,7 @@
     identifiers are not alphanumeric
     """
     inv_file = tempdir / 'inventory'
-    write_file(inv_file, inventory_v2)
+    inv_file.write_bytes(inventory_v2)
     app.config.intersphinx_mapping = {
         'http://docs.python.org/': inv_file,
         'py3k': ('http://docs.python.org/py3k/', inv_file),
diff --git a/tests/test_intl.py b/tests/test_intl.py
index ca0273c..bb54e5d 100644
--- a/tests/test_intl.py
+++ b/tests/test_intl.py
@@ -9,14 +9,14 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
+from __future__ import print_function
 
 import os
 import re
-from StringIO import StringIO
 from subprocess import Popen, PIPE
 from xml.etree import ElementTree
 
-from sphinx.util.pycompat import relpath
+from six import StringIO, string_types
 
 from util import test_roots, path, with_app, SkipTest
 
@@ -49,7 +49,7 @@
         for f in [f for f in files if f.endswith('.po')]:
             po = dirpath / f
             mo = root / 'xx' / 'LC_MESSAGES' / (
-                    relpath(po[:-3], root) + '.mo')
+                    os.path.relpath(po[:-3], root) + '.mo')
             if not mo.parent.exists():
                 mo.parent.makedirs()
             try:
@@ -60,8 +60,8 @@
             else:
                 stdout, stderr = p.communicate()
                 if p.returncode != 0:
-                    print stdout
-                    print stderr
+                    print(stdout)
+                    print(stderr)
                     assert False, \
                         'msgfmt exited with return code %s' % p.returncode
                 assert mo.isfile(), 'msgfmt failed'
@@ -75,9 +75,9 @@
 def elem_gettexts(elem):
     def itertext(self):
         # this function copied from Python-2.7 'ElementTree.itertext'.
-        # for compatibility to Python-2.5, 2.6, 3.1
+        # for compatibility to Python-2.6
         tag = self.tag
-        if not isinstance(tag, basestring) and tag is not None:
+        if not isinstance(tag, string_types) and tag is not None:
             return
         if self.text:
             yield self.text
@@ -86,7 +86,7 @@
                 yield s
             if e.tail:
                 yield e.tail
-    return filter(None, [s.strip() for s in itertext(elem)])
+    return [_f for _f in [s.strip() for s in itertext(elem)] if _f]
 
 
 def elem_getref(elem):
@@ -98,7 +98,7 @@
         _texts = elem_gettexts(elem)
         assert _texts == texts
     if refs is not None:
-        _refs = map(elem_getref, elem.findall('reference'))
+        _refs = [elem_getref(x) for x in elem.findall('reference')]
         assert _refs == refs
     if names is not None:
         _names = elem.attrib.get('names').split()
diff --git a/tests/test_linkcode.py b/tests/test_linkcode.py
index 83b7209..4584777 100644
--- a/tests/test_linkcode.py
+++ b/tests/test_linkcode.py
@@ -13,7 +13,7 @@
 from util import with_app
 
 
-@with_app(srcdir='(temp)', buildername='html', tags=['test_linkcode'])
+@with_app(buildername='html', tags=['test_linkcode'], _copy_to_temp=True)
 def test_html(app):
     app.builder.build_all()
 
diff --git a/tests/test_markup.py b/tests/test_markup.py
index 4f0b0de..81ade64 100644
--- a/tests/test_markup.py
+++ b/tests/test_markup.py
@@ -15,7 +15,6 @@
 from docutils.parsers import rst
 
 from sphinx.util import texescape
-from sphinx.util.pycompat import b
 from sphinx.writers.html import HTMLWriter, SmartyPantsHTMLTranslator
 from sphinx.writers.latex import LaTeXWriter, LaTeXTranslator
 
@@ -54,7 +53,7 @@
 
 
 def verify_re(rst, html_expected, latex_expected):
-    document = utils.new_document(b('test data'), settings)
+    document = utils.new_document(b'test data', settings)
     document['file'] = 'dummy'
     parser.parse(rst, document)
     for msg in document.traverse(nodes.system_message):
@@ -84,16 +83,16 @@
 
 def test_inline():
     # correct interpretation of code with whitespace
-    _html = ('<p><tt class="(samp )?docutils literal"><span class="pre">'
-             'code</span>&nbsp;&nbsp; <span class="pre">sample</span></tt></p>')
+    _html = ('<p><code class="(samp )?docutils literal"><span class="pre">'
+             'code</span>&nbsp;&nbsp; <span class="pre">sample</span></code></p>')
     yield verify_re, '``code   sample``', _html, r'\\code{code   sample}'
     yield verify_re, ':samp:`code   sample`', _html, r'\\code{code   sample}'
 
     # interpolation of braces in samp and file roles (HTML only)
     yield (verify, ':samp:`a{b}c`',
-           '<p><tt class="samp docutils literal"><span class="pre">a</span>'
+           '<p><code class="samp docutils literal"><span class="pre">a</span>'
            '<em><span class="pre">b</span></em>'
-           '<span class="pre">c</span></tt></p>',
+           '<span class="pre">c</span></code></p>',
            '\\code{a\\emph{b}c}')
 
     # interpolation of arrows in menuselection
@@ -116,8 +115,8 @@
     yield verify, '"John"', '<p>&#8220;John&#8221;</p>', "``John''"
     # ... but not in literal text
     yield (verify, '``"John"``',
-           '<p><tt class="docutils literal"><span class="pre">'
-           '&quot;John&quot;</span></tt></p>',
+           '<p><code class="docutils literal"><span class="pre">'
+           '&quot;John&quot;</span></code></p>',
            '\\code{"John"}')
 
     # verify classes for inline roles
@@ -128,7 +127,7 @@
 def test_latex_escaping():
     # correct escaping in normal mode
     yield (verify, u'Γ\\\\∞$', None,
-           ur'\(\Gamma\)\textbackslash{}\(\infty\)\$')
+           r'\(\Gamma\)\textbackslash{}\(\infty\)\$')
     # in verbatim code fragments
     yield (verify, u'::\n\n @Γ\\∞${}', None,
            u'\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n'
@@ -136,4 +135,4 @@
            u'\\end{Verbatim}')
     # in URIs
     yield (verify_re, u'`test <http://example.com/~me/>`_', None,
-           ur'\\href{http://example.com/~me/}{test}.*')
+           r'\\href{http://example.com/~me/}{test}.*')
diff --git a/tests/test_metadata.py b/tests/test_metadata.py
index a0d4445..a3fd135 100644
--- a/tests/test_metadata.py
+++ b/tests/test_metadata.py
@@ -23,7 +23,7 @@
 def setup_module():
     # Is there a better way of generating this doctree than manually iterating?
     global app, env
-    app = TestApp(srcdir='(temp)')
+    app = TestApp(_copy_to_temp=True)
     env = app.env
     msg, num, it = env.update(app.config, app.srcdir, app.doctreedir, app)
     for docname in it:
@@ -61,6 +61,9 @@
         'date': u'2006-05-21',
         'organization': u'humankind',
         'revision': u'4564',
+        'tocdepth': 1,
+        'orphan': u'',
+        'nocomments': u'',
     }
     # I like this way of comparing dicts - easier to see the error.
     for key in exampledocinfo:
diff --git a/tests/test_napoleon.py b/tests/test_napoleon.py
new file mode 100644
index 0000000..e2790d3
--- /dev/null
+++ b/tests/test_napoleon.py
@@ -0,0 +1,199 @@
+# -*- coding: utf-8 -*-
+"""
+    test_napoleon
+    ~~~~~~~~~~~~~
+
+    Tests for :mod:`sphinx.ext.napoleon.__init__` module.
+
+
+    :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from collections import namedtuple
+from unittest import TestCase
+
+from sphinx.application import Sphinx
+from sphinx.ext.napoleon import (_process_docstring, _skip_member, Config,
+                                 setup)
+from util import mock
+
+
+def _private_doc():
+    """module._private_doc.DOCSTRING"""
+    pass
+
+
+def _private_undoc():
+    pass
+
+
+def __special_doc__():
+    """module.__special_doc__.DOCSTRING"""
+    pass
+
+
+def __special_undoc__():
+    pass
+
+
+class SampleClass(object):
+    def _private_doc(self):
+        """SampleClass._private_doc.DOCSTRING"""
+        pass
+
+    def _private_undoc(self):
+        pass
+
+    def __special_doc__(self):
+        """SampleClass.__special_doc__.DOCSTRING"""
+        pass
+
+    def __special_undoc__(self):
+        pass
+
+
+class SampleError(Exception):
+    def _private_doc(self):
+        """SampleError._private_doc.DOCSTRING"""
+        pass
+
+    def _private_undoc(self):
+        pass
+
+    def __special_doc__(self):
+        """SampleError.__special_doc__.DOCSTRING"""
+        pass
+
+    def __special_undoc__(self):
+        pass
+
+SampleNamedTuple = namedtuple('SampleNamedTuple', 'user_id block_type def_id')
+
+
+class ProcessDocstringTest(TestCase):
+    def test_modify_in_place(self):
+        lines = ['Summary line.',
+                 '',
+                 'Args:',
+                 '   arg1: arg1 description']
+        app = mock.Mock()
+        app.config = Config()
+        _process_docstring(app, 'class', 'SampleClass', SampleClass,
+                           mock.Mock(), lines)
+
+        expected = ['Summary line.',
+                    '',
+                    ':param arg1: arg1 description',
+                    '']
+        self.assertEqual(expected, lines)
+
+
+class SetupTest(TestCase):
+    def test_unknown_app_type(self):
+        setup(object())
+
+    def test_add_config_values(self):
+        app = mock.Mock(Sphinx)
+        setup(app)
+        for name, (default, rebuild) in Config._config_values.items():
+            has_config = False
+            for method_name, args, kwargs in app.method_calls:
+                if(method_name == 'add_config_value' and
+                   args[0] == name):
+                    has_config = True
+            if not has_config:
+                self.fail('Config value was not added to app %s' % name)
+
+        has_process_docstring = False
+        has_skip_member = False
+        for method_name, args, kwargs in app.method_calls:
+            if method_name == 'connect':
+                if(args[0] == 'autodoc-process-docstring' and
+                   args[1] == _process_docstring):
+                    has_process_docstring = True
+                elif(args[0] == 'autodoc-skip-member' and
+                     args[1] == _skip_member):
+                    has_skip_member = True
+        if not has_process_docstring:
+            self.fail('autodoc-process-docstring never connected')
+        if not has_skip_member:
+            self.fail('autodoc-skip-member never connected')
+
+
+class SkipMemberTest(TestCase):
+    def assertSkip(self, what, member, obj, expect_skip, config_name):
+        skip = 'default skip'
+        app = mock.Mock()
+        app.config = Config()
+        setattr(app.config, config_name, True)
+        if expect_skip:
+            self.assertEqual(skip, _skip_member(app, what, member, obj, skip,
+                                                mock.Mock()))
+        else:
+            self.assertFalse(_skip_member(app, what, member, obj, skip,
+                                          mock.Mock()))
+        setattr(app.config, config_name, False)
+        self.assertEqual(skip, _skip_member(app, what, member, obj, skip,
+                                            mock.Mock()))
+
+    def test_namedtuple(self):
+        self.assertSkip('class', '_asdict',
+                        SampleNamedTuple._asdict, False,
+                        'napoleon_include_private_with_doc')
+
+    def test_class_private_doc(self):
+        self.assertSkip('class', '_private_doc',
+                        SampleClass._private_doc, False,
+                        'napoleon_include_private_with_doc')
+
+    def test_class_private_undoc(self):
+        self.assertSkip('class', '_private_undoc',
+                        SampleClass._private_undoc, True,
+                        'napoleon_include_private_with_doc')
+
+    def test_class_special_doc(self):
+        self.assertSkip('class', '__special_doc__',
+                        SampleClass.__special_doc__, False,
+                        'napoleon_include_special_with_doc')
+
+    def test_class_special_undoc(self):
+        self.assertSkip('class', '__special_undoc__',
+                        SampleClass.__special_undoc__, True,
+                        'napoleon_include_special_with_doc')
+
+    def test_exception_private_doc(self):
+        self.assertSkip('exception', '_private_doc',
+                        SampleError._private_doc, False,
+                        'napoleon_include_private_with_doc')
+
+    def test_exception_private_undoc(self):
+        self.assertSkip('exception', '_private_undoc',
+                        SampleError._private_undoc, True,
+                        'napoleon_include_private_with_doc')
+
+    def test_exception_special_doc(self):
+        self.assertSkip('exception', '__special_doc__',
+                        SampleError.__special_doc__, False,
+                        'napoleon_include_special_with_doc')
+
+    def test_exception_special_undoc(self):
+        self.assertSkip('exception', '__special_undoc__',
+                        SampleError.__special_undoc__, True,
+                        'napoleon_include_special_with_doc')
+
+    def test_module_private_doc(self):
+        self.assertSkip('module', '_private_doc', _private_doc, False,
+                        'napoleon_include_private_with_doc')
+
+    def test_module_private_undoc(self):
+        self.assertSkip('module', '_private_undoc', _private_undoc, True,
+                        'napoleon_include_private_with_doc')
+
+    def test_module_special_doc(self):
+        self.assertSkip('module', '__special_doc__', __special_doc__, False,
+                        'napoleon_include_special_with_doc')
+
+    def test_module_special_undoc(self):
+        self.assertSkip('module', '__special_undoc__', __special_undoc__, True,
+                        'napoleon_include_special_with_doc')
diff --git a/tests/test_napoleon_docstring.py b/tests/test_napoleon_docstring.py
new file mode 100644
index 0000000..3b5c4fc
--- /dev/null
+++ b/tests/test_napoleon_docstring.py
@@ -0,0 +1,442 @@
+# -*- coding: utf-8 -*-
+"""
+    test_napoleon_docstring
+    ~~~~~~~~~~~~~~~~~~~~~~~
+
+    Tests for :mod:`sphinx.ext.napoleon.docstring` module.
+
+
+    :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import textwrap
+from unittest import TestCase
+
+from sphinx.ext.napoleon import Config
+from sphinx.ext.napoleon.docstring import GoogleDocstring, NumpyDocstring
+from util import mock
+
+
+class BaseDocstringTest(TestCase):
+    pass
+
+
+class GoogleDocstringTest(BaseDocstringTest):
+    docstrings = [(
+        """Single line summary""",
+        """Single line summary"""
+    ), (
+        """
+        Single line summary
+
+        Extended description
+
+        """,
+        """
+        Single line summary
+
+        Extended description
+        """
+    ), (
+        """
+        Single line summary
+
+        Args:
+          arg1(str):Extended
+            description of arg1
+        """,
+        """
+        Single line summary
+
+        :Parameters: **arg1** (*str*) --
+                     Extended
+                     description of arg1"""
+    ), (
+        """
+        Single line summary
+
+        Args:
+          arg1(str):Extended
+            description of arg1
+          arg2 ( int ) : Extended
+            description of arg2
+
+        Keyword Args:
+          kwarg1(str):Extended
+            description of kwarg1
+          kwarg2 ( int ) : Extended
+            description of kwarg2""",
+        """
+        Single line summary
+
+        :Parameters: * **arg1** (*str*) --
+                       Extended
+                       description of arg1
+                     * **arg2** (*int*) --
+                       Extended
+                       description of arg2
+
+        :Keyword Arguments: * **kwarg1** (*str*) --
+                              Extended
+                              description of kwarg1
+                            * **kwarg2** (*int*) --
+                              Extended
+                              description of kwarg2"""
+    ), (
+        """
+        Single line summary
+
+        Arguments:
+          arg1(str):Extended
+            description of arg1
+          arg2 ( int ) : Extended
+            description of arg2
+
+        Keyword Arguments:
+          kwarg1(str):Extended
+            description of kwarg1
+          kwarg2 ( int ) : Extended
+            description of kwarg2""",
+        """
+        Single line summary
+
+        :Parameters: * **arg1** (*str*) --
+                       Extended
+                       description of arg1
+                     * **arg2** (*int*) --
+                       Extended
+                       description of arg2
+
+        :Keyword Arguments: * **kwarg1** (*str*) --
+                              Extended
+                              description of kwarg1
+                            * **kwarg2** (*int*) --
+                              Extended
+                              description of kwarg2"""
+    ), (
+        """
+        Single line summary
+
+        Return:
+          str:Extended
+          description of return value
+        """,
+        """
+        Single line summary
+
+        :returns: *str* --
+                  Extended
+                  description of return value"""
+    ), (
+        """
+        Single line summary
+
+        Returns:
+          str:Extended
+          description of return value
+        """,
+        """
+        Single line summary
+
+        :returns: *str* --
+                  Extended
+                  description of return value"""
+    ), (
+        """
+        Single line summary
+
+        Returns:
+          Extended
+          description of return value
+        """,
+        """
+        Single line summary
+
+        :returns: Extended
+                  description of return value"""
+    )]
+
+    def test_docstrings(self):
+        config = Config(napoleon_use_param=False, napoleon_use_rtype=False)
+        for docstring, expected in self.docstrings:
+            actual = str(GoogleDocstring(textwrap.dedent(docstring), config))
+            expected = textwrap.dedent(expected)
+            self.assertEqual(expected, actual)
+
+    def test_parameters_with_class_reference(self):
+        docstring = """\
+Construct a new XBlock.
+
+This class should only be used by runtimes.
+
+Arguments:
+    runtime (:class:`Runtime`): Use it to access the environment.
+        It is available in XBlock code as ``self.runtime``.
+
+    field_data (:class:`FieldData`): Interface used by the XBlock
+        fields to access their data from wherever it is persisted.
+
+    scope_ids (:class:`ScopeIds`): Identifiers needed to resolve scopes.
+
+"""
+
+        actual = str(GoogleDocstring(docstring))
+        expected = """\
+Construct a new XBlock.
+
+This class should only be used by runtimes.
+
+:param runtime: Use it to access the environment.
+                It is available in XBlock code as ``self.runtime``.
+
+:type runtime: :class:`Runtime`
+:param field_data: Interface used by the XBlock
+                   fields to access their data from wherever it is persisted.
+
+:type field_data: :class:`FieldData`
+:param scope_ids: Identifiers needed to resolve scopes.
+
+:type scope_ids: :class:`ScopeIds`
+"""
+        self.assertEqual(expected, actual)
+
+    def test_attributes_with_class_reference(self):
+        docstring = """\
+Attributes:
+    in_attr(:class:`numpy.ndarray`): super-dooper attribute
+"""
+
+        actual = str(GoogleDocstring(docstring))
+        expected = """\
+.. attribute:: in_attr
+
+   :class:`numpy.ndarray`
+
+   super-dooper attribute
+"""
+        self.assertEqual(expected, actual)
+
+        docstring = """\
+Attributes:
+    in_attr(numpy.ndarray): super-dooper attribute
+"""
+
+        actual = str(GoogleDocstring(docstring))
+        expected = """\
+.. attribute:: in_attr
+
+   *numpy.ndarray*
+
+   super-dooper attribute
+"""
+        self.assertEqual(expected, actual)
+
+
+class NumpyDocstringTest(BaseDocstringTest):
+    docstrings = [(
+        """Single line summary""",
+        """Single line summary"""
+    ), (
+        """
+        Single line summary
+
+        Extended description
+
+        """,
+        """
+        Single line summary
+
+        Extended description
+        """
+    ), (
+        """
+        Single line summary
+
+        Parameters
+        ----------
+        arg1:str
+            Extended
+            description of arg1
+        """,
+        """
+        Single line summary
+
+        :Parameters: **arg1** (*str*) --
+                     Extended
+                     description of arg1"""
+    ), (
+        """
+        Single line summary
+
+        Parameters
+        ----------
+        arg1:str
+            Extended
+            description of arg1
+        arg2 : int
+            Extended
+            description of arg2
+
+        Keyword Arguments
+        -----------------
+          kwarg1:str
+              Extended
+              description of kwarg1
+          kwarg2 : int
+              Extended
+              description of kwarg2
+        """,
+        """
+        Single line summary
+
+        :Parameters: * **arg1** (*str*) --
+                       Extended
+                       description of arg1
+                     * **arg2** (*int*) --
+                       Extended
+                       description of arg2
+
+        :Keyword Arguments: * **kwarg1** (*str*) --
+                              Extended
+                              description of kwarg1
+                            * **kwarg2** (*int*) --
+                              Extended
+                              description of kwarg2"""
+    ), (
+        """
+        Single line summary
+
+        Return
+        ------
+        str
+            Extended
+            description of return value
+        """,
+        """
+        Single line summary
+
+        :returns: *str* --
+                  Extended
+                  description of return value"""
+    ), (
+        """
+        Single line summary
+
+        Returns
+        -------
+        str
+            Extended
+            description of return value
+        """,
+        """
+        Single line summary
+
+        :returns: *str* --
+                  Extended
+                  description of return value"""
+    )]
+
+    def test_docstrings(self):
+        config = Config(napoleon_use_param=False, napoleon_use_rtype=False)
+        for docstring, expected in self.docstrings:
+            actual = str(NumpyDocstring(textwrap.dedent(docstring), config))
+            expected = textwrap.dedent(expected)
+            self.assertEqual(expected, actual)
+
+    def test_parameters_with_class_reference(self):
+        docstring = """\
+Parameters
+----------
+param1 : :class:`MyClass <name.space.MyClass>` instance
+
+"""
+
+        config = Config(napoleon_use_param=False)
+        actual = str(NumpyDocstring(docstring, config))
+        expected = """\
+:Parameters: **param1** (:class:`MyClass <name.space.MyClass>` instance)
+"""
+        self.assertEqual(expected, actual)
+
+        config = Config(napoleon_use_param=True)
+        actual = str(NumpyDocstring(docstring, config))
+        expected = """\
+
+:type param1: :class:`MyClass <name.space.MyClass>` instance
+"""
+        self.assertEqual(expected, actual)
+
+    def test_parameters_without_class_reference(self):
+        docstring = """\
+Parameters
+----------
+param1 : MyClass instance
+
+"""
+
+        config = Config(napoleon_use_param=False)
+        actual = str(NumpyDocstring(docstring, config))
+        expected = """\
+:Parameters: **param1** (*MyClass instance*)
+"""
+        self.assertEqual(expected, actual)
+
+        config = Config(napoleon_use_param=True)
+        actual = str(NumpyDocstring(textwrap.dedent(docstring), config))
+        expected = """\
+
+:type param1: MyClass instance
+"""
+        self.assertEqual(expected, actual)
+
+    def test_see_also_refs(self):
+        docstring = """\
+numpy.multivariate_normal(mean, cov, shape=None, spam=None)
+
+See Also
+--------
+some, other, funcs
+otherfunc : relationship
+
+"""
+
+        actual = str(NumpyDocstring(docstring))
+
+        expected = """\
+numpy.multivariate_normal(mean, cov, shape=None, spam=None)
+
+.. seealso::
+
+   :obj:`some`, :obj:`other`, :obj:`funcs`
+   \n\
+   :obj:`otherfunc`
+       relationship
+"""
+        self.assertEqual(expected, actual)
+
+        docstring = """\
+numpy.multivariate_normal(mean, cov, shape=None, spam=None)
+
+See Also
+--------
+some, other, funcs
+otherfunc : relationship
+
+"""
+
+        config = Config()
+        app = mock.Mock()
+        actual = str(NumpyDocstring(docstring, config, app, "method"))
+
+        expected = """\
+numpy.multivariate_normal(mean, cov, shape=None, spam=None)
+
+.. seealso::
+
+   :meth:`some`, :meth:`other`, :meth:`funcs`
+   \n\
+   :meth:`otherfunc`
+       relationship
+"""
+        self.assertEqual(expected, actual)
diff --git a/tests/test_napoleon_iterators.py b/tests/test_napoleon_iterators.py
new file mode 100644
index 0000000..320047e
--- /dev/null
+++ b/tests/test_napoleon_iterators.py
@@ -0,0 +1,346 @@
+# -*- coding: utf-8 -*-
+"""
+    test_napoleon_iterators
+    ~~~~~~~~~~~~~~~~~~~~~~~
+
+    Tests for :mod:`sphinx.ext.napoleon.iterators` module.
+
+
+    :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from sphinx.ext.napoleon.iterators import peek_iter, modify_iter
+from unittest import TestCase
+
+
+class BaseIteratorsTest(TestCase):
+    def assertEqualTwice(self, expected, func, *args):
+        self.assertEqual(expected, func(*args))
+        self.assertEqual(expected, func(*args))
+
+    def assertFalseTwice(self, func, *args):
+        self.assertFalse(func(*args))
+        self.assertFalse(func(*args))
+
+    def assertNext(self, it, expected, is_last):
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice(expected, it.peek)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice(expected, it.peek)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqual(expected, next(it))
+        if is_last:
+            self.assertFalseTwice(it.has_next)
+            self.assertRaisesTwice(StopIteration, it.next)
+        else:
+            self.assertTrueTwice(it.has_next)
+
+    def assertRaisesTwice(self, exc, func, *args):
+        self.assertRaises(exc, func, *args)
+        self.assertRaises(exc, func, *args)
+
+    def assertTrueTwice(self, func, *args):
+        self.assertTrue(func(*args))
+        self.assertTrue(func(*args))
+
+
+class PeekIterTest(BaseIteratorsTest):
+    def test_init_with_sentinel(self):
+        a = iter(['1', '2', 'DONE'])
+        sentinel = 'DONE'
+        self.assertRaises(TypeError, peek_iter, a, sentinel)
+
+        def get_next():
+            return next(a)
+        it = peek_iter(get_next, sentinel)
+        self.assertEqual(it.sentinel, sentinel)
+        self.assertNext(it, '1', is_last=False)
+        self.assertNext(it, '2', is_last=True)
+
+    def test_iter(self):
+        a = ['1', '2', '3']
+        it = peek_iter(a)
+        self.assertTrue(it is it.__iter__())
+
+        a = []
+        b = [i for i in peek_iter(a)]
+        self.assertEqual([], b)
+
+        a = ['1']
+        b = [i for i in peek_iter(a)]
+        self.assertEqual(['1'], b)
+
+        a = ['1', '2']
+        b = [i for i in peek_iter(a)]
+        self.assertEqual(['1', '2'], b)
+
+        a = ['1', '2', '3']
+        b = [i for i in peek_iter(a)]
+        self.assertEqual(['1', '2', '3'], b)
+
+    def test_next_with_multi(self):
+        a = []
+        it = peek_iter(a)
+        self.assertFalseTwice(it.has_next)
+        self.assertRaisesTwice(StopIteration, it.next, 2)
+
+        a = ['1']
+        it = peek_iter(a)
+        self.assertTrueTwice(it.has_next)
+        self.assertRaisesTwice(StopIteration, it.next, 2)
+        self.assertTrueTwice(it.has_next)
+
+        a = ['1', '2']
+        it = peek_iter(a)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqual(['1', '2'], it.next(2))
+        self.assertFalseTwice(it.has_next)
+
+        a = ['1', '2', '3']
+        it = peek_iter(a)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqual(['1', '2'], it.next(2))
+        self.assertTrueTwice(it.has_next)
+        self.assertRaisesTwice(StopIteration, it.next, 2)
+        self.assertTrueTwice(it.has_next)
+
+        a = ['1', '2', '3', '4']
+        it = peek_iter(a)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqual(['1', '2'], it.next(2))
+        self.assertTrueTwice(it.has_next)
+        self.assertEqual(['3', '4'], it.next(2))
+        self.assertFalseTwice(it.has_next)
+        self.assertRaisesTwice(StopIteration, it.next, 2)
+        self.assertFalseTwice(it.has_next)
+
+    def test_next_with_none(self):
+        a = []
+        it = peek_iter(a)
+        self.assertFalseTwice(it.has_next)
+        self.assertRaisesTwice(StopIteration, it.next)
+        self.assertFalseTwice(it.has_next)
+
+        a = ['1']
+        it = peek_iter(a)
+        self.assertEqual('1', it.__next__())
+
+        a = ['1']
+        it = peek_iter(a)
+        self.assertNext(it, '1', is_last=True)
+
+        a = ['1', '2']
+        it = peek_iter(a)
+        self.assertNext(it, '1', is_last=False)
+        self.assertNext(it, '2', is_last=True)
+
+        a = ['1', '2', '3']
+        it = peek_iter(a)
+        self.assertNext(it, '1', is_last=False)
+        self.assertNext(it, '2', is_last=False)
+        self.assertNext(it, '3', is_last=True)
+
+    def test_next_with_one(self):
+        a = []
+        it = peek_iter(a)
+        self.assertFalseTwice(it.has_next)
+        self.assertRaisesTwice(StopIteration, it.next, 1)
+
+        a = ['1']
+        it = peek_iter(a)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqual(['1'], it.next(1))
+        self.assertFalseTwice(it.has_next)
+        self.assertRaisesTwice(StopIteration, it.next, 1)
+
+        a = ['1', '2']
+        it = peek_iter(a)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqual(['1'], it.next(1))
+        self.assertTrueTwice(it.has_next)
+        self.assertEqual(['2'], it.next(1))
+        self.assertFalseTwice(it.has_next)
+        self.assertRaisesTwice(StopIteration, it.next, 1)
+
+    def test_next_with_zero(self):
+        a = []
+        it = peek_iter(a)
+        self.assertFalseTwice(it.has_next)
+        self.assertRaisesTwice(StopIteration, it.next, 0)
+
+        a = ['1']
+        it = peek_iter(a)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice([], it.next, 0)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice([], it.next, 0)
+
+        a = ['1', '2']
+        it = peek_iter(a)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice([], it.next, 0)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice([], it.next, 0)
+
+    def test_peek_with_multi(self):
+        a = []
+        it = peek_iter(a)
+        self.assertFalseTwice(it.has_next)
+        self.assertEqualTwice([it.sentinel, it.sentinel], it.peek, 2)
+        self.assertFalseTwice(it.has_next)
+
+        a = ['1']
+        it = peek_iter(a)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice(['1', it.sentinel], it.peek, 2)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice(['1', it.sentinel, it.sentinel], it.peek, 3)
+        self.assertTrueTwice(it.has_next)
+
+        a = ['1', '2']
+        it = peek_iter(a)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice(['1', '2'], it.peek, 2)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice(['1', '2', it.sentinel], it.peek, 3)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice(['1', '2', it.sentinel, it.sentinel], it.peek, 4)
+        self.assertTrueTwice(it.has_next)
+
+        a = ['1', '2', '3']
+        it = peek_iter(a)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice(['1', '2'], it.peek, 2)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice(['1', '2', '3'], it.peek, 3)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice(['1', '2', '3', it.sentinel], it.peek, 4)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqual('1', next(it))
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice(['2', '3'], it.peek, 2)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice(['2', '3', it.sentinel], it.peek, 3)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice(['2', '3', it.sentinel, it.sentinel], it.peek, 4)
+        self.assertTrueTwice(it.has_next)
+
+    def test_peek_with_none(self):
+        a = []
+        it = peek_iter(a)
+        self.assertFalseTwice(it.has_next)
+        self.assertEqualTwice(it.sentinel, it.peek)
+        self.assertFalseTwice(it.has_next)
+
+        a = ['1']
+        it = peek_iter(a)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice('1', it.peek)
+        self.assertEqual('1', next(it))
+        self.assertFalseTwice(it.has_next)
+        self.assertEqualTwice(it.sentinel, it.peek)
+        self.assertFalseTwice(it.has_next)
+
+        a = ['1', '2']
+        it = peek_iter(a)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice('1', it.peek)
+        self.assertEqual('1', next(it))
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice('2', it.peek)
+        self.assertEqual('2', next(it))
+        self.assertFalseTwice(it.has_next)
+        self.assertEqualTwice(it.sentinel, it.peek)
+        self.assertFalseTwice(it.has_next)
+
+    def test_peek_with_one(self):
+        a = []
+        it = peek_iter(a)
+        self.assertFalseTwice(it.has_next)
+        self.assertEqualTwice([it.sentinel], it.peek, 1)
+        self.assertFalseTwice(it.has_next)
+
+        a = ['1']
+        it = peek_iter(a)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice(['1'], it.peek, 1)
+        self.assertEqual('1', next(it))
+        self.assertFalseTwice(it.has_next)
+        self.assertEqualTwice([it.sentinel], it.peek, 1)
+        self.assertFalseTwice(it.has_next)
+
+        a = ['1', '2']
+        it = peek_iter(a)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice(['1'], it.peek, 1)
+        self.assertEqual('1', next(it))
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice(['2'], it.peek, 1)
+        self.assertEqual('2', next(it))
+        self.assertFalseTwice(it.has_next)
+        self.assertEqualTwice([it.sentinel], it.peek, 1)
+        self.assertFalseTwice(it.has_next)
+
+    def test_peek_with_zero(self):
+        a = []
+        it = peek_iter(a)
+        self.assertFalseTwice(it.has_next)
+        self.assertEqualTwice([], it.peek, 0)
+
+        a = ['1']
+        it = peek_iter(a)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice([], it.peek, 0)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice([], it.peek, 0)
+
+        a = ['1', '2']
+        it = peek_iter(a)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice([], it.peek, 0)
+        self.assertTrueTwice(it.has_next)
+        self.assertEqualTwice([], it.peek, 0)
+
+
+class ModifyIterTest(BaseIteratorsTest):
+    def test_init_with_sentinel_args(self):
+        a = iter(['1', '2', '3', 'DONE'])
+        sentinel = 'DONE'
+
+        def get_next():
+            return next(a)
+        it = modify_iter(get_next, sentinel, int)
+        expected = [1, 2, 3]
+        self.assertEqual(expected, [i for i in it])
+
+    def test_init_with_sentinel_kwargs(self):
+        a = iter([1, 2, 3, 4])
+        sentinel = 4
+
+        def get_next():
+            return next(a)
+        it = modify_iter(get_next, sentinel, modifier=str)
+        expected = ['1', '2', '3']
+        self.assertEqual(expected, [i for i in it])
+
+    def test_modifier_default(self):
+        a = ['', '  ', '  a  ', 'b  ', '  c', '  ', '']
+        it = modify_iter(a)
+        expected = ['', '  ', '  a  ', 'b  ', '  c', '  ', '']
+        self.assertEqual(expected, [i for i in it])
+
+    def test_modifier_not_callable(self):
+        self.assertRaises(TypeError, modify_iter, [1], modifier='not_callable')
+
+    def test_modifier_rstrip(self):
+        a = ['', '  ', '  a  ', 'b  ', '  c', '  ', '']
+        it = modify_iter(a, modifier=lambda s: s.rstrip())
+        expected = ['', '', '  a', 'b', '  c', '', '']
+        self.assertEqual(expected, [i for i in it])
+
+    def test_modifier_rstrip_unicode(self):
+        a = [u'', u'  ', u'  a  ', u'b  ', u'  c', u'  ', u'']
+        it = modify_iter(a, modifier=lambda s: s.rstrip())
+        expected = [u'', u'', u'  a', u'b', u'  c', u'', u'']
+        self.assertEqual(expected, [i for i in it])
diff --git a/tests/test_py_domain.py b/tests/test_py_domain.py
index 68634d8..87f6eb9 100644
--- a/tests/test_py_domain.py
+++ b/tests/test_py_domain.py
@@ -9,6 +9,8 @@
     :license: BSD, see LICENSE for details.
 """
 
+from six import text_type
+
 from sphinx import addnodes
 from sphinx.domains.python import py_sig_re, _pseudo_parse_arglist
 
@@ -26,19 +28,19 @@
 def test_function_signatures():
 
     rv = parse('func(a=1) -> int object')
-    assert unicode(rv) == u'a=1'
+    assert text_type(rv) == u'a=1'
 
     rv = parse('func(a=1, [b=None])')
-    assert unicode(rv) == u'a=1, [b=None]'
+    assert text_type(rv) == u'a=1, [b=None]'
 
     rv = parse('func(a=1[, b=None])')
-    assert unicode(rv) == u'a=1, [b=None]'
+    assert text_type(rv) == u'a=1, [b=None]'
 
     rv = parse("compile(source : string, filename, symbol='file')")
-    assert unicode(rv) == u"source : string, filename, symbol='file'"
+    assert text_type(rv) == u"source : string, filename, symbol='file'"
 
     rv = parse('func(a=[], [b=None])')
-    assert unicode(rv) == u'a=[], [b=None]'
+    assert text_type(rv) == u'a=[], [b=None]'
 
     rv = parse('func(a=[][, b=None])')
-    assert unicode(rv) == u'a=[], [b=None]'
+    assert text_type(rv) == u'a=[], [b=None]'
diff --git a/tests/test_quickstart.py b/tests/test_quickstart.py
index 8f63070..74deb46 100644
--- a/tests/test_quickstart.py
+++ b/tests/test_quickstart.py
@@ -11,10 +11,11 @@
 
 import sys
 import time
-from StringIO import StringIO
-import tempfile
 
-from util import raises, with_tempdir, with_app, SkipTest
+from six import PY2, text_type, StringIO
+from six.moves import input
+
+from util import raises, with_tempdir, SkipTest
 
 from sphinx import application
 from sphinx import quickstart as qs
@@ -28,18 +29,18 @@
 def setup_module():
     nocolor()
 
-def mock_raw_input(answers, needanswer=False):
+def mock_input(answers, needanswer=False):
     called = set()
-    def raw_input(prompt):
+    def input_(prompt):
         if prompt in called:
             raise AssertionError('answer for %r missing and no default '
                                  'present' % prompt)
         called.add(prompt)
-        if sys.version_info < (3, 0):
+        if PY2:
             prompt = str(prompt)  # Python2.x raw_input emulation
             # `raw_input` encode `prompt` by default encoding to print.
         else:
-            prompt = unicode(prompt)  # Python3.x input emulation
+            prompt = text_type(prompt)  # Python3.x input emulation
             # `input` decode prompt by default encoding before print.
         for question in answers:
             if prompt.startswith(qs.PROMPT_PREFIX + question):
@@ -47,15 +48,12 @@
         if needanswer:
             raise AssertionError('answer for %r missing' % prompt)
         return ''
-    return raw_input
+    return input_
 
-try:
-    real_raw_input = raw_input
-except NameError:
-    real_raw_input = input
+real_input = input
 
 def teardown_module():
-    qs.term_input = real_raw_input
+    qs.term_input = real_input
     qs.TERM_ENCODING = getattr(sys.stdin, 'encoding', None)
     coloron()
 
@@ -63,12 +61,12 @@
 def test_quickstart_inputstrip():
     d = {}
     answers = {
-        'Q1': 'Y\r',  # input() return with '\r' on Python-3.2.0 for Windows
-        'Q2': ' Yes \r',
+        'Q1': 'Y',
+        'Q2': ' Yes ',
         'Q3': 'N',
         'Q4': 'N ',
     }
-    qs.term_input = mock_raw_input(answers)
+    qs.term_input = mock_input(answers)
     qs.do_prompt(d, 'k1', 'Q1')
     assert d['k1'] == 'Y'
     qs.do_prompt(d, 'k2', 'Q2')
@@ -88,7 +86,7 @@
         'Q5': 'no',
         'Q6': 'foo',
     }
-    qs.term_input = mock_raw_input(answers)
+    qs.term_input = mock_input(answers)
     try:
         qs.do_prompt(d, 'k1', 'Q1')
     except AssertionError:
@@ -113,7 +111,7 @@
     answers = {
         'Q1': u'\u30c9\u30a4\u30c4',
     }
-    qs.term_input = mock_raw_input(answers)
+    qs.term_input = mock_input(answers)
     try:
         qs.do_prompt(d, 'k1', 'Q1', default=u'\u65e5\u672c')
     except UnicodeEncodeError:
@@ -131,7 +129,7 @@
         'Author name': 'Georg Brandl',
         'Project version': '0.1',
     }
-    qs.term_input = mock_raw_input(answers)
+    qs.term_input = mock_input(answers)
     d = {}
     qs.ask_user(d)
     qs.generate(d)
@@ -170,6 +168,7 @@
         'Author name': u'Wolfgang Schäuble & G\'Beckstein'.encode('utf-8'),
         'Project version': '2.0',
         'Project release': '2.0.1',
+        'Project language': 'de',
         'Source file suffix': '.txt',
         'Name of your master document': 'contents',
         'autodoc': 'y',
@@ -185,7 +184,7 @@
         'Create Windows command file': 'no',
         'Do you want to use the epub builder': 'yes',
     }
-    qs.term_input = mock_raw_input(answers, needanswer=True)
+    qs.term_input = mock_input(answers, needanswer=True)
     qs.TERM_ENCODING = 'utf-8'
     d = {}
     qs.ask_user(d)
@@ -231,7 +230,7 @@
         'Author name': 'Georg Brandl',
         'Project version': '0.1',
     }
-    qs.term_input = mock_raw_input(answers)
+    qs.term_input = mock_input(answers)
     d = {}
     qs.ask_user(d)
     qs.generate(d)
@@ -252,7 +251,7 @@
         'Author name': 'Georg Brandl',
         'Project version': '0.1',
     }
-    qs.term_input = mock_raw_input(answers)
+    qs.term_input = mock_input(answers)
     d = {}
     qs.ask_user(d)
     qs.generate(d)
@@ -278,7 +277,7 @@
         'Author name': 'Georg Brandl',
         'Project version': '0.1',
     }
-    qs.term_input = mock_raw_input(answers)
+    qs.term_input = mock_input(answers)
     d = {}
     qs.ask_user(d)
     qs.generate(d)
diff --git a/tests/test_search.py b/tests/test_search.py
index 2efd753..a7e99e0 100644
--- a/tests/test_search.py
+++ b/tests/test_search.py
@@ -13,7 +13,6 @@
 from docutils.parsers import rst
 
 from sphinx.search import IndexBuilder
-from sphinx.util.pycompat import b
 
 
 settings = parser = None
@@ -32,7 +31,7 @@
 '''
 
 def test_wordcollector():
-    doc = utils.new_document(b('test data'), settings)
+    doc = utils.new_document(b'test data', settings)
     doc['file'] = 'dummy'
     parser.parse(FILE_CONTENTS, doc)
 
diff --git a/tests/test_searchadapters.py b/tests/test_searchadapters.py
index 81d7c17..9a41601 100644
--- a/tests/test_searchadapters.py
+++ b/tests/test_searchadapters.py
@@ -10,7 +10,8 @@
 """
 
 import os
-from StringIO import StringIO
+
+from six import StringIO
 
 from sphinx.websupport import WebSupport
 
diff --git a/tests/test_theming.py b/tests/test_theming.py
index 7f91a32..067c431 100644
--- a/tests/test_theming.py
+++ b/tests/test_theming.py
@@ -26,7 +26,7 @@
     assert set(Theme.themes.keys()) == \
            set(['basic', 'default', 'scrolls', 'agogo', 'sphinxdoc', 'haiku',
                 'traditional', 'testtheme', 'ziptheme', 'epub', 'nature',
-                'pyramid'])
+                'pyramid', 'bizstyle'])
     assert Theme.themes['testtheme'][1] is None
     assert isinstance(Theme.themes['ziptheme'][1], zipfile.ZipFile)
 
@@ -55,3 +55,26 @@
     # cleanup temp directories
     theme.cleanup()
     assert not os.path.exists(themedir)
+
+@with_app(buildername='html')
+def test_js_source(app):
+    # Now sphinx provides non-minified JS files for jquery.js and underscore.js
+    # to clarify the source of the minified files. see also #1434.
+    # If you update the version of the JS file, please update the source of the
+    # JS file and version number in this test.
+
+    app.builder.build_all()
+
+    v = '1.8.3'
+    msg = 'jquery.js version does not match to {v}'.format(v=v)
+    jquery_min = (app.outdir / '_static' / 'jquery.js').text()
+    assert 'jQuery v{v}'.format(v=v) in jquery_min, msg
+    jquery_src = (app.outdir / '_static' / 'jquery-{v}.js'.format(v=v)).text()
+    assert 'jQuery JavaScript Library v{v}'.format(v=v) in jquery_src, msg
+
+    v = '1.3.1'
+    msg = 'underscore.js version does not match to {v}'.format(v=v)
+    underscore_min = (app.outdir / '_static' / 'underscore.js').text()
+    assert 'Underscore.js {v}'.format(v=v) in underscore_min, msg
+    underscore_src = (app.outdir / '_static' / 'underscore-{v}.js'.format(v=v)).text()
+    assert 'Underscore.js {v}'.format(v=v) in underscore_src, msg
diff --git a/tests/test_util_i18n.py b/tests/test_util_i18n.py
new file mode 100644
index 0000000..afc9fb3
--- /dev/null
+++ b/tests/test_util_i18n.py
@@ -0,0 +1,163 @@
+# -*- coding: utf-8 -*-

+"""

+    test_util_i18n

+    ~~~~~~~~~~~~~~

+

+    Test i18n util.

+

+    :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.

+    :license: BSD, see LICENSE for details.

+"""

+from __future__ import print_function

+

+import os

+from os import path

+

+from babel.messages.mofile import read_mo

+from sphinx.util import i18n

+

+from util import with_tempdir

+

+

+def test_catalog_info_for_file_and_path():

+    cat = i18n.CatalogInfo('path', 'domain')

+    assert cat.po_file == 'domain.po'

+    assert cat.mo_file == 'domain.mo'

+    assert cat.po_path == path.join('path', 'domain.po')

+    assert cat.mo_path == path.join('path', 'domain.mo')

+

+

+def test_catalog_info_for_sub_domain_file_and_path():

+    cat = i18n.CatalogInfo('path', 'sub/domain')

+    assert cat.po_file == 'sub/domain.po'

+    assert cat.mo_file == 'sub/domain.mo'

+    assert cat.po_path == path.join('path', 'sub/domain.po')

+    assert cat.mo_path == path.join('path', 'sub/domain.mo')

+

+

+@with_tempdir

+def test_catalog_outdated(dir):

+    (dir / 'test.po').write_text('#')

+    cat = i18n.CatalogInfo(dir, 'test')

+    assert cat.is_outdated()  # if mo is not exist

+

+    mo_file = (dir / 'test.mo')

+    mo_file.write_text('#')

+    assert not cat.is_outdated()  # if mo is exist and newer than po

+

+    os.utime(mo_file, (os.stat(mo_file).st_mtime - 10,) * 2) # to be outdate

+    assert cat.is_outdated()  # if mo is exist and older than po

+

+

+@with_tempdir

+def test_catalog_write_mo(dir):

+    (dir / 'test.po').write_text('#')

+    cat = i18n.CatalogInfo(dir, 'test')

+    cat.write_mo('en')

+    assert path.exists(cat.mo_path)

+    assert read_mo(open(cat.mo_path, 'rb')) is not None

+

+

+@with_tempdir

+def test_get_catalogs_for_xx(dir):

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES').makedirs()

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test1.po').write_text('#')

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test2.po').write_text('#')

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test3.pot').write_text('#')

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub').makedirs()

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test4.po').write_text('#')

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test5.po').write_text('#')

+    (dir / 'loc1' / 'en' / 'LC_MESSAGES').makedirs()

+    (dir / 'loc1' / 'en' / 'LC_MESSAGES' / 'test6.po').write_text('#')

+    (dir / 'loc1' / 'xx' / 'LC_ALL').makedirs()

+    (dir / 'loc1' / 'xx' / 'LC_ALL' / 'test7.po').write_text('#')

+

+    catalogs = i18n.get_catalogs([dir / 'loc1'], 'xx', force_all=False)

+    domains = set(c.domain for c in catalogs)

+    assert domains == set([

+        'test1',

+        'test2',

+        path.normpath('sub/test4'),

+        path.normpath('sub/test5'),

+    ])

+

+

+@with_tempdir

+def test_get_catalogs_for_en(dir):

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES').makedirs()

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'xx_dom.po').write_text('#')

+    (dir / 'loc1' / 'en' / 'LC_MESSAGES').makedirs()

+    (dir / 'loc1' / 'en' / 'LC_MESSAGES' / 'en_dom.po').write_text('#')

+

+    catalogs = i18n.get_catalogs([dir / 'loc1'], 'en', force_all=False)

+    domains = set(c.domain for c in catalogs)

+    assert domains == set(['en_dom'])

+

+

+@with_tempdir

+def test_get_catalogs_with_non_existent_locale(dir):

+    catalogs = i18n.get_catalogs([dir / 'loc1'], 'xx')

+    assert not catalogs

+

+    catalogs = i18n.get_catalogs([dir / 'loc1'], None)

+    assert not catalogs

+

+

+def test_get_catalogs_with_non_existent_locale_dirs():

+    catalogs = i18n.get_catalogs(['dummy'], 'xx')

+    assert not catalogs

+

+

+@with_tempdir

+def test_get_catalogs_for_xx_without_outdated(dir):

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES').makedirs()

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test1.po').write_text('#')

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test1.mo').write_text('#')

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test2.po').write_text('#')

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test2.mo').write_text('#')

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test3.pot').write_text('#')

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test3.mo').write_text('#')

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub').makedirs()

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test4.po').write_text('#')

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test4.mo').write_text('#')

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test5.po').write_text('#')

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test5.mo').write_text('#')

+

+    catalogs = i18n.get_catalogs([dir / 'loc1'], 'xx', force_all=False)

+    assert not catalogs

+

+    catalogs = i18n.get_catalogs([dir / 'loc1'], 'xx', force_all=True)

+    domains = set(c.domain for c in catalogs)

+    assert domains == set([

+        'test1',

+        'test2',

+        path.normpath('sub/test4'),

+        path.normpath('sub/test5'),

+    ])

+

+

+@with_tempdir

+def test_get_catalogs_from_multiple_locale_dirs(dir):

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES').makedirs()

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test1.po').write_text('#')

+    (dir / 'loc2' / 'xx' / 'LC_MESSAGES').makedirs()

+    (dir / 'loc2' / 'xx' / 'LC_MESSAGES' / 'test1.po').write_text('#')

+    (dir / 'loc2' / 'xx' / 'LC_MESSAGES' / 'test2.po').write_text('#')

+

+    catalogs = i18n.get_catalogs([dir / 'loc1', dir / 'loc2'], 'xx')

+    domains = sorted(c.domain for c in catalogs)

+    assert domains == ['test1', 'test1', 'test2']

+

+

+@with_tempdir

+def test_get_catalogs_with_compact(dir):

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES').makedirs()

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test1.po').write_text('#')

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test2.po').write_text('#')

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub').makedirs()

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test3.po').write_text('#')

+    (dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test4.po').write_text('#')

+

+    catalogs = i18n.get_catalogs([dir / 'loc1'], 'xx', gettext_compact=True)

+    domains = set(c.domain for c in catalogs)

+    assert domains == set(['test1', 'test2', 'sub'])

diff --git a/tests/test_versioning.py b/tests/test_versioning.py
index bf2f65e..d9cbf8e 100644
--- a/tests/test_versioning.py
+++ b/tests/test_versioning.py
@@ -15,7 +15,6 @@
 
 from sphinx import addnodes
 from sphinx.versioning import add_uids, merge_doctrees, get_ratio
-from sphinx.util.pycompat import all
 
 from util import test_root, TestApp
 
diff --git a/tests/test_websupport.py b/tests/test_websupport.py
index 9376a2a..d355422 100644
--- a/tests/test_websupport.py
+++ b/tests/test_websupport.py
@@ -10,13 +10,9 @@
 """
 
 import os
-from StringIO import StringIO
+from functools import wraps
 
-try:
-    from functools import wraps
-except ImportError:
-    # functools is new in 2.5
-    wraps = lambda f: (lambda w: w)
+from six import StringIO
 
 from sphinx.websupport import WebSupport
 from sphinx.websupport.errors import DocumentNotFoundError, \
diff --git a/tests/util.py b/tests/util.py
index 61c9bd0..bbfb2d4 100644
--- a/tests/util.py
+++ b/tests/util.py
@@ -7,18 +7,14 @@
     :license: BSD, see LICENSE for details.
 """
 
+import os
 import sys
-import StringIO
 import tempfile
 import shutil
 import re
-from codecs import open
+from functools import wraps
 
-try:
-    from functools import wraps
-except ImportError:
-    # functools is new in 2.4
-    wraps = lambda f: (lambda w: w)
+from six import StringIO
 
 from sphinx import application
 from sphinx.theming import Theme
@@ -28,13 +24,20 @@
 
 from nose import tools, SkipTest
 
+try:
+    # Python >=3.3
+    from unittest import mock
+except ImportError:
+    import mock
+
 
 __all__ = [
     'test_root', 'test_roots', 'raises', 'raises_msg',
     'skip_if', 'skip_unless', 'skip_unless_importable', 'Struct',
     'ListOutput', 'TestApp', 'with_app', 'gen_with_app',
-    'path', 'with_tempdir', 'write_file',
+    'path', 'with_tempdir',
     'sprint', 'remove_unicode_literals',
+    'mock',
 ]
 
 
@@ -67,7 +70,7 @@
     """
     try:
         func(*args, **kwds)
-    except exc, err:
+    except exc as err:
         assert msg in str(err), "\"%s\" not in \"%s\"" % (msg, err)
     else:
         raise AssertionError('%s did not raise %s' %
@@ -128,7 +131,9 @@
                  buildername='html', confoverrides=None,
                  status=None, warning=None, freshenv=None,
                  warningiserror=None, tags=None,
-                 confname='conf.py', cleanenv=False):
+                 confname='conf.py', cleanenv=False,
+                 _copy_to_temp=False,
+                 ):
 
         application.CONFIG_FILENAME = confname
 
@@ -136,12 +141,6 @@
 
         if srcdir is None:
             srcdir = test_root
-        if srcdir == '(temp)':
-            tempdir = path(tempfile.mkdtemp())
-            self.cleanup_trees.append(tempdir)
-            temproot = tempdir / 'root'
-            test_root.copytree(temproot)
-            srcdir = temproot
         elif srcdir == '(empty)':
             tempdir = path(tempfile.mkdtemp())
             self.cleanup_trees.append(tempdir)
@@ -151,6 +150,14 @@
             srcdir = temproot
         else:
             srcdir = path(srcdir)
+
+        if _copy_to_temp:
+            tempdir = path(tempfile.mkdtemp())
+            self.cleanup_trees.append(tempdir)
+            temproot = tempdir / srcdir.basename()
+            srcdir.copytree(temproot)
+            srcdir = temproot
+
         self.builddir = srcdir.joinpath('_build')
         if confdir is None:
             confdir = srcdir
@@ -168,7 +175,7 @@
         if confoverrides is None:
             confoverrides = {}
         if status is None:
-            status = StringIO.StringIO()
+            status = StringIO()
         if warning is None:
             warning = ListOutput('stderr')
         if freshenv is None:
@@ -232,21 +239,17 @@
     return new_func
 
 
-def write_file(name, contents, encoding=None):
-    if encoding is None:
-        mode = 'wb'
-        if isinstance(contents, unicode):
-            contents = contents.encode('ascii')
-    else:
-        mode = 'w'
-    f = open(str(name), mode, encoding=encoding)
-    f.write(contents)
-    f.close()
-
-
 def sprint(*args):
     sys.stderr.write(' '.join(map(str, args)) + '\n')
 
 _unicode_literals_re = re.compile(r'u(".*?")|u(\'.*?\')')
 def remove_unicode_literals(s):
     return _unicode_literals_re.sub(lambda x: x.group(1) or x.group(2), s)
+
+
+def find_files(root, suffix=None):
+    for dirpath, dirs, files in os.walk(root, followlinks=True):
+        dirpath = path(dirpath)
+        for f in [f for f in files if not suffix or f.endswith(suffix)]:
+            fpath = dirpath / f
+            yield os.path.relpath(fpath, root)
diff --git a/tox.ini b/tox.ini
index f1675e9..2c3ddfd 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist=py25,py26,py27,py31,py32,py33,pypy,du11,du10,du09,du08,du07
+envlist=py26,py27,py33,py34,pypy,du12,du11,du10
 
 [testenv]
 deps=
@@ -12,45 +12,36 @@
     {envpython} tests/run.py {posargs}
     sphinx-build -W -b html -d {envtmpdir}/doctrees doc {envtmpdir}/html
 
-[testenv:py25]
+[testenv:py26]
 deps=
-    simplejson==2.5.0
+    mock
     {[testenv]deps}
-setenv=
-    PIP_INSECURE = 1
-    {[testenv]setenv}
 
-[testenv:py33]
+[testenv:py27]
 deps=
-    docutils>=0.10.0
+    mock
     {[testenv]deps}
 
 [testenv:pypy]
 deps=
+    mock
     simplejson
     {[testenv]deps}
 
-[testenv:du07]
-deps=
-    docutils==0.7
-    {[testenv]deps}
-
-[testenv:du08]
-deps=
-    docutils==0.8.1
-    {[testenv]deps}
-
-[testenv:du09]
-deps=
-    docutils==0.9.1
-    {[testenv]deps}
-
 [testenv:du10]
 deps=
+    mock
     docutils==0.10
     {[testenv]deps}
 
 [testenv:du11]
 deps=
+    mock
     docutils==0.11
     {[testenv]deps}
+
+[testenv:du12]
+deps=
+    mock
+    docutils==0.12
+    {[testenv]deps}
diff --git a/utils/check_sources.py b/utils/check_sources.py
index 7bbd0a7..1b78ab6 100755
--- a/utils/check_sources.py
+++ b/utils/check_sources.py
@@ -10,18 +10,13 @@
     :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
     :license: BSD, see LICENSE for details.
 """
+from __future__ import print_function
 
 import sys, os, re
 import cStringIO
 from optparse import OptionParser
 from os.path import join, splitext, abspath
 
-if sys.version_info >= (3, 0):
-    def b(s):
-        return s.encode('utf-8')
-else:
-    b = str
-
 
 checkers = {}
 
@@ -36,25 +31,25 @@
 
 
 name_mail_re = r'[\w ]+(<.*?>)?'
-copyright_re = re.compile(b(r'^    :copyright: Copyright 200\d(-20\d\d)? '
-                            r'by %s(, %s)*[,.]$' %
-                            (name_mail_re, name_mail_re)))
-license_re = re.compile(b(r"    :license: (.*?).\n"))
-copyright_2_re = re.compile(b(r'^                %s(, %s)*[,.]$' %
-                             (name_mail_re, name_mail_re)))
-coding_re    = re.compile(b(r'coding[:=]\s*([-\w.]+)'))
-not_ix_re    = re.compile(b(r'\bnot\s+\S+?\s+i[sn]\s\S+'))
-is_const_re  = re.compile(b(r'if.*?==\s+(None|False|True)\b'))
+copyright_re = re.compile(br'^    :copyright: Copyright 200\d(-20\d\d)? '
+                          br'by %s(, %s)*[,.]$' %
+                          (name_mail_re, name_mail_re))
+license_re = re.compile(br"    :license: (.*?).\n")
+copyright_2_re = re.compile(br'^                %s(, %s)*[,.]$' %
+                            (name_mail_re, name_mail_re))
+coding_re    = re.compile(br'coding[:=]\s*([-\w.]+)')
+not_ix_re    = re.compile(br'\bnot\s+\S+?\s+i[sn]\s\S+')
+is_const_re  = re.compile(br'if.*?==\s+(None|False|True)\b')
 
-misspellings = [b("developement"), b("adress"), # ALLOW-MISSPELLING
-                b("verificate"), b("informations")] # ALLOW-MISSPELLING
+misspellings = [b"developement", b"adress", # ALLOW-MISSPELLING
+                b"verificate", b"informations"] # ALLOW-MISSPELLING
 
 if sys.version_info < (3, 0):
     @checker('.py')
     def check_syntax(fn, lines):
         try:
-            compile(b('').join(lines), fn, "exec")
-        except SyntaxError, err:
+            compile(b''.join(lines), fn, "exec")
+        except SyntaxError as err:
             yield 0, "not compilable: %s" % err
 
 
@@ -68,7 +63,7 @@
             co = coding_re.search(line)
             if co:
                 encoding = co.group(1).decode('ascii')
-        if line.strip().startswith(b('#')):
+        if line.strip().startswith(b'#'):
             continue
         #m = not_ix_re.search(line)
         #if m:
@@ -77,9 +72,9 @@
             yield lno+1, 'using == None/True/False'
         try:
             line.decode(encoding)
-        except UnicodeDecodeError, err:
+        except UnicodeDecodeError as err:
             yield lno+1, "not decodable: %s\n   Line: %r" % (err, line)
-        except LookupError, err:
+        except LookupError as err:
             yield 0, "unknown encoding: %s" % encoding
             encoding = 'latin1'
 
@@ -88,7 +83,7 @@
 def check_fileheader(fn, lines):
     # line number correction
     c = 1
-    if lines[0:1] == [b('#!/usr/bin/env python\n')]:
+    if lines[0:1] == [b'#!/usr/bin/env python\n']:
         lines = lines[1:]
         c = 2
 
@@ -97,38 +92,38 @@
     for lno, l in enumerate(lines):
         llist.append(l)
         if lno == 0:
-            if l == b('# -*- coding: rot13 -*-\n'):
+            if l == b'# -*- coding: rot13 -*-\n':
                 # special-case pony package
                 return
-            elif l != b('# -*- coding: utf-8 -*-\n'):
+            elif l != b'# -*- coding: utf-8 -*-\n':
                 yield 1, "missing coding declaration"
         elif lno == 1:
-            if l != b('"""\n') and l != b('r"""\n'):
+            if l != b'"""\n' and l != b'r"""\n':
                 yield 2, 'missing docstring begin (""")'
             else:
                 docopen = True
         elif docopen:
-            if l == b('"""\n'):
+            if l == b'"""\n':
                 # end of docstring
                 if lno <= 4:
                     yield lno+c, "missing module name in docstring"
                 break
 
-            if l != b("\n") and l[:4] != b('    ') and docopen:
+            if l != b"\n" and l[:4] != b'    ' and docopen:
                 yield lno+c, "missing correct docstring indentation"
 
             if lno == 2:
                 # if not in package, don't check the module name
                 modname = fn[:-3].replace('/', '.').replace('.__init__', '')
                 while modname:
-                    if l.lower()[4:-1] == b(modname):
+                    if l.lower()[4:-1] == bytes(modname):
                         break
                     modname = '.'.join(modname.split('.')[1:])
                 else:
                     yield 3, "wrong module name in docstring heading"
                 modnamelen = len(l.strip())
             elif lno == 3:
-                if l.strip() != modnamelen * b("~"):
+                if l.strip() != modnamelen * b"~":
                     yield 4, "wrong module name underline, should be ~~~...~"
 
     else:
@@ -151,16 +146,16 @@
 @checker('.py', '.html', '.rst')
 def check_whitespace_and_spelling(fn, lines):
     for lno, line in enumerate(lines):
-        if b("\t") in line:
+        if b"\t" in line:
             yield lno+1, "OMG TABS!!!1 "
-        if line[:-1].rstrip(b(' \t')) != line[:-1]:
+        if line[:-1].rstrip(b' \t') != line[:-1]:
             yield lno+1, "trailing whitespace"
         for word in misspellings:
-            if word in line and b('ALLOW-MISSPELLING') not in line:
+            if word in line and b'ALLOW-MISSPELLING' not in line:
                 yield lno+1, '"%s" used' % word
 
 
-bad_tags = map(b, ['<u>', '<s>', '<strike>', '<center>', '<font'])
+bad_tags = [b'<u>', b'<s>', b'<strike>', b'<center>', b'<font']
 
 @checker('.html')
 def check_xhtml(fn, lines):
@@ -183,7 +178,7 @@
     elif len(args) == 1:
         path = args[0]
     else:
-        print args
+        print(args)
         parser.error('No more then one path supported')
 
     verbose = options.verbose
@@ -214,7 +209,7 @@
                 continue
 
             if verbose:
-                print "Checking %s..." % fn
+                print("Checking %s..." % fn)
 
             try:
                 f = open(fn, 'rb')
@@ -222,8 +217,8 @@
                     lines = list(f)
                 finally:
                     f.close()
-            except (IOError, OSError), err:
-                print "%s: cannot open: %s" % (fn, err)
+            except (IOError, OSError) as err:
+                print("%s: cannot open: %s" % (fn, err))
                 num += 1
                 continue
 
@@ -231,15 +226,15 @@
                 if not in_check_pkg and checker.only_pkg:
                     continue
                 for lno, msg in checker(fn, lines):
-                    print >>out, "%s:%d: %s" % (fn, lno, msg)
+                    print("%s:%d: %s" % (fn, lno, msg), file=out)
                     num += 1
     if verbose:
-        print
+        print()
     if num == 0:
-        print "No errors found."
+        print("No errors found.")
     else:
-        print out.getvalue().rstrip('\n')
-        print "%d error%s found." % (num, num > 1 and "s" or "")
+        print(out.getvalue().rstrip('\n'))
+        print("%d error%s found." % (num, num > 1 and "s" or ""))
     return int(num > 0)
 
 
diff --git a/utils/reindent.py b/utils/reindent.py
index 59828fd..ef53fe8 100755
--- a/utils/reindent.py
+++ b/utils/reindent.py
@@ -38,6 +38,7 @@
 user/group and permissions could leave the backup file more readable that
 you'd prefer. You can always use the --nobackup option to prevent this.
 """
+from __future__ import print_function
 
 __version__ = "1"
 
@@ -59,8 +60,8 @@
 
 def usage(msg=None):
     if msg is not None:
-        print >> sys.stderr, msg
-    print >> sys.stderr, __doc__
+        print(msg, file=sys.stderr)
+    print(__doc__, file=sys.stderr)
 
 def errprint(*args):
     sep = ""
@@ -75,7 +76,7 @@
     try:
         opts, args = getopt.getopt(sys.argv[1:], "drnvh",
                         ["dryrun", "recurse", "nobackup", "verbose", "help"])
-    except getopt.error, msg:
+    except getopt.error as msg:
         usage(msg)
         return
     for o, a in opts:
@@ -101,7 +102,7 @@
 def check(file):
     if os.path.isdir(file) and not os.path.islink(file):
         if verbose:
-            print "listing directory", file
+            print("listing directory", file)
         names = os.listdir(file)
         for name in names:
             fullname = os.path.join(file, name)
@@ -113,10 +114,10 @@
         return
 
     if verbose:
-        print "checking", file, "...",
+        print("checking", file, "...", end=' ')
     try:
         f = open(file)
-    except IOError, msg:
+    except IOError as msg:
         errprint("%s: I/O Error: %s" % (file, str(msg)))
         return
 
@@ -124,24 +125,24 @@
     f.close()
     if r.run():
         if verbose:
-            print "changed."
+            print("changed.")
             if dryrun:
-                print "But this is a dry run, so leaving it alone."
+                print("But this is a dry run, so leaving it alone.")
         if not dryrun:
             bak = file + ".bak"
             if makebackup:
                 shutil.copyfile(file, bak)
                 if verbose:
-                    print "backed up", file, "to", bak
+                    print("backed up", file, "to", bak)
             f = open(file, "w")
             r.write(f)
             f.close()
             if verbose:
-                print "wrote new", file
+                print("wrote new", file)
         return True
     else:
         if verbose:
-            print "unchanged."
+            print("unchanged.")
         return False
 
 def _rstrip(line, JUNK='\n \t'):
@@ -262,7 +263,7 @@
         return line
 
     # Line-eater for tokenize.
-    def tokeneater(self, type, token, (sline, scol), end, line,
+    def tokeneater(self, type, token, position, end, line,
                    INDENT=tokenize.INDENT,
                    DEDENT=tokenize.DEDENT,
                    NEWLINE=tokenize.NEWLINE,
@@ -285,7 +286,7 @@
 
         elif type == COMMENT:
             if self.find_stmt:
-                self.stats.append((sline, -1))
+                self.stats.append((position[0], -1))
                 # but we're still looking for a new stmt, so leave
                 # find_stmt alone
 
@@ -298,7 +299,7 @@
             # ENDMARKER.
             self.find_stmt = 0
             if line:   # not endmarker
-                self.stats.append((sline, self.level))
+                self.stats.append((position[0], self.level))
 
 # Count number of leading blanks.
 def getlspace(line):