--- python-django-1.1.1.orig/debian/python-django.manpages
+++ python-django-1.1.1/debian/python-django.manpages
@@ -0,0 +1 @@
+docs/man/django-admin.1
--- python-django-1.1.1.orig/debian/compat
+++ python-django-1.1.1/debian/compat
@@ -0,0 +1 @@
+7
--- python-django-1.1.1.orig/debian/python-django-doc.doc-base
+++ python-django-1.1.1/debian/python-django-doc.doc-base
@@ -0,0 +1,20 @@
+Document: python-django-doc
+Title: Python Django Documentation
+Author: Django Software Foundation
+Abstract: This documentation gives an introduction 
+ to Django and its contributed packages like its automatic
+ admin and the user authentication applications.
+Section: Programming/Python
+
+Format: HTML
+Index: /usr/share/doc/python-django-doc/html/index.html
+Files: /usr/share/doc/python-django-doc/html/*.html
+ /usr/share/doc/python-django-doc/html/faq/*.html
+ /usr/share/doc/python-django-doc/html/howto/*.html
+ /usr/share/doc/python-django-doc/html/internals/*.html
+ /usr/share/doc/python-django-doc/html/intro/*.html
+ /usr/share/doc/python-django-doc/html/misc/*.html
+ /usr/share/doc/python-django-doc/html/obsolete/*.html
+ /usr/share/doc/python-django-doc/html/ref/*.html
+ /usr/share/doc/python-django-doc/html/releases/*.html
+ /usr/share/doc/python-django-doc/html/topics/*.html
--- python-django-1.1.1.orig/debian/python-django-doc.examples
+++ python-django-1.1.1/debian/python-django-doc.examples
@@ -0,0 +1 @@
+examples/*
--- python-django-1.1.1.orig/debian/python-django.examples
+++ python-django-1.1.1/debian/python-django.examples
@@ -0,0 +1 @@
+debian/contrib/*
--- python-django-1.1.1.orig/debian/pycompat
+++ python-django-1.1.1/debian/pycompat
@@ -0,0 +1 @@
+2
--- python-django-1.1.1.orig/debian/watch
+++ python-django-1.1.1/debian/watch
@@ -0,0 +1,3 @@
+version=3
+opts=filenamemangle=s/.*\/download\/(.*)\/tarball\//Django-$1.tar.gz/,uversionmangle=s/-(alpha|beta)-/~$1/ \
+    http://www.djangoproject.com/download/ (.+)/tarball/
--- python-django-1.1.1.orig/debian/control
+++ python-django-1.1.1/debian/control
@@ -0,0 +1,57 @@
+Source: python-django
+Section: python
+Priority: optional
+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
+XSBC-Original-Maintainer: Chris Lamb <lamby@debian.org>
+Uploaders: Debian Python Modules Team <python-modules-team@lists.alioth.debian.org>, Raphaël Hertzog <hertzog@debian.org>
+Standards-Version: 3.8.3
+Build-Depends: debhelper (>= 7.0.50), python-support, quilt (>= 0.46-7~), python (>= 2.5) | python-sqlite
+Build-Depends-Indep: python-sphinx, libjs-jquery
+Homepage: http://www.djangoproject.com/
+Vcs-Svn: svn://svn.debian.org/python-modules/packages/python-django/trunk/
+Vcs-Browser: http://svn.debian.org/viewsvn/python-modules/packages/python-django/trunk/
+
+Package: python-django
+Architecture: all
+Depends: ${misc:Depends}, ${python:Depends}
+Suggests: python-psycopg2, python-psycopg, python-mysqldb, python-flup, python-sqlite
+Description: High-level Python web development framework
+ Django is a high-level web application framework that loosely follows the
+ model-view-controller design pattern.
+ .
+ Python's equivalent to Ruby on Rails, Django lets you build complex
+ data-driven websites quickly and easily - Django focuses on automating as much
+ as possible and adhering to the "Don't Repeat Yourself" (DRY) principle.
+ .
+ Django additionally emphasizes reusability and "pluggability" of components;
+ many generic third-party "applications" are available to enhance projects or
+ to simply to reduce development time even further.
+ .
+ Notable features include:
+  * An object-relational mapper (ORM)
+  * Automatic admin interface
+  * Elegant URL dispatcher
+  * Form serialization and validation system
+  * Templating system
+  * Lightweight, standalone web server for development and testing
+  * Internationalization support
+  * Testing framework and client
+
+Package: python-django-doc
+Section: doc
+Architecture: all
+Depends: ${misc:Depends}
+Recommends: libjs-jquery
+Description: High-level Python web development framework (documentation)
+ Django is a high-level web application framework that loosely follows the
+ model-view-controller design pattern.
+ .
+ Python's equivalent to Ruby on Rails, Django lets you build complex
+ data-driven websites quickly and easily - Django focuses on automating as much
+ as possible and adhering to the "Don't Repeat Yourself" (DRY) principle.
+ .
+ Django additionally emphasizes reusability and "pluggability" of components;
+ many generic third-party "applications" are available to enhance projects or
+ to simply to reduce development time even further.
+ .
+ This package contains the HTML documentation and example projects.
--- python-django-1.1.1.orig/debian/python-django-doc.docs
+++ python-django-1.1.1/debian/python-django-doc.docs
@@ -0,0 +1 @@
+docs.debian/_build/html
--- python-django-1.1.1.orig/debian/changelog
+++ python-django-1.1.1/debian/changelog
@@ -0,0 +1,550 @@
+python-django (1.1.1-2ubuntu1.7) lucid-security; urgency=low
+
+  * Add additional tests for CVE-2012-4520
+    - debian/patches/CVE-2012-4520-additional-tests.diff: add various poisoned
+      host header test material
+  * Don't fail self-tests if MANAGERS or ADMINS is defined in settings.py
+    - debian/patches/lp1080204.diff: Isolate poisoned_http_host tests from 500
+    - https://code.djangoproject.com/ticket/19172
+    - LP: #1080204
+
+ -- Jamie Strandboge <jamie@ubuntu.com>  Mon, 19 Nov 2012 15:20:21 -0600
+
+python-django (1.1.1-2ubuntu1.6) lucid-security; urgency=low
+
+  * SECURITY UPDATE: fix Host header poisoning
+    - debian/patches/CVE-2012-4520.diff: adjust HttpRequest.get_host() to
+      raise django.core.exceptions.SuspiciousOperation if Host headers contain
+      potentially dangerous content.
+    - CVE-2012-4520
+    - LP: #1068486
+
+ -- Jamie Strandboge <jamie@ubuntu.com>  Fri, 09 Nov 2012 16:16:26 -0600
+
+python-django (1.1.1-2ubuntu1.5) lucid-security; urgency=low
+
+  * SECURITY UPDATE: Cross-site scripting in authentication views
+    (LP: #1031733)
+    - debian/patches/16_fix_cross_site_scripting_in_authentication.diff:
+      fix unsafe redirects indjango/http/__init__.py. Patch backported from
+      Debian Squeeze and fixed for python 2.4 compatibility.
+    - CVE-2012-3442
+  * SECURITY UPDATE: Denial-of-service in image validation (LP: #1031733)
+    - debian/patches/17_fix_dos_in_image_validation.diff: call verify()
+      immediately after the constructor in django/forms/fields.py.
+    - CVE-2012-3443
+  * SECURITY UPDATE: Denial-of-service via get_image_dimensions()
+    (LP: #1031733)
+    - debian/patches/18_fix_dos_via_get_image_dimensions.diff: don't limit
+      chunk size in django/core/files/images.py.
+    - CVE-2012-3444
+
+ -- Marc Deslauriers <marc.deslauriers@ubuntu.com>  Thu, 06 Sep 2012 09:56:37 -0400
+
+python-django (1.1.1-2ubuntu1.4) lucid-security; urgency=low
+
+  * SECURITY UPDATE: session manipulation when using django.contrib.sessions
+    with memory-based sessions and caching
+    - debian/patches/CVE-2011-4136.patch: use namespace of cache to store keys
+      for session instead of root namespace
+    - CVE-2011-4136
+  * SECURITY UPDATE: potential denial of service and information disclosure in
+    URLField
+    - debian/patches/CVE-2011-4137+4138.patch: set verify_exists to False by
+      default and use a timeout if available.
+    - CVE-2011-4137, CVE-2011-4138
+  * SECURITY UPDATE: potential cache-poisoning via crafted Host header
+    - debian/patches/CVE-2011-4139.patch: ignore X-Forwarded-Host header by
+      default when constructing full URLs
+    - CVE-2011-4139
+  * More information on these issues can be found at:
+    https://www.djangoproject.com/weblog/2011/sep/09/security-releases-issued/
+
+ -- Jamie Strandboge <jamie@ubuntu.com>  Wed, 07 Dec 2011 16:02:57 -0600
+
+python-django (1.1.1-2ubuntu1.3) lucid-security; urgency=low
+
+  * SECURITY UPDATE: flaw in CSRF handling (LP: #719031)
+    - debian/patches/10_CVE-2011-0696.diff: apply full CSRF validation to all
+      requests, regardless of apparent AJAX origin. This is technically
+      backwards-incompatible, but the security risks have been judged to
+      outweigh the compatibility concerns in this case. See the Django project
+      notes for more information:
+      http://www.djangoproject.com/weblog/2011/feb/08/security/
+    - CVE-2011-0696
+  * SECURITY UPDATE: potential XSS in file field rendering
+    - debian/patches/11_CVE-2011-0697.diff: properly escape URL in
+      django/contrib/admin/widgets.py
+    - CVE-2011-0697
+
+ -- Jamie Strandboge <jamie@ubuntu.com>  Tue, 15 Feb 2011 17:11:08 -0600
+
+python-django (1.1.1-2ubuntu1.2) lucid-security; urgency=low
+
+  * SECURITY UPDATE: information leak in admin interface
+    - debian/patches/08_security_admin_infoleak.diff: validate querystring
+      lookup arguments either specify only fields on the model being viewed,
+      or cross relations which have been explicitly whitelisted.
+    - CVE-2010-4534
+  * SECURITY UPDATE:
+    - debian/patches/09_security_pasword_reset_dos.diff: adjust
+      base36_to_int() function in django.utils.http will now validate the
+      length of its input; on input longer than 13 digits (sufficient to
+      base36-encode any 64-bit integer), it will now raise ValueError.
+      Additionally, the default URL patterns for django.contrib.auth will now
+      enforce a maximum length on the relevant parameters.
+    - CVE-2010-4535
+
+ -- Jamie Strandboge <jamie@ubuntu.com>  Mon, 03 Jan 2011 11:31:57 -0600
+
+python-django (1.1.1-2ubuntu1) lucid; urgency=low
+
+  * Fix django test client cookie handling (LP: #513719)
+
+ -- Elliot Murphy <elliot@ubuntu.com>  Fri, 29 Jan 2010 13:01:27 -0500
+
+python-django (1.1.1-2) unstable; urgency=low
+
+  * Remove embedded "decimal" code copy and use system version instead. The
+    "doctest" code copy cannot be removed as parts of Django depend on modified
+    behaviour. (Closes: #555419)
+  * Fix FTBFS in November by applying patch from upstream bug #12125.
+    (Closes: #555931)
+  * Fix FTBFS under Python 2.6.3 by applying patch from upstream bug #11993.
+    (Closes: #555969)
+
+ -- Chris Lamb <lamby@debian.org>  Tue, 01 Dec 2009 23:46:22 +0000
+
+python-django (1.1.1-1) unstable; urgency=high
+
+  * New upstream security release - fixes pathological regular expression
+    backtracking performance in URL and email fields which can be used as part
+    of a denial of service attack.
+  * Set Maintainer: to myself with thanks to Brett Parker.
+  * Bump versioned build dependency on quilt to help backporters.
+    (Closes: #547955)
+
+ -- Chris Lamb <lamby@debian.org>  Sat, 10 Oct 2009 10:17:52 +0100
+
+python-django (1.1-4) unstable; urgency=low
+
+  * Sourceful upload to drop dependency on Python 2.4.
+
+ -- Chris Lamb <lamby@debian.org>  Mon, 24 Aug 2009 08:16:11 +0100
+
+python-django (1.1-3) unstable; urgency=low
+
+  * Disable regression tests that require an internet connection. Patch by
+    Krzysztof Klimonda <kklimonda@syntaxhighlighted.com>. (Closes: #542996)
+  * Bump Standards-Version to 3.8.3.
+
+ -- Chris Lamb <lamby@debian.org>  Sun, 23 Aug 2009 18:13:18 +0100
+
+python-django (1.1-2) unstable; urgency=low
+
+  * Run testsuite on build.
+  * Use "--with quilt" over specifying $(QUILT_STAMPFN)/unpatch dependencies.
+  * Override clean target correctly.
+
+ -- Chris Lamb <lamby@debian.org>  Fri, 14 Aug 2009 08:06:29 +0100
+
+python-django (1.1-1) unstable; urgency=low
+
+  * New upstream release.
+  * Merge from experimental:
+    - Ship FastCGI initscript and /etc/default file in python-django's examples
+      directory (Closes: #538863)
+    - Drop "05_10539-sphinx06-compatibility.diff"; it has been applied
+      upstream.
+    - Bump Standards-Version to 3.8.2.
+
+ -- Chris Lamb <lamby@debian.org>  Wed, 29 Jul 2009 11:26:28 +0200
+
+python-django (1.0.2-7) unstable; urgency=low
+
+  * Fix compatibility with Python 2.6 and Python transitions in general.
+    Thanks to Krzysztof Klimonda <kklimonda@syntaxhighlighted.com>.
+
+ -- Chris Lamb <lamby@debian.org>  Sat, 16 May 2009 00:09:47 +0100
+
+python-django (1.0.2-6) unstable; urgency=low
+
+  * Backport patch from <http://code.djangoproject.com/ticket/10539> to fix
+    FTBFS when using python-sphinx >= 0.6. (Closes: #527492)
+
+ -- Chris Lamb <lamby@debian.org>  Sun, 10 May 2009 22:11:09 +0100
+
+python-django (1.0.2-5) unstable; urgency=low
+
+  * Fix issue where newly created projects do not have their manage.py file
+    executable.
+
+ -- Chris Lamb <lamby@debian.org>  Thu, 26 Mar 2009 23:42:14 +0000
+
+python-django (1.0.2-4) unstable; urgency=low
+
+  * Programatically replace most references to "django-admin.py" with
+    "django-admin" in the generated documentation. (Closes: #519937)
+  * Bump Standards-Version to 3.8.1; no changes.
+
+ -- Chris Lamb <lamby@debian.org>  Tue, 24 Mar 2009 00:50:26 +0000
+
+python-django (1.0.2-3) unstable; urgency=low
+
+  * Split documentation into a separate python-django-doc package due to size
+    (approximately 6Mb).
+
+ -- Chris Lamb <lamby@debian.org>  Tue, 10 Mar 2009 21:13:57 +0000
+
+python-django (1.0.2-2) unstable; urgency=low
+
+  * Don't rely on the internal layout of python-support. (Closes: #517052)
+  * Move to debhelper-based packaging for operational clarity:
+    - Remove bashisms from binary-post-install.
+    - Use quilt instead of simple-patchsys.mk and adjust existing patches so
+      that we can apply with -p1 for the "quilt" source package type.
+  * Adjust Build-Depends:
+    - Bump debhelper requirement 7.0.50 for override_* feature.
+    - Drop cdbs, python-dev and python-setuptools requirement.
+    - Just Build-Depend on `python', not `python-dev'.
+    - Drop versions on Build-Depends where they are satisfied in current
+      oldstable (ie. etch).
+  * debian/control:
+    - Add python-sqlite to Suggests.
+    - Remove repeated 'Priority' line in binary package stanza.
+    - Update crufty long and short descriptions.
+    - Add ${misc:Depends} in binary stanza for debhelper-using package.
+
+ -- Chris Lamb <lamby@debian.org>  Sun, 08 Mar 2009 06:01:59 +0000
+
+python-django (1.0.2-1) unstable; urgency=low
+
+  [ Chris Lamb ]
+  * New upstream bugfix release. Closes: #505783
+  * Add myself to Uploaders with ACK from Brett.
+
+  [ David Spreen ]
+  * Remove python-pysqlite2 from Recommends because Python 2.5 includes
+    sqlite library used by Django. Closes: 497886
+
+  [ Sandro Tosi ]
+  * debian/control
+    - switch Vcs-Browser field to viewsvn
+
+ -- Chris Lamb <lamby@debian.org>  Wed, 19 Nov 2008 21:31:00 +0000
+
+python-django (1.0-1) unstable; urgency=low
+
+  [ David Spreen ]
+  * New _stable_ upstream release.
+
+  [ Raphael Hertzog ]
+  * This version fixes the latest security issue:
+    http://www.djangoproject.com/weblog/2008/sep/02/security/
+    Closes: #497765
+  * Don't include source files of documentation in the binary package,
+    keep only the HTML version.
+  * Updated README.Debian with information about the switch from 0.96 to
+    1.0.
+  * Remove execute right on /etc/bash_completion.d/django_bash_completion
+  * Add debian/patches/04_hyphen-manpage.diff to fix a lintian message
+    (hyphen-used-as-minus-sign usr/share/man/man1/django-admin.1.gz:156).
+  * Don't compress javascript files.
+  * Add libjs-jquery to Recommends since it's used by the HTML
+    documentation.
+
+ -- Raphael Hertzog <hertzog@debian.org>  Thu, 04 Sep 2008 08:33:32 +0200
+
+python-django (1.0~beta2+ds-1) unstable; urgency=low
+
+  * Bumping up upstream version to push sources into unstable.
+    (Thanks to Raphael Hertzog).
+
+ -- David Spreen <netzwurm@debian.org>  Sat, 30 Aug 2008 20:56:09 -0700
+
+python-django (1.0~beta2-3) unstable; urgency=low
+
+  [ David Spreen ]
+  * Updated the copyright information to include copyright and 
+    licenses for individual contributions. 
+  * Added the documentation to the main python-django package:
+  * debian/python-django.install
+    - Added installation of html documentation.
+  * debian/python-django.doc-base
+    - Added.
+  * debian/control
+    - Added Build-Depends-Indep on python-sphinx and libjs-jquery.
+  * debian/rules
+    - Readded code to build documentation.
+    - Readded code to link to libjs-jquery.
+  * debian/NEWS
+    - Fixed format.
+    - Added more comprehensive list of changes and references to 
+      local documentation as well as the wiki pages for 
+      backwards-incompatible changes.
+  * debian/python-django.docs
+    - Removed docs/*.txt since those are templates for the 
+      generated docs now included with doc-base.
+  
+ -- David Spreen <netzwurm@debian.org>  Fri, 29 Aug 2008 09:20:45 -0700
+
+python-django (1.0~beta2-2) unstable; urgency=low
+
+  [ David Spreen ]
+  * Removed all -doc related files temporarily to push beta2 into 
+    unstable for extensive testing. The -doc package will be 
+    readded once this package is in unstable as recommended in
+    http://lists.debian.org/debian-release/2008/08/msg01475.html.
+  * debian/python-django-doc.install
+    - Removed.
+  * debian/python-django-doc.doc-base
+    - Removed.
+  * debian/python-django-doc.examples
+    - Moved to python-django.examples.
+  * debian/rules
+    - Removed python-doc related build and post-installation.
+  * debian/control
+    - Removed binary package python-django-doc.
+    - Removed Build-Depends-Indep on python-sphinx and libjs-jquery.
+  * debian/python-django.install:
+    - Removed multiple package related issues.
+
+ -- David Spreen <netzwurm@debian.org>  Thu, 28 Aug 2008 20:15:21 -0700
+
+python-django (1.0~beta2-1) experimental; urgency=low
+
+  [ David Spreen ]
+  * The `hooray for the documentation' release!
+  * New upstream beta release. 
+  * debian/control 
+    - Updated standards version.
+    - Added python-sphinx and libjs-jquery.
+    - Added python-django-doc package depending on libjs-jquery.
+  * debian/docs
+    - Moved to debian/python-django.docs.
+  * debian/install
+    - Moved to debian/python-django.install.
+  * debian/manpages
+    - Moved to debian/python-django.manpages.
+  * debian/examples
+    - Moved to debian/python-django-doc.examples
+  * debian/README.Debian
+    - Moved to debian/python-django.README.Debian
+  * debian/python-django-doc.doc-base:
+    - Added doc-base file for the documentation.
+  * debian/python-django-doc.install:
+    - Added install file for sphinx generated documentation.
+  * debian/rules:
+    - Added code to generate documentation with sphinx and 
+      replace convenience file of jquery.js with the respective
+      symlink to libjs-jquery.
+  
+ -- David Spreen <netzwurm@debian.org>  Thu, 28 Aug 2008 10:22:29 -0700
+
+python-django (1.0~beta1-1) experimental; urgency=low
+
+  [ David Spreen ]
+  * New upstream beta release. Closes: #492956
+  * debian/control: Added myself to Uploaders field.
+  * debian/watch: Added mangling for filename and version. Old watch file would 
+    name the download 'tarball'. Also added mangling to handle alpha and beta 
+    versioning.
+  * Drop debian/patches/01_add_shebang.diff as this has been fixed upstream.
+  * Drop debian/patches/02_bash_completion.diff as this has been committed
+    upstream http://code.djangoproject.com/ticket/7268.
+  * debian/control: Added python-flup to the Suggest field. Closes: #488123
+  * debian/patches/03_manpage.diff: Adapted patch to new upstream version.
+  
+  [ Jan Dittberner ]
+  * add debian/watch file.
+  
+ -- David Spreen <netzwurm@debian.org>  Fri, 15 Aug 2008 16:05:07 -0700
+
+python-django (0.97~svn7534-1) experimental; urgency=low
+
+  * New upstream snapshot. Closes: #409565, #481051
+    - Include an XSS security fix (CVE-2008-2302). Closes: #481164
+  * Drop debian/patches/04_pg_version_fix.diff as another fix
+    has been committed upstream (see http://code.djangoproject.com/ticket/6433
+    and http://code.djangoproject.com/changeset/7415).
+  * Add some headers to the remaining patches.
+
+ -- Raphael Hertzog <hertzog@debian.org>  Mon, 19 May 2008 23:41:50 +0200
+
+python-django (0.97~svn7189-1) experimental; urgency=low
+
+  * New upstream snapshot including bash completion fix
+    Closes: #450913
+
+ -- Brett Parker <iDunno@sommitrealweird.co.uk>  Sun, 02 Mar 2008 12:59:03 +0000
+
+python-django (0.97~svn7047-2) experimental; urgency=low
+
+  [ Brett Parker ]
+  * Patch for postgresql version issue with 8.3 beta/rc releases
+    Closes: #462058
+
+  [ Raphael Hertzog ]
+  * Updated Standards-Version to 3.7.3.
+  * Adjusted build-dependency on python-setuptools to strip the -1 part.
+
+ -- Brett Parker <iDunno@sommitrealweird.co.uk>  Wed,  6 Feb 2008 15:15:37 +0000
+
+python-django (0.97~svn7047-1) experimental; urgency=low
+
+  * New upstream snapshot (rev 7047)
+  - tarball prepared by Gabriel Falcão Gonçalves de Moura
+    <gabriel@guake-terminal.org>
+
+ -- Gustavo Noronha Silva <kov@debian.org>  Tue, 29 Jan 2008 10:54:47 -0200
+
+python-django (0.97~svn6996-1) experimental; urgency=low
+
+  * New upstream snapshot
+  * debian/control:
+  - added myself to Uploaders
+
+ -- Gustavo Noronha Silva <kov@debian.org>  Sat, 05 Jan 2008 20:53:23 -0200
+
+python-django (0.97~svn6668-2) UNRELEASED; urgency=low
+
+  [ Raphael Hertzog ]
+  * Install examples with dh_installexamples instead of dh_installdocs
+    (change done by Ubuntu) as empty files are kept.
+
+  [ Sandro Tosi ]
+  * debian/control
+    - uniforming Vcs-Browser field
+
+ -- Raphael Hertzog <hertzog@debian.org>  Mon, 17 Dec 2007 09:09:16 +0100
+
+python-django (0.97~svn6668-1) experimental; urgency=low
+
+  * New SVN snapshot (rev 6668)
+    - Auth system delegations
+    - Apps can now have thier own management commands
+    - Fix for CVE-2007-5712 remote denial of service
+      Closes: #448838
+  * Fix missing upstream info in changelog
+    Closes: #450659
+
+ -- Brett Parker <iDunno@sommitrealweird.co.uk>  Sun, 11 Nov 2007 10:15:55 +0000
+
+python-django (0.96+svn6373-1) experimental; urgency=low
+
+  [ Raphael Hertzog ]
+  * New SVN snapshot (rev 6373, a few days after the last Django sprint).
+  * Note: The version 0.96+svn6034-1 never got uploaded.
+  * Rename XS-Vcs* fields to Vcs-* since they are now supported by dpkg.
+
+  [ Piotr Ożarowski ]
+  * XS-Vcs-Browser and Homepage fields added
+
+ -- Raphael Hertzog <hertzog@debian.org>  Thu, 04 Oct 2007 14:59:01 +0200
+
+python-django (0.96+svn6034-1) experimental; urgency=low
+
+  [ Brett Parker]
+  * New SVN snapshot (rev 6034).
+     * validate and runserver commands now display the number of errors
+       (returning back to previous functionality).
+     * Small documentation fixes
+     * assertRedirects handling for paths with get data
+     * start{project,app} no make sure files created are writable
+  * Add man page for django-admin to the debian package
+
+ -- Brett Parker <iDunno@sommitrealweird.co.uk>  Sat,  8 Sep 2007 10:37:00 +0100
+
+python-django (0.96+svn6020-1) experimental; urgency=low
+
+  * New SVN snapshot (rev 6020).
+
+ -- Raphael Hertzog <hertzog@debian.org>  Sun, 26 Aug 2007 18:16:08 +0200
+
+python-django (0.96+svn5779-1) experimental; urgency=low
+
+  * SVN snapshot (rev 5779) packaged to experimental as many interesting
+    Django applications rely on newer unreleased features.
+
+ -- Raphael Hertzog <hertzog@debian.org>  Tue, 31 Jul 2007 13:40:18 +0200
+
+python-django (0.96-1) unstable; urgency=low
+
+  [ Brett Parker ]
+  * New upstream release - introduces some backwards incompatible changes, see
+    README.Debian or the backwards incompatible changes page at
+    http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges
+  * Add documentation from upstream to /usr/share/doc/python-django
+    Closes: #411249
+  * Install the bash completion file from extras in to
+    /etc/bash_completion.d/django_bash_completion
+    Closes: #414399
+  * Egg support dropped as it's been dropped by upstream.
+
+ -- Brett Parker <iDunno@sommitrealweird.co.uk>  Sun, 25 Mar 2007 19:18:39 +0100
+
+python-django (0.95.1-1) unstable; urgency=low
+
+  [ Brett Parker ]
+  * New upstream minor release for security bugs:
+    - http://www.djangoproject.com/weblog/2007/jan/21/0951/
+      - Fixes a small security vulnerability in the script Django's
+        internationalization system uses to compile translation files
+        (changeset 4360 in the "0.95-bugfixes" branch).
+      - fix for a bug in Django's authentication middleware which could cause
+        apparent "caching" of a logged-in user (changeset 4361).
+      - patch which disables debugging mode in the flup FastCGI package Django
+        uses to launch its FastCGI server, which prevents tracebacks from
+        bubbling up during production use (changeset 4363).
+    Closes: #407786, #407607
+  * Sets Recommends to python-psycopg and moves other database engines to
+    the Suggests field.
+
+  [ Raphael Hertzog ]
+  * Use python-pysqlite2 as default database engine in Recommends. Others are
+    in Suggests. Closes: #403761
+  * Add python-psycopg2 in Suggests. Closes: #407489
+
+ -- Raphael Hertzog <hertzog@debian.org>  Sun, 21 Jan 2007 17:45:50 +0100
+
+python-django (0.95-3) unstable; urgency=low
+
+  * Integrate 2 upstream changesets:
+    - http://code.djangoproject.com/changeset/3754 as
+      debian/patches/04_sec_fix_auth.diff
+      Fixes a possible case of mis-authentication due to bad caching.
+      Closes: #407521
+    - http://code.djangoproject.com/changeset/3592 as
+      debian/patches/03_sec_fix_compile-messages.diff
+      Fixes an (unlikely) arbitrary command execution if the user is blindly
+      running compile-messages.py on a untrusted set of *.po files.
+      Closes: #407519
+
+ -- Raphael Hertzog <hertzog@debian.org>  Sat, 16 Dec 2006 15:13:29 +0100
+
+python-django (0.95-2) unstable; urgency=low
+
+  [ Piotr Ozarowski ]
+  * Added XS-Vcs-Svn field
+
+  [ Brett Parker ]
+  * Made manage.py get a shebang with the version of python
+    used when running django-admin (closes: #401616)
+  * Created a convenience /usr/lib/python-django/bin symlink.
+
+  [ Raphael Hertzog ]
+  * Adapted Brett's work to better fit my views of the packaging.
+
+ -- Raphael Hertzog <hertzog@debian.org>  Sat, 16 Dec 2006 11:03:20 +0100
+
+python-django (0.95-1) unstable; urgency=low
+
+  [ Brett Parker ]
+  * 0.95 release - initial packaging
+
+  [ Raphael Hertzog ]
+  * Fix recommends: s/python-sqlite/python-pysqlite2/
+  * Add debian/pyversions to ensure that we have at least python 2.3 (and to
+    work around bug #391689 of python-support).
+
+ -- Raphael Hertzog <hertzog@debian.org>  Mon,  9 Oct 2006 12:10:27 +0200
--- python-django-1.1.1.orig/debian/NEWS
+++ python-django-1.1.1/debian/NEWS
@@ -0,0 +1,63 @@
+python-django (1.0~beta2-3) unstable; urgency=low
+  
+  The transition from Django 0.96.2 to Django 1.0 means that your Django software
+  will probably have to be updated. A comprehensive list of changes since Django
+  0.96 is available at the Django Wiki[1]. If you are upgrading from 0.95 
+  (Sarge), you should refer to this page[2] as well. 
+  
+  The Debian package now also includes the full Django documentation in HTML
+  format[3]
+  
+  The following incomplete list of major changes is taken from the release notes 
+  of 1.0alpha1[4], 1.0alpha2[5], 1.0beta1[6] ad 1.0beta2[7]. For more changes 
+  see those release notes or [1].
+  
+  Refactored admin application (newforms-admin)
+    The Django administrative interface (django.contrib.admin) has been 
+    completely refactored; admin definitions are now completely decoupled from 
+    model definitions (no more class Admin declaration in models!), rewritten 
+    to use Django’s new form-handling library (introduced in the 0.96 release 
+    as django.newforms, and now available as simply django.forms) and redesigned 
+    with extensibility and customization in mind. Full documentation for the 
+    admin application is available online in the official Django 
+    documentation[8].
+  
+  INSERT/UPDATE distinction
+    Although Django’s default behavior of having a model’s save() method 
+    automatically determine whether to perform an INSERT or an UPDATE at 
+    the SQL level is suitable for the majority of cases, there are occasional 
+    situations where forcing one or the other is useful. As a result, models 
+    can now support an additional parameter to save() which can force a specific
+    operation. Consult the database API documentation[9] for details and important
+    notes about appropriate use of this parameter.
+  
+  Split CacheMiddleware
+    Django’s CacheMiddleware has been split into three classes: CacheMiddleware 
+    itself still exists and retains all of its previous functionality, but it 
+    is now built from two separate middleware classes which handle the two parts 
+    of caching (inserting into and reading from the cache) separately, offering 
+    additional flexibility for situations where combining these functions into a 
+    single middleware posed problems. Full details, including updated notes on 
+    appropriate use, are in the caching documentation[10].
+  
+  Refactored django.contrib.comments
+    As part of a Google Summer of Code project, Thejaswi Puthraya carried out 
+    a major rewrite and refactoring of Django’s bundled comment system, greatly 
+    increasing its flexibility and customizability. Full documentation[11] is 
+    available, as well as an upgrade guide[12] if you were using the previous 
+    incarnation of the comments application.
+  
+  [1] http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges
+  [2] http://code.djangoproject.com/wiki/OlderBackwardsIncompatibleChanges
+  [3] /usr/share/doc/python-django/html/index.html
+  [4] http://docs.djangoproject.com/en/dev/releases/1.0-alpha-1/#releases-1-0-alpha-1
+  [5] http://docs.djangoproject.com/en/dev/releases/1.0-alpha-2/#releases-1-0-alpha-2 
+  [6] http://docs.djangoproject.com/en/dev/releases/1.0-beta/#releases-1-0-beta
+  [7] http://docs.djangoproject.com/en/dev/releases/1.0-beta-2/
+  [8] /usr/share/doc/python-django/html/ref/contrib/admin.html
+  [9] /usr/share/doc/python-django/html/ref/models/index.html
+  [10] /usr/share/doc/python-django/html/topics/cache.html
+  [11] /usr/share/doc/python-django/html/ref/contrib/comments/index.html
+  [12] /usr/share/doc/python-django/html/ref/contrib/comments/upgrade.htm
+  
+ -- David Spreen <netzwurm@debian.org>  Fri, 28 Aug 2008 09:10:16 -0700
--- python-django-1.1.1.orig/debian/rules
+++ python-django-1.1.1/debian/rules
@@ -0,0 +1,57 @@
+#!/usr/bin/make -f
+
+include /usr/share/python/python.mk
+
+PREFIX = debian/python-django
+DJANGO_DIR = $(PREFIX)/$(call py_libdir_sh,`pyversions -d`)/django
+
+%:
+	dh --with quilt $@
+
+override_dh_auto_clean:
+	rm -rf docs.debian testproject
+	dh_auto_clean
+
+override_dh_auto_build:
+	dh_auto_build
+	
+	# Build the HTML documentation.
+	# We programmatically replace most instances of django-admin.py with
+	# django-admin and remove the source files from the target _build.
+	cp -r docs docs.debian
+	find docs.debian -type f -print0 | xargs -0r perl -pi -e 's|(?<!/)(django-admin)\.py|$$1|'
+	make -C docs.debian html
+	rm -rf docs.debian/_build/html/_sources/
+
+override_dh_auto_test:
+	PYTHONPATH=. django/bin/django-admin.py startproject testproject
+	sed -i "s|DATABASE_ENGINE = ''|DATABASE_ENGINE = 'sqlite3'|" testproject/settings.py
+	PYTHONPATH=. tests/runtests.py --settings=testproject.settings --verbosity=2
+
+override_dh_install:
+	dh_install
+	
+	# Use default shebang
+	perl -pi -e 's|^#!/usr/bin/env python.*|#!/usr/bin/python|' $(DJANGO_DIR)/conf/project_template/manage.py
+	chmod +x $(DJANGO_DIR)/conf/project_template/manage.py
+	
+	# Move scripts to /usr/lib/python-django
+	mkdir -p $(PREFIX)/usr/lib/python-django
+	mv $(DJANGO_DIR)/bin $(PREFIX)/usr/lib/python-django
+	
+	# Fix permissions
+	chmod 644 $(PREFIX)/etc/bash_completion.d/django_bash_completion
+	find $(PREFIX)/usr/lib/python-django/bin/ -name '*.py' -not -name '__init__.py' -print0 | xargs -0r chmod 755
+	
+	# Rename django-admin.py to django-admin
+	mv $(PREFIX)/usr/bin/django-admin.py $(PREFIX)/usr/bin/django-admin
+
+override_dh_installdocs:
+	dh_installdocs
+	# Remove embedded copy of libjs-jquery
+	cd debian/python-django-doc/usr/share/doc/python-django-doc/html/_static \
+		&& rm jquery.js \
+		&& ln -s ../../../../javascript/jquery/jquery.js .
+
+override_dh_compress:
+	dh_compress -X.js
--- python-django-1.1.1.orig/debian/python-django.docs
+++ python-django-1.1.1/debian/python-django.docs
@@ -0,0 +1,2 @@
+README
+AUTHORS
--- python-django-1.1.1.orig/debian/copyright
+++ python-django-1.1.1/debian/copyright
@@ -0,0 +1,312 @@
+This package was debianized by Brett Parker <iDunno@sommitrealweird.co.uk> with
+the assistance of Raphael Hertzog <hertzog@debian.org>, Gustavo Noronha Silva 
+<kov@debian.org>, David Spreen <netzwurm@debian.org> and the Debian Python 
+Modules Team <python-modules-team@lists.alioth.debian.org>.
+
+The upstream source is available from <http://www.djangoproject.com/download/>.
+
+Main Django Code Licence:
+=========================
+Copyright (c) Django Software Foundation and individual contributors.
+All rights reserved.
+
+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.
+
+    3. Neither the name of Django nor the names of its contributors may be used
+       to endorse or promote products derived from this software without
+       specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+
+Individual copyright holders stated in Main Django License are listed
+in /usr/share/doc/python-django/AUTHORS.gz.
+
+PyDispatcher Licence (django/dispatch/*):
+=========================================
+
+	Copyright (c) 2001-2003, Patrick K. O'Brien and Contributors
+	All rights reserved.
+	
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions
+	are met:
+	
+		Redistributions of source code must retain the above copyright
+		notice, this list of conditions and the following disclaimer.
+	
+		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.
+	
+		The name of Patrick K. O'Brien, or the name of any Contributor,
+		may not be used to endorse or promote products derived from this 
+		software without specific prior written permission.
+	
+	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+	``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
+	COPYRIGHT HOLDERS AND CONTRIBUTORS 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. 
+
+License of django/utils/simplejson/*
+====================================
+
+Copyright (c) 2006 Bob Ippolito
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, 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.
+
+License for django/utils/functional.py and django/utils/_decimal.py
+(License taken from Python 2.5)
+=======================================================================
+
+functional.py:
+Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation
+
+decimal.py:
+Copyright (c) 2004 Python Software Foundation
+
+
+PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+--------------------------------------------
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation
+("PSF"), and the Individual or Organization ("Licensee") accessing and
+otherwise using this software ("Python") in source or binary form and
+its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python
+alone or in any derivative version, provided, however, that PSF's
+License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
+2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation;
+All Rights Reserved" are retained in Python alone or in any derivative
+version prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python.
+
+4. PSF is making Python available to Licensee on an "AS IS"
+basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between PSF and
+Licensee.  This License Agreement does not grant permission to use PSF
+trademarks or trade name in a trademark sense to endorse or promote
+products or services of Licensee, or any third party.
+
+8. By copying, installing or otherwise using Python, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+django/utils/autoreload.py
+===========================
+
+Portions Copyright (c) 2004 CherryPy Team <team@cherrypy.org>
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+     * Redistributions of source code must retain the above copyright notice,
+       this list of conditions and the following disclaimer.
+     * 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.
+     * Neither the name of the CherryPy Team nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+
+Some code taken from Ian Bicking's Paste which is released under the MIT
+License: 
+
+Copyright (c) 2008 Ian Bicking
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, 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.
+
+django/contrib/gis/geos/* and django/contrib/gis/gdal/*
+========================================================
+Copyright (c) 2007, Justin Bronn
+
+All rights reserved.
+
+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.
+
+    3. Neither the name of GEOSGeometry nor the names of its contributors may be used
+       to endorse or promote products derived from this software without
+       specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+
+django/contrib/gis/measure.py:
+===============================
+Copyright (c) 2007, Robert Coup <robert.coup@onetrackmind.co.nz>
+
+All rights reserved.
+
+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.
+
+    3. Neither the name of Distance nor the names of its contributors may be used
+       to endorse or promote products derived from this software without
+       specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+
+docs/_static/reset-fonts-grids.css:
+====================================
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+
+Software License Agreement (BSD License), downloaded from
+<http://developer.yahoo.net/yui/license.txt> on Friday, Aug 29 2008
+
+Copyright (c) 2006, Yahoo! Inc.
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms, with or 
+without modification, are permitted provided that the following conditions are 
+met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* 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.
+
+* Neither the name of Yahoo! Inc. nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of Yahoo! Inc.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
--- python-django-1.1.1.orig/debian/pyversions
+++ python-django-1.1.1/debian/pyversions
@@ -0,0 +1 @@
+2.3-
--- python-django-1.1.1.orig/debian/python-django.README.Debian
+++ python-django-1.1.1/debian/python-django.README.Debian
@@ -0,0 +1,178 @@
+0.96 -> 1.0
+===========
+
+Django 1.0 has a number of backwards-incompatible changes from Django
+0.96. If you have apps written against Django 0.96 that you need to port,
+see the detailed porting guide:
+/usr/share/doc/python-django/html/releases/1.0-porting-guide.html
+or
+http://docs.djangoproject.com/en/dev/releases/1.0-porting-guide/
+
+You can also find a complete list of of backwards incompatible changes
+here:
+http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges
+
+0.95 -> 0.96
+============
+
+Information here has been gathered from:
+    http://www.djangoproject.com/documentation/release_notes_0.96/
+and
+    http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges
+
+Backwards Incompatible Changes
+------------------------------
+
+    Database constraint names changed
+    =================================
+
+    As of [3512], the format of the constraint names Django generates for
+    foreign key references changed slightly. These names are only used
+    sometimes, when it is not possible to put the reference directly on the
+    affected column, so this is not always visible.
+
+    The effect of this change is that manage.py reset app_name and similar
+    commands may generate SQL with invalid constraint names and thus generate
+    an error when run against the database (the database server will complain
+    about the constraint not existing). To fix this, you will need to tweak the
+    output of manage.py sqlreset app_name to match the correct constraint names
+    and pass the results to the database server manually. 
+
+    Backslash escaping changed
+    ==========================
+
+    As of [3552], the Django database API now escapes backslashes given as
+    query parameters. If you have any database API code that match backslashes,
+    and it was working before (despite the broken escaping), you'll have to
+    change your code to "unescape" the slashes one level.
+
+    For example, this used to work:
+
+    # Code that matches a single backslash
+    MyModel.objects.filter(text__contains='\\\\')
+
+    But it should be rewritten as this:
+
+    # Code that matches a single backslash
+    MyModel.objects.filter(text__contains='\\')
+
+    Removed ENABLE_PSYCO setting
+    ============================
+
+    As of [3877], the ENABLE_PSYCO setting no longer exists. If your settings
+    file includes ENABLE_PSYCO, nothing will break per se, but it just won't do
+    anything. If you want to use Psyco with Django, write some custom
+    middleware that activates Psyco.
+
+    Changed Admin.manager option to more flexible hook
+    ==================================================
+
+    As of [4342], the manager option to class Admin no longer exists. This
+    option was undocumented, but we're mentioning the change here in case you
+    used it. In favor of this option, class Admin may now define one of these
+    methods:
+
+        * queryset()
+        * queryset_add()
+        * queryset_change() 
+
+    These give you much more flexibility.
+
+    Note that this change was made to the NewformsAdminBranch. (We initially
+    called the new method change_list_queryset, but this was changed in [4584]
+    to be more flexible.) The change will not be made to trunk until that
+    branch is merged to trunk.
+
+    Changed prepopulate_from to be defined in the Admin class, 
+    not database field classes ¶
+    ==========================================================
+
+    As of [4446], the prepopulate_from option to database fields no
+    longer exists. It's been discontinued in favor of the new
+    prepopulated_fields option on class Admin. The new
+    prepopulated_fields option, if given, should be a dictionary
+    mapping field names to lists/tuples of field names. Here's an
+    example comparing old syntax and new syntax:
+
+    # OLD:
+    class MyModel(models.Model):
+        first_name = models.CharField(maxlength=30)
+        last_name = models.CharField(maxlength=30)
+        slug = models.CharField(maxlength=60, prepopulate_from=('first_name', 'last_name'))
+
+        class Admin:
+            pass
+
+    # NEW:
+    class MyModel(models.Model):
+        first_name = models.CharField(maxlength=30)
+        last_name = models.CharField(maxlength=30)
+        slug = models.CharField(maxlength=60)
+
+        class Admin:
+            prepopulated_fields = {'slug': ('first_name', 'last_name')}
+
+    Moved admin doc views into django.contrib.admindocs
+    ====================================================
+
+    As of [4585], the documentation views for the Django admin site were moved
+    into a new package, django.contrib.admindocs.
+
+    The admin docs, which aren't documented very well, were located at docs/ in
+    the admin site. They're also linked-to by the "Documentation" link in the
+    upper right of default admin templates.
+
+    Because we've moved the doc views, you now have to activate admin docs
+    explicitly. Do this by adding the following line to your URLconf:
+
+    (r'^admin/doc/', include('django.contrib.admindocs.urls')),
+
+    Note that this change was made to the NewformsAdminBranch. The change will
+    not be made to trunk until that branch is merged to trunk.
+
+    Enforcing MySQLdb version
+    =========================
+
+    As of [4724], Django will raise an error if you try to use the MySQL
+    backend with a MySQLdb ( MySQL python module) version earlier than 1.2.1p2.
+    There were significant, production-related bugs in earlier versions, so we
+    have upgraded the minimum requirement.
+
+    In [4767], a mysql_old backend was added, that is identical to the original
+    mysql backend prior to the change in [4724]. This backend can be used if
+    upgrading the MySQLdb module is not immediately possible, however, it is
+    deprecated and no further development will be done on it. 
+
+New Features
+------------
+    
+    New forms library
+    =================
+
+    The new forms library has been merged from the new forms branch in to
+    django.newforms in 0.96, the next revision will replace django.forms with
+    django.newforms, the current forms library is already copied to
+    django.oldforms to make the transition easier - it's advised to either
+    upgrade your forms code to the newforms library or to change your imports
+    as follows:
+        
+        from django import forms
+    becomes
+        from django import oldforms as forms
+    
+    URLconf improvements
+    ====================
+    
+    It's now possible to use imported views in the urlconf rather than a string
+    representing the view to call.
+
+    Test framework
+    ==============
+
+    Now possible to write tests based on doctest and unittest
+
+    Admin area changes
+    ==================
+
+    Changes to the user adding and updating views so that you don't need to
+    worry about hashed passwords.
--- python-django-1.1.1.orig/debian/python-django.install
+++ python-django-1.1.1/debian/python-django.install
@@ -0,0 +1,2 @@
+usr/
+extras/django_bash_completion etc/bash_completion.d/
--- python-django-1.1.1.orig/debian/contrib/initscript
+++ python-django-1.1.1/debian/contrib/initscript
@@ -0,0 +1,131 @@
+#! /bin/sh
+### BEGIN INIT INFO
+# Provides:          FastCGI servers for Django
+# Required-Start:    networking
+# Required-Stop:     networking
+# Default-Start:     2 3 4 5
+# Default-Stop:      S 0 1 6
+# Short-Description: Start FastCGI servers with Django.
+# Description:       Django, in order to operate with FastCGI, must be started
+#                    in a very specific way with manage.py. This must be done
+#                    for each Django web server that has to run.
+### END INIT INFO
+#
+# Author:  Guillermo Fernandez Castellanos
+#          <guillermo.fernandez.castellanos AT gmail.com>.
+#
+# Changed: Jannis Leidel
+#          <jannis AT leidel.info>
+#          Joost Cassee
+#          <joost@cassee.net>
+#
+# Version: @(#)fastcgi 0.3 05-Aug-2008 joost AT cassee.net
+#
+
+set -e
+
+#### CONFIGURATION (override in /etc/default/django)
+
+# django project names/directories
+DJANGO_SITES=""
+
+# path to the directory with your django projects
+SITES_PATH=/var/lib/django
+
+# path to the directory for socket and pid files
+RUNFILES_PATH=/var/run/django
+
+# please make sure this is NOT root
+# local user prefered, www-data accepted
+RUN_AS=www-data
+
+# maximum requests before fast-cgi process respawns
+# (a.k.a. get killed and let live)
+MAXREQUESTS=1000
+
+#### END CONFIGURATION
+
+# Include defaults if available
+if [ -f /etc/default/django ] ; then
+    . /etc/default/django
+fi
+
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+DESC="Django FastCGI servers"
+NAME=$0
+SCRIPTNAME=/etc/init.d/$NAME
+mkdir -p $RUNFILES_PATH
+chown -R $RUN_AS:$RUN_AS $RUNFILES_PATH
+
+#
+#       Function that starts the daemon/service.
+#
+d_start()
+{
+    # Starting all Django FastCGI processes
+    # PORT=$PORT_START
+    for SITE in $DJANGO_SITES
+    do
+        echo -n ", $SITE"
+        if [ -f $RUNFILES_PATH/$SITE.pid ]; then
+            echo -n " already running"
+        else
+            start-stop-daemon --start --quiet \
+                       --pidfile $RUNFILES_PATH/$SITE.pid \
+                       --chuid $RUN_AS --exec /usr/bin/env -- python \
+                       $SITES_PATH/$SITE/manage.py runfcgi \
+                       protocol=fcgi method=threaded maxrequests=$MAXREQUESTS \
+                       socket=$RUNFILES_PATH/$SITE.socket \
+                       pidfile=$RUNFILES_PATH/$SITE.pid
+            chmod 400 $RUNFILES_PATH/$SITE.pid
+        fi
+        sleep 1
+    done
+}
+
+#
+#       Function that stops the daemon/service.
+#
+d_stop() {
+    # Killing all Django FastCGI processes running
+    for SITE in $DJANGO_SITES
+    do
+        echo -n ", $SITE"
+        start-stop-daemon --stop --quiet --pidfile $RUNFILES_PATH/$SITE.pid \
+                          || echo -n " not running"
+        if [ -f $RUNFILES_PATH/$SITE.pid ]; then
+           rm -f $RUNFILES_PATH/$SITE.pid
+        fi
+        sleep 1
+    done
+}
+
+ACTION="$1"
+case "$ACTION" in
+    start)
+        echo -n "Starting $DESC: $NAME"
+        d_start
+        echo "."
+        ;;
+
+    stop)
+        echo -n "Stopping $DESC: $NAME"
+        d_stop
+        echo "."
+        ;;
+
+    restart|force-reload)
+        echo -n "Restarting $DESC: $NAME"
+        d_stop
+        sleep 2
+        d_start
+        echo "."
+        ;;
+
+    *)
+        echo "Usage: $NAME {start|stop|restart|force-reload}" >&2
+        exit 3
+        ;;
+esac
+
+exit 0
--- python-django-1.1.1.orig/debian/contrib/default
+++ python-django-1.1.1/debian/contrib/default
@@ -0,0 +1,16 @@
+# django project names/directories
+DJANGO_SITES="myapp myapp2 myapp3"
+
+# path to the directory with your django projects
+#SITES_PATH=/home/django/projects
+
+# path to the directory for socket and pid files
+RUNFILES_PATH=$SITES_PATH/run
+
+# please make sure this is NOT root
+# local user prefered, www-data accepted
+RUN_AS=django
+
+# maximum requests before fast-cgi process respawns
+# (a.k.a. get killed and let live)
+MAXREQUESTS=100
--- python-django-1.1.1.orig/debian/patches/CVE-2011-4137+4138.patch
+++ python-django-1.1.1/debian/patches/CVE-2011-4137+4138.patch
@@ -0,0 +1,42 @@
+Origin: backport, https://code.djangoproject.com/changeset/16766
+Description: Altered the behavior of URLField to avoid a potential DOS vector,
+ and to avoid potential leakage of local filesystem data.
+Index: python-django-1.1.1/django/db/models/fields/__init__.py
+===================================================================
+--- python-django-1.1.1.orig/django/db/models/fields/__init__.py	2009-04-12 00:32:23.000000000 -0500
++++ python-django-1.1.1/django/db/models/fields/__init__.py	2011-12-07 16:00:14.000000000 -0600
+@@ -888,7 +888,7 @@
+         return super(TimeField, self).formfield(**defaults)
+ 
+ class URLField(CharField):
+-    def __init__(self, verbose_name=None, name=None, verify_exists=True, **kwargs):
++    def __init__(self, verbose_name=None, name=None, verify_exists=False, **kwargs):
+         kwargs['max_length'] = kwargs.get('max_length', 200)
+         self.verify_exists = verify_exists
+         CharField.__init__(self, verbose_name, name, **kwargs)
+Index: python-django-1.1.1/docs/ref/models/fields.txt
+===================================================================
+--- python-django-1.1.1.orig/docs/ref/models/fields.txt	2009-09-23 18:41:35.000000000 -0500
++++ python-django-1.1.1/docs/ref/models/fields.txt	2011-12-07 16:00:14.000000000 -0600
+@@ -730,7 +730,7 @@
+ ``URLField``
+ ------------
+ 
+-.. class:: URLField([verify_exists=True, max_length=200, **options])
++.. class:: URLField([verify_exists=False, max_length=200, **options])
+ 
+ A :class:`CharField` for a URL. Has one extra optional argument:
+ 
+@@ -742,6 +742,12 @@
+     a url being serverd by the same server will hang.
+     This should not be a problem for multithreaded servers.
+ 
++
++.. versionchanged:: 1.2
++
++    The default value of ``verify_exists`` has been changed to
++    ``False``. This argument should not be set to ``True`` because it
++    has security and performance problems.
+ The admin represents this as an ``<input type="text">`` (a single-line input).
+ 
+ Like all :class:`CharField` subclasses, :class:`URLField` takes the optional
--- python-django-1.1.1.orig/debian/patches/18_fix_dos_via_get_image_dimensions.diff
+++ python-django-1.1.1/debian/patches/18_fix_dos_via_get_image_dimensions.diff
@@ -0,0 +1,28 @@
+Description: Fix denial of service via get_image_dimensions()
+Origin: upstream, https://github.com/django/django/commit/9ca0ff6268eeff92d0d0ac2c315d4b6a8e229155/download
+Bug-Debian: http://bugs.debian.org/683364
+
+Index: python-django-1.1.1/django/core/files/images.py
+===================================================================
+--- python-django-1.1.1.orig/django/core/files/images.py	2009-05-11 05:57:19.000000000 -0400
++++ python-django-1.1.1/django/core/files/images.py	2012-09-06 09:55:50.112096246 -0400
+@@ -39,13 +39,18 @@
+         file = open(file_or_path, 'rb')
+         close = True
+     try:
++        # Most of the time PIL only needs a small chunk to parse the image and
++        # get the dimensions, but with some TIFF files PIL needs to parse the
++        # whole file.
++        chunk_size = 1024
+         while 1:
+-            data = file.read(1024)
++            data = file.read(chunk_size)
+             if not data:
+                 break
+             p.feed(data)
+             if p.image:
+                 return p.image.size
++            chunk_size = chunk_size*2
+         return None
+     finally:
+         if close:
--- python-django-1.1.1.orig/debian/patches/CVE-2012-4520.patch
+++ python-django-1.1.1/debian/patches/CVE-2012-4520.patch
@@ -0,0 +1,113 @@
+Origin: backport, b45c377f8f488955e0c7069cad3f3dd21910b071
+From b45c377f8f488955e0c7069cad3f3dd21910b071 Mon Sep 17 00:00:00 2001
+From: Preston Holmes <preston@ptone.com>
+Date: Wed, 17 Oct 2012 14:43:08 -0700
+Subject: [PATCH] Fixed a security issue related to password resets
+
+Full disclosure and new release are forthcoming
+
+backport from master
+---
+ django/contrib/auth/tests/urls.py  |    1 +
+ django/contrib/auth/tests/views.py |   39 ++++++++++++++++++++++++++++++++++++
+ django/contrib/auth/views.py       |    2 +-
+ django/http/__init__.py            |    5 +++++
+ 4 files changed, 46 insertions(+), 1 deletion(-)
+
+Index: python-django-1.1.1/django/contrib/auth/tests/urls.py
+===================================================================
+--- python-django-1.1.1.orig/django/contrib/auth/tests/urls.py	2009-05-04 02:05:44.000000000 -0500
++++ python-django-1.1.1/django/contrib/auth/tests/urls.py	2012-11-09 16:13:37.000000000 -0600
+@@ -14,5 +14,6 @@
+     (r'^logout/custom_query/$', 'django.contrib.auth.views.logout', dict(redirect_field_name='follow')),
+     (r'^logout/next_page/$', 'django.contrib.auth.views.logout', dict(next_page='/somewhere/')),
+     (r'^remote_user/$', remote_user_auth_view),
++    (r'^admin_password_reset/$', 'django.contrib.auth.views.password_reset', dict(is_admin_site=True)),
+ )
+ 
+Index: python-django-1.1.1/django/contrib/auth/tests/views.py
+===================================================================
+--- python-django-1.1.1.orig/django/contrib/auth/tests/views.py	2009-04-18 22:41:33.000000000 -0500
++++ python-django-1.1.1/django/contrib/auth/tests/views.py	2012-11-09 16:12:08.000000000 -0600
+@@ -8,6 +8,7 @@
+ from django.contrib.auth.models import User
+ from django.test import TestCase
+ from django.core import mail
++from django.core.exceptions import SuspiciousOperation
+ from django.core.urlresolvers import reverse
+ 
+ class AuthViewsTestCase(TestCase):
+@@ -62,6 +63,44 @@
+         self.assertEquals(len(mail.outbox), 1)
+         self.assert_("http://" in mail.outbox[0].body)
+ 
++    def test_admin_reset(self):
++        "If the reset view is marked as being for admin, the HTTP_HOST header is used for a domain override."
++        response = self.client.post('/admin_password_reset/',
++            {'email': 'staffmember@example.com'},
++            HTTP_HOST='adminsite.com'
++        )
++        self.assertEqual(response.status_code, 302)
++        self.assertEqual(len(mail.outbox), 1)
++        self.assertTrue("http://adminsite.com" in mail.outbox[0].body)
++        self.assertEqual(settings.DEFAULT_FROM_EMAIL, mail.outbox[0].from_email)
++
++    def test_poisoned_http_host(self):
++        "Poisoned HTTP_HOST headers can't be used for reset emails"
++        # This attack is based on the way browsers handle URLs. The colon
++        # should be used to separate the port, but if the URL contains an @,
++        # the colon is interpreted as part of a username for login purposes,
++        # making 'evil.com' the request domain. Since HTTP_HOST is used to
++        # produce a meaningful reset URL, we need to be certain that the
++        # HTTP_HOST header isn't poisoned. This is done as a check when get_host()
++        # is invoked, but we check here as a practical consequence.
++        def test_host_poisoning():
++            self.client.post('/password_reset/',
++                {'email': 'staffmember@example.com'},
++                HTTP_HOST='www.example:dr.frankenstein@evil.tld'
++            )
++        self.assertRaises(SuspiciousOperation, test_host_poisoning)
++        self.assertEqual(len(mail.outbox), 0)
++
++    def test_poisoned_http_host_admin_site(self):
++        "Poisoned HTTP_HOST headers can't be used for reset emails on admin views"
++        def test_host_poisoning():
++            self.client.post('/admin_password_reset/',
++                {'email': 'staffmember@example.com'},
++                HTTP_HOST='www.example:dr.frankenstein@evil.tld'
++            )
++        self.assertRaises(SuspiciousOperation, test_host_poisoning)
++        self.assertEqual(len(mail.outbox), 0)
++
+     def _test_confirm_start(self):
+         # Start by creating the email
+         response = self.client.post('/password_reset/', {'email': 'staffmember@example.com'})
+Index: python-django-1.1.1/django/contrib/auth/views.py
+===================================================================
+--- python-django-1.1.1.orig/django/contrib/auth/views.py	2009-04-01 12:02:32.000000000 -0500
++++ python-django-1.1.1/django/contrib/auth/views.py	2012-11-09 16:14:53.000000000 -0600
+@@ -91,7 +91,7 @@
+             opts['use_https'] = request.is_secure()
+             opts['token_generator'] = token_generator
+             if is_admin_site:
+-                opts['domain_override'] = request.META['HTTP_HOST']
++                opts['domain_override'] = domain_override=request.get_host()
+             else:
+                 opts['email_template_name'] = email_template_name
+                 if not Site._meta.installed:
+Index: python-django-1.1.1/django/http/__init__.py
+===================================================================
+--- python-django-1.1.1.orig/django/http/__init__.py	2012-11-09 16:11:27.000000000 -0600
++++ python-django-1.1.1/django/http/__init__.py	2012-11-09 16:12:08.000000000 -0600
+@@ -57,6 +57,11 @@
+             server_port = str(self.META['SERVER_PORT'])
+             if server_port != (self.is_secure() and '443' or '80'):
+                 host = '%s:%s' % (host, server_port)
++
++        # Disallow potentially poisoned hostnames.
++        if set(';/?@&=+$,').intersection(host):
++            raise SuspiciousOperation('Invalid HTTP_HOST header: %s' % host)
++
+         return host
+ 
+     def get_full_path(self):
--- python-django-1.1.1.orig/debian/patches/CVE-2012-4520-additional-tests.diff
+++ python-django-1.1.1/debian/patches/CVE-2012-4520-additional-tests.diff
@@ -0,0 +1,94 @@
+Origin: backport, 6383d2358c1077b16b13eb6e6975d7a200ed7285
+Description: Added missed poisoned host header test material
+
+Index: python-django-1.1.1/tests/regressiontests/requests/tests.py
+===================================================================
+--- python-django-1.1.1.orig/tests/regressiontests/requests/tests.py	2012-11-19 17:30:02.000000000 -0600
++++ python-django-1.1.1/tests/regressiontests/requests/tests.py	2012-11-19 17:30:25.000000000 -0600
+@@ -4,6 +4,7 @@
+ 
+ from django.conf import settings
+ from django.http import HttpRequest, HttpResponse, parse_cookie
++from django.core.exceptions import SuspiciousOperation
+ from django.core.handlers.wsgi import WSGIRequest
+ from django.core.handlers.modpython import ModPythonRequest
+ from django.utils.http import cookie_date
+@@ -101,6 +102,39 @@
+             }
+             self.assertEqual(request.get_host(), 'internal.com:8042')
+ 
++            # Poisoned host headers are rejected as suspicious
++            legit_hosts = [
++                'example.com',
++                'example.com:80',
++                '12.34.56.78',
++                '12.34.56.78:443',
++                '[2001:19f0:feee::dead:beef:cafe]',
++                '[2001:19f0:feee::dead:beef:cafe]:8080',
++            ]
++
++            poisoned_hosts = [
++                'example.com@evil.tld',
++                'example.com:dr.frankenstein@evil.tld',
++                'example.com:someone@somestie.com:80',
++                'example.com:80/badpath'
++            ]
++
++            for host in legit_hosts:
++                request = HttpRequest()
++                request.META = {
++                    'HTTP_HOST': host,
++                }
++                request.get_host()
++
++            for host in poisoned_hosts:
++                def test_host_poisoning():
++                    request = HttpRequest()
++                    request.META = {
++                        'HTTP_HOST': host,
++                    }
++                    request.get_host()
++                self.assertRaises(SuspiciousOperation, test_host_poisoning)
++
+         finally:
+             settings.USE_X_FORWARDED_HOST = old_USE_X_FORWARDED_HOST
+ 
+@@ -145,5 +179,38 @@
+             }
+             self.assertEqual(request.get_host(), 'internal.com:8042')
+ 
++            # Poisoned host headers are rejected as suspicious
++            legit_hosts = [
++                'example.com',
++                'example.com:80',
++                '12.34.56.78',
++                '12.34.56.78:443',
++                '[2001:19f0:feee::dead:beef:cafe]',
++                '[2001:19f0:feee::dead:beef:cafe]:8080',
++            ]
++
++            poisoned_hosts = [
++                'example.com@evil.tld',
++                'example.com:dr.frankenstein@evil.tld',
++                'example.com:dr.frankenstein@evil.tld:80',
++                'example.com:80/badpath'
++            ]
++
++            for host in legit_hosts:
++                request = HttpRequest()
++                request.META = {
++                    'HTTP_HOST': host,
++                }
++                request.get_host()
++
++            for host in poisoned_hosts:
++                def test_host_poisoning():
++                    request = HttpRequest()
++                    request.META = {
++                        'HTTP_HOST': host,
++                    }
++                    request.get_host()
++                self.assertRaises(SuspiciousOperation, test_host_poisoning)
++
+         finally:
+             settings.USE_X_FORWARDED_HOST = old_USE_X_FORWARDED_HOST
--- python-django-1.1.1.orig/debian/patches/09_security_pasword_reset_dos.diff
+++ python-django-1.1.1/debian/patches/09_security_pasword_reset_dos.diff
@@ -0,0 +1,56 @@
+Origin: http://code.djangoproject.com/changeset/15036
+Description: Denial-of-service attack in password-reset mechanism
+ (CVE-2010-4535)
+
+Index: python-django-1.1.1/django/contrib/auth/tests/tokens.py
+===================================================================
+--- python-django-1.1.1.orig/django/contrib/auth/tests/tokens.py	2011-01-03 11:30:57.000000000 -0600
++++ python-django-1.1.1/django/contrib/auth/tests/tokens.py	2011-01-03 11:31:00.000000000 -0600
+@@ -34,4 +34,9 @@
+ >>> p2.check_token(u, tk1)
+ False
+ 
++This will put a 14-digit base36 timestamp into the token, which is too large.
++>>> tk1 = p0._make_token_with_timestamp(u, 175455491841851871349)
++>>> p0.check_token(u, tk1)
++False
++
+ """
+Index: python-django-1.1.1/django/contrib/auth/urls.py
+===================================================================
+--- python-django-1.1.1.orig/django/contrib/auth/urls.py	2011-01-03 11:30:57.000000000 -0600
++++ python-django-1.1.1/django/contrib/auth/urls.py	2011-01-03 11:31:00.000000000 -0600
+@@ -1,4 +1,4 @@
+-# These URLs are normally mapped to /admin/urls.py. This URLs file is 
++# These URLs are normally mapped to /admin/urls.py. This URLs file is
+ # provided as a convenience to those who want to deploy these URLs elsewhere.
+ # This file is also used to provide a reliable view deployment for test purposes.
+ 
+@@ -11,7 +11,7 @@
+     (r'^password_change/done/$', 'django.contrib.auth.views.password_change_done'),
+     (r'^password_reset/$', 'django.contrib.auth.views.password_reset'),
+     (r'^password_reset/done/$', 'django.contrib.auth.views.password_reset_done'),
+-    (r'^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm'),
++    (r'^reset/(?P<uidb36>[0-9A-Za-z]{1,13})-(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', 'django.contrib.auth.views.password_reset_confirm'),
+     (r'^reset/done/$', 'django.contrib.auth.views.password_reset_complete'),
+ )
+ 
+Index: python-django-1.1.1/django/utils/http.py
+===================================================================
+--- python-django-1.1.1.orig/django/utils/http.py	2011-01-03 11:30:57.000000000 -0600
++++ python-django-1.1.1/django/utils/http.py	2011-01-03 11:31:00.000000000 -0600
+@@ -73,8 +73,13 @@
+ 
+ def base36_to_int(s):
+     """
+-    Convertd a base 36 string to an integer
++    Converts a base 36 string to an ``int``. To prevent
++    overconsumption of server resources, raises ``ValueError` if the
++    input is longer than 13 base36 digits (13 digits is sufficient to
++    base36-encode any 64-bit integer).
+     """
++    if len(s) > 13:
++        raise ValueError("Base36 input too large")
+     return int(s, 36)
+ 
+ def int_to_base36(i):
--- python-django-1.1.1.orig/debian/patches/01_disable_url_verify_regression_tests.diff
+++ python-django-1.1.1/debian/patches/01_disable_url_verify_regression_tests.diff
@@ -0,0 +1,41 @@
+Forwarded-Upstream: not needed
+Author: Krzysztof Klimonda <kklimonda@syntaxhighlighted.com>
+Comment:
+ Disable regression tests that require an internet connection.
+ .
+ This is a Debian specific patch.
+
+Index: python-django-1.1/tests/regressiontests/forms/fields.py
+===================================================================
+--- python-django-1.1.orig/tests/regressiontests/forms/fields.py	2009-08-15 21:03:21.248330080 +0200
++++ python-django-1.1/tests/regressiontests/forms/fields.py	2009-08-15 21:03:45.709392050 +0200
+@@ -977,29 +977,6 @@
+ ...
+ ValidationError: [u'Enter a valid URL.']
+ 
+-URLField takes an optional verify_exists parameter, which is False by default.
+-This verifies that the URL is live on the Internet and doesn't return a 404 or 500:
+->>> f = URLField(verify_exists=True)
+->>> f.clean('http://www.google.com') # This will fail if there's no Internet connection
+-u'http://www.google.com/'
+->>> f.clean('http://example')
+-Traceback (most recent call last):
+-...
+-ValidationError: [u'Enter a valid URL.']
+->>> f.clean('http://www.broken.djangoproject.com') # bad domain
+-Traceback (most recent call last):
+-...
+-ValidationError: [u'This URL appears to be a broken link.']
+->>> f.clean('http://google.com/we-love-microsoft.html') # good domain, bad page
+-Traceback (most recent call last):
+-...
+-ValidationError: [u'This URL appears to be a broken link.']
+->>> f = URLField(verify_exists=True, required=False)
+->>> f.clean('')
+-u''
+->>> f.clean('http://www.google.com') # This will fail if there's no Internet connection
+-u'http://www.google.com/'
+-
+ URLField also access min_length and max_length parameters, for convenience.
+ >>> f = URLField(min_length=15, max_length=20)
+ >>> f.clean('http://f.com')
--- python-django-1.1.1.orig/debian/patches/05_ftbfs_in_november.diff
+++ python-django-1.1.1/debian/patches/05_ftbfs_in_november.diff
@@ -0,0 +1,13 @@
+Forwarded-Upstream: http://code.djangoproject.com/changeset/11697
+Comment:
+ Fix FTBFS in November.
+
+--- ./tests/regressiontests/views/tests/generic/date_based.py (revision 10556)
++++ ./tests/regressiontests/views/tests/generic/date_based.py (revision 11697)
+@@ -101,5 +101,5 @@
+         now = datetime.now()
+         prev_month = now.date().replace(day=1)
+-        if prev_month.month == 11:
++        if prev_month.month == 1:
+             prev_month = prev_month.replace(year=prev_month.year-1, month=12)
+         else:
--- python-django-1.1.1.orig/debian/patches/17_fix_dos_in_image_validation.diff
+++ python-django-1.1.1/debian/patches/17_fix_dos_in_image_validation.diff
@@ -0,0 +1,33 @@
+Description: Fix denial of service in image validation
+Origin: upstream, https://github.com/django/django/commit/b2eb4787a0fff9c9993b78be5c698e85108f3446
+Bug-Debian: http://bugs.debian.org/683364
+
+Index: python-django-1.1.1/django/forms/fields.py
+===================================================================
+--- python-django-1.1.1.orig/django/forms/fields.py	2009-10-09 16:59:05.000000000 -0400
++++ python-django-1.1.1/django/forms/fields.py	2012-09-06 09:55:40.140095990 -0400
+@@ -505,20 +505,10 @@
+                 file = StringIO(data['content'])
+ 
+         try:
+-            # load() is the only method that can spot a truncated JPEG,
+-            #  but it cannot be called sanely after verify()
+-            trial_image = Image.open(file)
+-            trial_image.load()
+-
+-            # Since we're about to use the file again we have to reset the
+-            # file object if possible.
+-            if hasattr(file, 'reset'):
+-                file.reset()
+-
+-            # verify() is the only method that can spot a corrupt PNG,
+-            #  but it must be called immediately after the constructor
+-            trial_image = Image.open(file)
+-            trial_image.verify()
++            # load() could spot a truncated JPEG, but it loads the entire
++            # image in memory, which is a DoS vector. See #3848 and #18520.
++            # verify() must be called immediately after the constructor.
++            Image.open(file).verify()
+         except ImportError:
+             # Under PyPy, it is possible to import PIL. However, the underlying
+             # _imaging C module isn't available, so an ImportError will be
--- python-django-1.1.1.orig/debian/patches/CVE-2011-4136.patch
+++ python-django-1.1.1/debian/patches/CVE-2011-4136.patch
@@ -0,0 +1,90 @@
+Origin: https://code.djangoproject.com/changeset/16765
+Description: Corrected an issue which could allow attackers to manipulate
+ session data using the cache.
+Index: python-django-1.2.5/django/contrib/sessions/backends/cached_db.py
+===================================================================
+--- python-django-1.2.5.orig/django/contrib/sessions/backends/cached_db.py	2011-11-28 17:44:57.000000000 -0600
++++ python-django-1.2.5/django/contrib/sessions/backends/cached_db.py	2011-11-28 17:45:01.000000000 -0600
+@@ -6,6 +6,8 @@
+ from django.contrib.sessions.backends.db import SessionStore as DBStore
+ from django.core.cache import cache
+ 
++KEY_PREFIX = "django.contrib.sessions.cached_db"
++
+ class SessionStore(DBStore):
+     """
+     Implements cached, database backed sessions.
+@@ -15,10 +17,11 @@
+         super(SessionStore, self).__init__(session_key)
+ 
+     def load(self):
+-        data = cache.get(self.session_key, None)
++        data = cache.get(KEY_PREFIX + self.session_key, None)
+         if data is None:
+             data = super(SessionStore, self).load()
+-            cache.set(self.session_key, data, settings.SESSION_COOKIE_AGE)
++            cache.set(KEY_PREFIX + self.session_key, data, 
++                      settings.SESSION_COOKIE_AGE)
+         return data
+ 
+     def exists(self, session_key):
+@@ -26,11 +29,12 @@
+ 
+     def save(self, must_create=False):
+         super(SessionStore, self).save(must_create)
+-        cache.set(self.session_key, self._session, settings.SESSION_COOKIE_AGE)
++        cache.set(KEY_PREFIX + self.session_key, self._session, 
++                  settings.SESSION_COOKIE_AGE)
+ 
+     def delete(self, session_key=None):
+         super(SessionStore, self).delete(session_key)
+-        cache.delete(session_key or self.session_key)
++        cache.delete(KEY_PREFIX + (session_key or self.session_key))
+ 
+     def flush(self):
+         """
+Index: python-django-1.2.5/django/contrib/sessions/backends/cache.py
+===================================================================
+--- python-django-1.2.5.orig/django/contrib/sessions/backends/cache.py	2011-11-28 17:44:57.000000000 -0600
++++ python-django-1.2.5/django/contrib/sessions/backends/cache.py	2011-11-28 17:45:01.000000000 -0600
+@@ -1,6 +1,8 @@
+ from django.contrib.sessions.backends.base import SessionBase, CreateError
+ from django.core.cache import cache
+ 
++KEY_PREFIX = "django.contrib.sessions.cache"
++
+ class SessionStore(SessionBase):
+     """
+     A cache-based session store.
+@@ -10,7 +12,7 @@
+         super(SessionStore, self).__init__(session_key)
+ 
+     def load(self):
+-        session_data = self._cache.get(self.session_key)
++        session_data = self._cache.get(KEY_PREFIX + self.session_key)
+         if session_data is not None:
+             return session_data
+         self.create()
+@@ -37,13 +39,13 @@
+             func = self._cache.add
+         else:
+             func = self._cache.set
+-        result = func(self.session_key, self._get_session(no_load=must_create),
++        result = func(KEY_PREFIX + self.session_key, self._get_session(no_load=must_create),
+                 self.get_expiry_age())
+         if must_create and not result:
+             raise CreateError
+ 
+     def exists(self, session_key):
+-        if self._cache.has_key(session_key):
++        if self._cache.has_key(KEY_PREFIX + session_key):
+             return True
+         return False
+ 
+@@ -52,5 +54,5 @@
+             if self._session_key is None:
+                 return
+             session_key = self._session_key
+-        self._cache.delete(session_key)
++        self._cache.delete(KEY_PREFIX + session_key)
+ 
--- python-django-1.1.1.orig/debian/patches/lp1080204.diff
+++ python-django-1.1.1/debian/patches/lp1080204.diff
@@ -0,0 +1,35 @@
+Origin: backport, b774c5993cf80000966ae8f04c985116f98ee5ac
+Description: Isolated poisoned_http_host tests from 500 handlers
+Bug: https://code.djangoproject.com/ticket/19172
+Bug-Ubuntu: https://launchpad.net/bugs/1080204
+
+Index: python-django-1.1.1/django/contrib/auth/tests/views.py
+===================================================================
+--- python-django-1.1.1.orig/django/contrib/auth/tests/views.py	2012-11-19 16:34:14.000000000 -0600
++++ python-django-1.1.1/django/contrib/auth/tests/views.py	2012-11-19 16:34:14.000000000 -0600
+@@ -89,7 +89,11 @@
+                 HTTP_HOST='www.example:dr.frankenstein@evil.tld'
+             )
+         self.assertRaises(SuspiciousOperation, test_host_poisoning)
+-        self.assertEqual(len(mail.outbox), 0)
++        # Skip any 500 handler action (like sending more mail...)
++        # if ADMINS or MANAGERS is defined
++        if settings.ADMINS and len(settings.ADMINS) == 0 and \
++           settings.MANAGERS and len(settings.MANAGERS) == 0:
++            self.assertEqual(len(mail.outbox), 0)
+ 
+     def test_poisoned_http_host_admin_site(self):
+         "Poisoned HTTP_HOST headers can't be used for reset emails on admin views"
+@@ -99,7 +103,11 @@
+                 HTTP_HOST='www.example:dr.frankenstein@evil.tld'
+             )
+         self.assertRaises(SuspiciousOperation, test_host_poisoning)
+-        self.assertEqual(len(mail.outbox), 0)
++        # Skip any 500 handler action (like sending more mail...)
++        # if ADMINS or MANAGERS is defined
++        if settings.ADMINS and len(settings.ADMINS) == 0 and \
++           settings.MANAGERS and len(settings.MANAGERS) == 0:
++            self.assertEqual(len(mail.outbox), 0)
+ 
+     def _test_confirm_start(self):
+         # Start by creating the email
--- python-django-1.1.1.orig/debian/patches/02-embedded_code_copies.diff
+++ python-django-1.1.1/debian/patches/02-embedded_code_copies.diff
@@ -0,0 +1,3088 @@
+
+ Use the system version of the decimal module.
+
+   -- Chris Lamb <lamby@debian.org>  Tue, 01 Dec 2009 22:43:48 +0000
+
+--- a/django/utils/_decimal.py	2009-12-01 22:47:42.000000000 +0000
++++ b/django/utils/_decimal.py	2009-12-01 22:48:42.000000000 +0000
+@@ -1,3079 +1 @@
+-# Copyright (c) 2004 Python Software Foundation.
+-# All rights reserved.
+-
+-# Written by Eric Price <eprice at tjhsst.edu>
+-#    and Facundo Batista <facundo at taniquetil.com.ar>
+-#    and Raymond Hettinger <python at rcn.com>
+-#    and Aahz <aahz at pobox.com>
+-#    and Tim Peters
+-
+-# This module is currently Py2.3 compatible and should be kept that way
+-# unless a major compelling advantage arises.  IOW, 2.3 compatibility is
+-# strongly preferred, but not guaranteed.
+-
+-# Also, this module should be kept in sync with the latest updates of
+-# the IBM specification as it evolves.  Those updates will be treated
+-# as bug fixes (deviation from the spec is a compatibility, usability
+-# bug) and will be backported.  At this point the spec is stabilizing
+-# and the updates are becoming fewer, smaller, and less significant.
+-
+-"""
+-This is a Py2.3 implementation of decimal floating point arithmetic based on
+-the General Decimal Arithmetic Specification:
+-
+-    www2.hursley.ibm.com/decimal/decarith.html
+-
+-and IEEE standard 854-1987:
+-
+-    www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html
+-
+-Decimal floating point has finite precision with arbitrarily large bounds.
+-
+-The purpose of the module is to support arithmetic using familiar
+-"schoolhouse" rules and to avoid the some of tricky representation
+-issues associated with binary floating point.  The package is especially
+-useful for financial applications or for contexts where users have
+-expectations that are at odds with binary floating point (for instance,
+-in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead
+-of the expected Decimal("0.00") returned by decimal floating point).
+-
+-Here are some examples of using the decimal module:
+-
+->>> from decimal import *
+->>> setcontext(ExtendedContext)
+->>> Decimal(0)
+-Decimal("0")
+->>> Decimal("1")
+-Decimal("1")
+->>> Decimal("-.0123")
+-Decimal("-0.0123")
+->>> Decimal(123456)
+-Decimal("123456")
+->>> Decimal("123.45e12345678901234567890")
+-Decimal("1.2345E+12345678901234567892")
+->>> Decimal("1.33") + Decimal("1.27")
+-Decimal("2.60")
+->>> Decimal("12.34") + Decimal("3.87") - Decimal("18.41")
+-Decimal("-2.20")
+->>> dig = Decimal(1)
+->>> print dig / Decimal(3)
+-0.333333333
+->>> getcontext().prec = 18
+->>> print dig / Decimal(3)
+-0.333333333333333333
+->>> print dig.sqrt()
+-1
+->>> print Decimal(3).sqrt()
+-1.73205080756887729
+->>> print Decimal(3) ** 123
+-4.85192780976896427E+58
+->>> inf = Decimal(1) / Decimal(0)
+->>> print inf
+-Infinity
+->>> neginf = Decimal(-1) / Decimal(0)
+->>> print neginf
+--Infinity
+->>> print neginf + inf
+-NaN
+->>> print neginf * inf
+--Infinity
+->>> print dig / 0
+-Infinity
+->>> getcontext().traps[DivisionByZero] = 1
+->>> print dig / 0
+-Traceback (most recent call last):
+-  ...
+-  ...
+-  ...
+-DivisionByZero: x / 0
+->>> c = Context()
+->>> c.traps[InvalidOperation] = 0
+->>> print c.flags[InvalidOperation]
+-0
+->>> c.divide(Decimal(0), Decimal(0))
+-Decimal("NaN")
+->>> c.traps[InvalidOperation] = 1
+->>> print c.flags[InvalidOperation]
+-1
+->>> c.flags[InvalidOperation] = 0
+->>> print c.flags[InvalidOperation]
+-0
+->>> print c.divide(Decimal(0), Decimal(0))
+-Traceback (most recent call last):
+-  ...
+-  ...
+-  ...
+-InvalidOperation: 0 / 0
+->>> print c.flags[InvalidOperation]
+-1
+->>> c.flags[InvalidOperation] = 0
+->>> c.traps[InvalidOperation] = 0
+->>> print c.divide(Decimal(0), Decimal(0))
+-NaN
+->>> print c.flags[InvalidOperation]
+-1
+->>>
+-"""
+-
+-__all__ = [
+-    # Two major classes
+-    'Decimal', 'Context',
+-
+-    # Contexts
+-    'DefaultContext', 'BasicContext', 'ExtendedContext',
+-
+-    # Exceptions
+-    'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero',
+-    'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow',
+-
+-    # Constants for use in setting up contexts
+-    'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING',
+-    'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN',
+-
+-    # Functions for manipulating contexts
+-    'setcontext', 'getcontext'
+-]
+-
+-import copy as _copy
+-
+-#Rounding
+-ROUND_DOWN = 'ROUND_DOWN'
+-ROUND_HALF_UP = 'ROUND_HALF_UP'
+-ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
+-ROUND_CEILING = 'ROUND_CEILING'
+-ROUND_FLOOR = 'ROUND_FLOOR'
+-ROUND_UP = 'ROUND_UP'
+-ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
+-
+-#Rounding decision (not part of the public API)
+-NEVER_ROUND = 'NEVER_ROUND'    # Round in division (non-divmod), sqrt ONLY
+-ALWAYS_ROUND = 'ALWAYS_ROUND'  # Every operation rounds at end.
+-
+-#Errors
+-
+-class DecimalException(ArithmeticError):
+-    """Base exception class.
+-
+-    Used exceptions derive from this.
+-    If an exception derives from another exception besides this (such as
+-    Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
+-    called if the others are present.  This isn't actually used for
+-    anything, though.
+-
+-    handle  -- Called when context._raise_error is called and the
+-               trap_enabler is set.  First argument is self, second is the
+-               context.  More arguments can be given, those being after
+-               the explanation in _raise_error (For example,
+-               context._raise_error(NewError, '(-x)!', self._sign) would
+-               call NewError().handle(context, self._sign).)
+-
+-    To define a new exception, it should be sufficient to have it derive
+-    from DecimalException.
+-    """
+-    def handle(self, context, *args):
+-        pass
+-
+-
+-class Clamped(DecimalException):
+-    """Exponent of a 0 changed to fit bounds.
+-
+-    This occurs and signals clamped if the exponent of a result has been
+-    altered in order to fit the constraints of a specific concrete
+-    representation. This may occur when the exponent of a zero result would
+-    be outside the bounds of a representation, or  when a large normal
+-    number would have an encoded exponent that cannot be represented. In
+-    this latter case, the exponent is reduced to fit and the corresponding
+-    number of zero digits are appended to the coefficient ("fold-down").
+-    """
+-
+-
+-class InvalidOperation(DecimalException):
+-    """An invalid operation was performed.
+-
+-    Various bad things cause this:
+-
+-    Something creates a signaling NaN
+-    -INF + INF
+-     0 * (+-)INF
+-     (+-)INF / (+-)INF
+-    x % 0
+-    (+-)INF % x
+-    x._rescale( non-integer )
+-    sqrt(-x) , x > 0
+-    0 ** 0
+-    x ** (non-integer)
+-    x ** (+-)INF
+-    An operand is invalid
+-    """
+-    def handle(self, context, *args):
+-        if args:
+-            if args[0] == 1: #sNaN, must drop 's' but keep diagnostics
+-                return Decimal( (args[1]._sign, args[1]._int, 'n') )
+-        return NaN
+-
+-class ConversionSyntax(InvalidOperation):
+-    """Trying to convert badly formed string.
+-
+-    This occurs and signals invalid-operation if an string is being
+-    converted to a number and it does not conform to the numeric string
+-    syntax. The result is [0,qNaN].
+-    """
+-
+-    def handle(self, context, *args):
+-        return (0, (0,), 'n') #Passed to something which uses a tuple.
+-
+-class DivisionByZero(DecimalException, ZeroDivisionError):
+-    """Division by 0.
+-
+-    This occurs and signals division-by-zero if division of a finite number
+-    by zero was attempted (during a divide-integer or divide operation, or a
+-    power operation with negative right-hand operand), and the dividend was
+-    not zero.
+-
+-    The result of the operation is [sign,inf], where sign is the exclusive
+-    or of the signs of the operands for divide, or is 1 for an odd power of
+-    -0, for power.
+-    """
+-
+-    def handle(self, context, sign, double = None, *args):
+-        if double is not None:
+-            return (Infsign[sign],)*2
+-        return Infsign[sign]
+-
+-class DivisionImpossible(InvalidOperation):
+-    """Cannot perform the division adequately.
+-
+-    This occurs and signals invalid-operation if the integer result of a
+-    divide-integer or remainder operation had too many digits (would be
+-    longer than precision). The result is [0,qNaN].
+-    """
+-
+-    def handle(self, context, *args):
+-        return (NaN, NaN)
+-
+-class DivisionUndefined(InvalidOperation, ZeroDivisionError):
+-    """Undefined result of division.
+-
+-    This occurs and signals invalid-operation if division by zero was
+-    attempted (during a divide-integer, divide, or remainder operation), and
+-    the dividend is also zero. The result is [0,qNaN].
+-    """
+-
+-    def handle(self, context, tup=None, *args):
+-        if tup is not None:
+-            return (NaN, NaN) #for 0 %0, 0 // 0
+-        return NaN
+-
+-class Inexact(DecimalException):
+-    """Had to round, losing information.
+-
+-    This occurs and signals inexact whenever the result of an operation is
+-    not exact (that is, it needed to be rounded and any discarded digits
+-    were non-zero), or if an overflow or underflow condition occurs. The
+-    result in all cases is unchanged.
+-
+-    The inexact signal may be tested (or trapped) to determine if a given
+-    operation (or sequence of operations) was inexact.
+-    """
+-    pass
+-
+-class InvalidContext(InvalidOperation):
+-    """Invalid context.  Unknown rounding, for example.
+-
+-    This occurs and signals invalid-operation if an invalid context was
+-    detected during an operation. This can occur if contexts are not checked
+-    on creation and either the precision exceeds the capability of the
+-    underlying concrete representation or an unknown or unsupported rounding
+-    was specified. These aspects of the context need only be checked when
+-    the values are required to be used. The result is [0,qNaN].
+-    """
+-
+-    def handle(self, context, *args):
+-        return NaN
+-
+-class Rounded(DecimalException):
+-    """Number got rounded (not  necessarily changed during rounding).
+-
+-    This occurs and signals rounded whenever the result of an operation is
+-    rounded (that is, some zero or non-zero digits were discarded from the
+-    coefficient), or if an overflow or underflow condition occurs. The
+-    result in all cases is unchanged.
+-
+-    The rounded signal may be tested (or trapped) to determine if a given
+-    operation (or sequence of operations) caused a loss of precision.
+-    """
+-    pass
+-
+-class Subnormal(DecimalException):
+-    """Exponent < Emin before rounding.
+-
+-    This occurs and signals subnormal whenever the result of a conversion or
+-    operation is subnormal (that is, its adjusted exponent is less than
+-    Emin, before any rounding). The result in all cases is unchanged.
+-
+-    The subnormal signal may be tested (or trapped) to determine if a given
+-    or operation (or sequence of operations) yielded a subnormal result.
+-    """
+-    pass
+-
+-class Overflow(Inexact, Rounded):
+-    """Numerical overflow.
+-
+-    This occurs and signals overflow if the adjusted exponent of a result
+-    (from a conversion or from an operation that is not an attempt to divide
+-    by zero), after rounding, would be greater than the largest value that
+-    can be handled by the implementation (the value Emax).
+-
+-    The result depends on the rounding mode:
+-
+-    For round-half-up and round-half-even (and for round-half-down and
+-    round-up, if implemented), the result of the operation is [sign,inf],
+-    where sign is the sign of the intermediate result. For round-down, the
+-    result is the largest finite number that can be represented in the
+-    current precision, with the sign of the intermediate result. For
+-    round-ceiling, the result is the same as for round-down if the sign of
+-    the intermediate result is 1, or is [0,inf] otherwise. For round-floor,
+-    the result is the same as for round-down if the sign of the intermediate
+-    result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded
+-    will also be raised.
+-   """
+-
+-    def handle(self, context, sign, *args):
+-        if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN,
+-                                     ROUND_HALF_DOWN, ROUND_UP):
+-            return Infsign[sign]
+-        if sign == 0:
+-            if context.rounding == ROUND_CEILING:
+-                return Infsign[sign]
+-            return Decimal((sign, (9,)*context.prec,
+-                            context.Emax-context.prec+1))
+-        if sign == 1:
+-            if context.rounding == ROUND_FLOOR:
+-                return Infsign[sign]
+-            return Decimal( (sign, (9,)*context.prec,
+-                             context.Emax-context.prec+1))
+-
+-
+-class Underflow(Inexact, Rounded, Subnormal):
+-    """Numerical underflow with result rounded to 0.
+-
+-    This occurs and signals underflow if a result is inexact and the
+-    adjusted exponent of the result would be smaller (more negative) than
+-    the smallest value that can be handled by the implementation (the value
+-    Emin). That is, the result is both inexact and subnormal.
+-
+-    The result after an underflow will be a subnormal number rounded, if
+-    necessary, so that its exponent is not less than Etiny. This may result
+-    in 0 with the sign of the intermediate result and an exponent of Etiny.
+-
+-    In all cases, Inexact, Rounded, and Subnormal will also be raised.
+-    """
+-
+-# List of public traps and flags
+-_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
+-           Underflow, InvalidOperation, Subnormal]
+-
+-# Map conditions (per the spec) to signals
+-_condition_map = {ConversionSyntax:InvalidOperation,
+-                  DivisionImpossible:InvalidOperation,
+-                  DivisionUndefined:InvalidOperation,
+-                  InvalidContext:InvalidOperation}
+-
+-##### Context Functions #######################################
+-
+-# The getcontext() and setcontext() function manage access to a thread-local
+-# current context.  Py2.4 offers direct support for thread locals.  If that
+-# is not available, use threading.currentThread() which is slower but will
+-# work for older Pythons.  If threads are not part of the build, create a
+-# mock threading object with threading.local() returning the module namespace.
+-
+-try:
+-    import threading
+-except ImportError:
+-    # Python was compiled without threads; create a mock object instead
+-    import sys
+-    class MockThreading:
+-        def local(self, sys=sys):
+-            return sys.modules[__name__]
+-    threading = MockThreading()
+-    del sys, MockThreading
+-
+-try:
+-    threading.local
+-
+-except AttributeError:
+-
+-    #To fix reloading, force it to create a new context
+-    #Old contexts have different exceptions in their dicts, making problems.
+-    if hasattr(threading.currentThread(), '__decimal_context__'):
+-        del threading.currentThread().__decimal_context__
+-
+-    def setcontext(context):
+-        """Set this thread's context to context."""
+-        if context in (DefaultContext, BasicContext, ExtendedContext):
+-            context = context.copy()
+-            context.clear_flags()
+-        threading.currentThread().__decimal_context__ = context
+-
+-    def getcontext():
+-        """Returns this thread's context.
+-
+-        If this thread does not yet have a context, returns
+-        a new context and sets this thread's context.
+-        New contexts are copies of DefaultContext.
+-        """
+-        try:
+-            return threading.currentThread().__decimal_context__
+-        except AttributeError:
+-            context = Context()
+-            threading.currentThread().__decimal_context__ = context
+-            return context
+-
+-else:
+-
+-    local = threading.local()
+-    if hasattr(local, '__decimal_context__'):
+-        del local.__decimal_context__
+-
+-    def getcontext(_local=local):
+-        """Returns this thread's context.
+-
+-        If this thread does not yet have a context, returns
+-        a new context and sets this thread's context.
+-        New contexts are copies of DefaultContext.
+-        """
+-        try:
+-            return _local.__decimal_context__
+-        except AttributeError:
+-            context = Context()
+-            _local.__decimal_context__ = context
+-            return context
+-
+-    def setcontext(context, _local=local):
+-        """Set this thread's context to context."""
+-        if context in (DefaultContext, BasicContext, ExtendedContext):
+-            context = context.copy()
+-            context.clear_flags()
+-        _local.__decimal_context__ = context
+-
+-    del threading, local        # Don't contaminate the namespace
+-
+-
+-##### Decimal class ###########################################
+-
+-class Decimal(object):
+-    """Floating point class for decimal arithmetic."""
+-
+-    __slots__ = ('_exp','_int','_sign', '_is_special')
+-    # Generally, the value of the Decimal instance is given by
+-    #  (-1)**_sign * _int * 10**_exp
+-    # Special values are signified by _is_special == True
+-
+-    # We're immutable, so use __new__ not __init__
+-    def __new__(cls, value="0", context=None):
+-        """Create a decimal point instance.
+-
+-        >>> Decimal('3.14')              # string input
+-        Decimal("3.14")
+-        >>> Decimal((0, (3, 1, 4), -2))  # tuple input (sign, digit_tuple, exponent)
+-        Decimal("3.14")
+-        >>> Decimal(314)                 # int or long
+-        Decimal("314")
+-        >>> Decimal(Decimal(314))        # another decimal instance
+-        Decimal("314")
+-        """
+-
+-        self = object.__new__(cls)
+-        self._is_special = False
+-
+-        # From an internal working value
+-        if isinstance(value, _WorkRep):
+-            self._sign = value.sign
+-            self._int = tuple(map(int, str(value.int)))
+-            self._exp = int(value.exp)
+-            return self
+-
+-        # From another decimal
+-        if isinstance(value, Decimal):
+-            self._exp  = value._exp
+-            self._sign = value._sign
+-            self._int  = value._int
+-            self._is_special  = value._is_special
+-            return self
+-
+-        # From an integer
+-        if isinstance(value, (int,long)):
+-            if value >= 0:
+-                self._sign = 0
+-            else:
+-                self._sign = 1
+-            self._exp = 0
+-            self._int = tuple(map(int, str(abs(value))))
+-            return self
+-
+-        # tuple/list conversion (possibly from as_tuple())
+-        if isinstance(value, (list,tuple)):
+-            if len(value) != 3:
+-                raise ValueError, 'Invalid arguments'
+-            if value[0] not in (0,1):
+-                raise ValueError, 'Invalid sign'
+-            for digit in value[1]:
+-                if not isinstance(digit, (int,long)) or digit < 0:
+-                    raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
+-
+-            self._sign = value[0]
+-            self._int  = tuple(value[1])
+-            if value[2] in ('F','n','N'):
+-                self._exp = value[2]
+-                self._is_special = True
+-            else:
+-                self._exp  = int(value[2])
+-            return self
+-
+-        if isinstance(value, float):
+-            raise TypeError("Cannot convert float to Decimal.  " +
+-                            "First convert the float to a string")
+-
+-        # Other argument types may require the context during interpretation
+-        if context is None:
+-            context = getcontext()
+-
+-        # From a string
+-        # REs insist on real strings, so we can too.
+-        if isinstance(value, basestring):
+-            if _isinfinity(value):
+-                self._exp = 'F'
+-                self._int = (0,)
+-                self._is_special = True
+-                if _isinfinity(value) == 1:
+-                    self._sign = 0
+-                else:
+-                    self._sign = 1
+-                return self
+-            if _isnan(value):
+-                sig, sign, diag = _isnan(value)
+-                self._is_special = True
+-                if len(diag) > context.prec: #Diagnostic info too long
+-                    self._sign, self._int, self._exp = \
+-                                context._raise_error(ConversionSyntax)
+-                    return self
+-                if sig == 1:
+-                    self._exp = 'n' #qNaN
+-                else: #sig == 2
+-                    self._exp = 'N' #sNaN
+-                self._sign = sign
+-                self._int = tuple(map(int, diag)) #Diagnostic info
+-                return self
+-            try:
+-                self._sign, self._int, self._exp = _string2exact(value)
+-            except ValueError:
+-                self._is_special = True
+-                self._sign, self._int, self._exp = context._raise_error(ConversionSyntax)
+-            return self
+-
+-        raise TypeError("Cannot convert %r to Decimal" % value)
+-
+-    def _isnan(self):
+-        """Returns whether the number is not actually one.
+-
+-        0 if a number
+-        1 if NaN
+-        2 if sNaN
+-        """
+-        if self._is_special:
+-            exp = self._exp
+-            if exp == 'n':
+-                return 1
+-            elif exp == 'N':
+-                return 2
+-        return 0
+-
+-    def _isinfinity(self):
+-        """Returns whether the number is infinite
+-
+-        0 if finite or not a number
+-        1 if +INF
+-        -1 if -INF
+-        """
+-        if self._exp == 'F':
+-            if self._sign:
+-                return -1
+-            return 1
+-        return 0
+-
+-    def _check_nans(self, other = None, context=None):
+-        """Returns whether the number is not actually one.
+-
+-        if self, other are sNaN, signal
+-        if self, other are NaN return nan
+-        return 0
+-
+-        Done before operations.
+-        """
+-
+-        self_is_nan = self._isnan()
+-        if other is None:
+-            other_is_nan = False
+-        else:
+-            other_is_nan = other._isnan()
+-
+-        if self_is_nan or other_is_nan:
+-            if context is None:
+-                context = getcontext()
+-
+-            if self_is_nan == 2:
+-                return context._raise_error(InvalidOperation, 'sNaN',
+-                                        1, self)
+-            if other_is_nan == 2:
+-                return context._raise_error(InvalidOperation, 'sNaN',
+-                                        1, other)
+-            if self_is_nan:
+-                return self
+-
+-            return other
+-        return 0
+-
+-    def __nonzero__(self):
+-        """Is the number non-zero?
+-
+-        0 if self == 0
+-        1 if self != 0
+-        """
+-        if self._is_special:
+-            return 1
+-        return sum(self._int) != 0
+-
+-    def __cmp__(self, other, context=None):
+-        other = _convert_other(other)
+-        if other is NotImplemented:
+-            return other
+-
+-        if self._is_special or other._is_special:
+-            ans = self._check_nans(other, context)
+-            if ans:
+-                return 1 # Comparison involving NaN's always reports self > other
+-
+-            # INF = INF
+-            return cmp(self._isinfinity(), other._isinfinity())
+-
+-        if not self and not other:
+-            return 0 #If both 0, sign comparison isn't certain.
+-
+-        #If different signs, neg one is less
+-        if other._sign < self._sign:
+-            return -1
+-        if self._sign < other._sign:
+-            return 1
+-
+-        self_adjusted = self.adjusted()
+-        other_adjusted = other.adjusted()
+-        if self_adjusted == other_adjusted and \
+-           self._int + (0,)*(self._exp - other._exp) == \
+-           other._int + (0,)*(other._exp - self._exp):
+-            return 0 #equal, except in precision. ([0]*(-x) = [])
+-        elif self_adjusted > other_adjusted and self._int[0] != 0:
+-            return (-1)**self._sign
+-        elif self_adjusted < other_adjusted and other._int[0] != 0:
+-            return -((-1)**self._sign)
+-
+-        # Need to round, so make sure we have a valid context
+-        if context is None:
+-            context = getcontext()
+-
+-        context = context._shallow_copy()
+-        rounding = context._set_rounding(ROUND_UP) #round away from 0
+-
+-        flags = context._ignore_all_flags()
+-        res = self.__sub__(other, context=context)
+-
+-        context._regard_flags(*flags)
+-
+-        context.rounding = rounding
+-
+-        if not res:
+-            return 0
+-        elif res._sign:
+-            return -1
+-        return 1
+-
+-    def __eq__(self, other):
+-        if not isinstance(other, (Decimal, int, long)):
+-            return NotImplemented
+-        return self.__cmp__(other) == 0
+-
+-    def __ne__(self, other):
+-        if not isinstance(other, (Decimal, int, long)):
+-            return NotImplemented
+-        return self.__cmp__(other) != 0
+-
+-    def compare(self, other, context=None):
+-        """Compares one to another.
+-
+-        -1 => a < b
+-        0  => a = b
+-        1  => a > b
+-        NaN => one is NaN
+-        Like __cmp__, but returns Decimal instances.
+-        """
+-        other = _convert_other(other)
+-        if other is NotImplemented:
+-            return other
+-
+-        #compare(NaN, NaN) = NaN
+-        if (self._is_special or other and other._is_special):
+-            ans = self._check_nans(other, context)
+-            if ans:
+-                return ans
+-
+-        return Decimal(self.__cmp__(other, context))
+-
+-    def __hash__(self):
+-        """x.__hash__() <==> hash(x)"""
+-        # Decimal integers must hash the same as the ints
+-        # Non-integer decimals are normalized and hashed as strings
+-        # Normalization assures that hast(100E-1) == hash(10)
+-        if self._is_special:
+-            if self._isnan():
+-                raise TypeError('Cannot hash a NaN value.')
+-            return hash(str(self))
+-        i = int(self)
+-        if self == Decimal(i):
+-            return hash(i)
+-        assert self.__nonzero__()   # '-0' handled by integer case
+-        return hash(str(self.normalize()))
+-
+-    def as_tuple(self):
+-        """Represents the number as a triple tuple.
+-
+-        To show the internals exactly as they are.
+-        """
+-        return (self._sign, self._int, self._exp)
+-
+-    def __repr__(self):
+-        """Represents the number as an instance of Decimal."""
+-        # Invariant:  eval(repr(d)) == d
+-        return 'Decimal("%s")' % str(self)
+-
+-    def __str__(self, eng = 0, context=None):
+-        """Return string representation of the number in scientific notation.
+-
+-        Captures all of the information in the underlying representation.
+-        """
+-
+-        if self._is_special:
+-            if self._isnan():
+-                minus = '-'*self._sign
+-                if self._int == (0,):
+-                    info = ''
+-                else:
+-                    info = ''.join(map(str, self._int))
+-                if self._isnan() == 2:
+-                    return minus + 'sNaN' + info
+-                return minus + 'NaN' + info
+-            if self._isinfinity():
+-                minus = '-'*self._sign
+-                return minus + 'Infinity'
+-
+-        if context is None:
+-            context = getcontext()
+-
+-        tmp = map(str, self._int)
+-        numdigits = len(self._int)
+-        leftdigits = self._exp + numdigits
+-        if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
+-            if self._exp < 0 and self._exp >= -6: #short, no need for e/E
+-                s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
+-                return s
+-            #exp is closest mult. of 3 >= self._exp
+-            exp = ((self._exp - 1)// 3 + 1) * 3
+-            if exp != self._exp:
+-                s = '0.'+'0'*(exp - self._exp)
+-            else:
+-                s = '0'
+-            if exp != 0:
+-                if context.capitals:
+-                    s += 'E'
+-                else:
+-                    s += 'e'
+-                if exp > 0:
+-                    s += '+' #0.0e+3, not 0.0e3
+-                s += str(exp)
+-            s = '-'*self._sign + s
+-            return s
+-        if eng:
+-            dotplace = (leftdigits-1)%3+1
+-            adjexp = leftdigits -1 - (leftdigits-1)%3
+-        else:
+-            adjexp = leftdigits-1
+-            dotplace = 1
+-        if self._exp == 0:
+-            pass
+-        elif self._exp < 0 and adjexp >= 0:
+-            tmp.insert(leftdigits, '.')
+-        elif self._exp < 0 and adjexp >= -6:
+-            tmp[0:0] = ['0'] * int(-leftdigits)
+-            tmp.insert(0, '0.')
+-        else:
+-            if numdigits > dotplace:
+-                tmp.insert(dotplace, '.')
+-            elif numdigits < dotplace:
+-                tmp.extend(['0']*(dotplace-numdigits))
+-            if adjexp:
+-                if not context.capitals:
+-                    tmp.append('e')
+-                else:
+-                    tmp.append('E')
+-                    if adjexp > 0:
+-                        tmp.append('+')
+-                tmp.append(str(adjexp))
+-        if eng:
+-            while tmp[0:1] == ['0']:
+-                tmp[0:1] = []
+-            if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
+-                tmp[0:0] = ['0']
+-        if self._sign:
+-            tmp.insert(0, '-')
+-
+-        return ''.join(tmp)
+-
+-    def to_eng_string(self, context=None):
+-        """Convert to engineering-type string.
+-
+-        Engineering notation has an exponent which is a multiple of 3, so there
+-        are up to 3 digits left of the decimal place.
+-
+-        Same rules for when in exponential and when as a value as in __str__.
+-        """
+-        return self.__str__(eng=1, context=context)
+-
+-    def __neg__(self, context=None):
+-        """Returns a copy with the sign switched.
+-
+-        Rounds, if it has reason.
+-        """
+-        if self._is_special:
+-            ans = self._check_nans(context=context)
+-            if ans:
+-                return ans
+-
+-        if not self:
+-            # -Decimal('0') is Decimal('0'), not Decimal('-0')
+-            sign = 0
+-        elif self._sign:
+-            sign = 0
+-        else:
+-            sign = 1
+-
+-        if context is None:
+-            context = getcontext()
+-        if context._rounding_decision == ALWAYS_ROUND:
+-            return Decimal((sign, self._int, self._exp))._fix(context)
+-        return Decimal( (sign, self._int, self._exp))
+-
+-    def __pos__(self, context=None):
+-        """Returns a copy, unless it is a sNaN.
+-
+-        Rounds the number (if more then precision digits)
+-        """
+-        if self._is_special:
+-            ans = self._check_nans(context=context)
+-            if ans:
+-                return ans
+-
+-        sign = self._sign
+-        if not self:
+-            # + (-0) = 0
+-            sign = 0
+-
+-        if context is None:
+-            context = getcontext()
+-
+-        if context._rounding_decision == ALWAYS_ROUND:
+-            ans = self._fix(context)
+-        else:
+-            ans = Decimal(self)
+-        ans._sign = sign
+-        return ans
+-
+-    def __abs__(self, round=1, context=None):
+-        """Returns the absolute value of self.
+-
+-        If the second argument is 0, do not round.
+-        """
+-        if self._is_special:
+-            ans = self._check_nans(context=context)
+-            if ans:
+-                return ans
+-
+-        if not round:
+-            if context is None:
+-                context = getcontext()
+-            context = context._shallow_copy()
+-            context._set_rounding_decision(NEVER_ROUND)
+-
+-        if self._sign:
+-            ans = self.__neg__(context=context)
+-        else:
+-            ans = self.__pos__(context=context)
+-
+-        return ans
+-
+-    def __add__(self, other, context=None):
+-        """Returns self + other.
+-
+-        -INF + INF (or the reverse) cause InvalidOperation errors.
+-        """
+-        other = _convert_other(other)
+-        if other is NotImplemented:
+-            return other
+-
+-        if context is None:
+-            context = getcontext()
+-
+-        if self._is_special or other._is_special:
+-            ans = self._check_nans(other, context)
+-            if ans:
+-                return ans
+-
+-            if self._isinfinity():
+-                #If both INF, same sign => same as both, opposite => error.
+-                if self._sign != other._sign and other._isinfinity():
+-                    return context._raise_error(InvalidOperation, '-INF + INF')
+-                return Decimal(self)
+-            if other._isinfinity():
+-                return Decimal(other)  #Can't both be infinity here
+-
+-        shouldround = context._rounding_decision == ALWAYS_ROUND
+-
+-        exp = min(self._exp, other._exp)
+-        negativezero = 0
+-        if context.rounding == ROUND_FLOOR and self._sign != other._sign:
+-            #If the answer is 0, the sign should be negative, in this case.
+-            negativezero = 1
+-
+-        if not self and not other:
+-            sign = min(self._sign, other._sign)
+-            if negativezero:
+-                sign = 1
+-            return Decimal( (sign, (0,), exp))
+-        if not self:
+-            exp = max(exp, other._exp - context.prec-1)
+-            ans = other._rescale(exp, watchexp=0, context=context)
+-            if shouldround:
+-                ans = ans._fix(context)
+-            return ans
+-        if not other:
+-            exp = max(exp, self._exp - context.prec-1)
+-            ans = self._rescale(exp, watchexp=0, context=context)
+-            if shouldround:
+-                ans = ans._fix(context)
+-            return ans
+-
+-        op1 = _WorkRep(self)
+-        op2 = _WorkRep(other)
+-        op1, op2 = _normalize(op1, op2, shouldround, context.prec)
+-
+-        result = _WorkRep()
+-        if op1.sign != op2.sign:
+-            # Equal and opposite
+-            if op1.int == op2.int:
+-                if exp < context.Etiny():
+-                    exp = context.Etiny()
+-                    context._raise_error(Clamped)
+-                return Decimal((negativezero, (0,), exp))
+-            if op1.int < op2.int:
+-                op1, op2 = op2, op1
+-                #OK, now abs(op1) > abs(op2)
+-            if op1.sign == 1:
+-                result.sign = 1
+-                op1.sign, op2.sign = op2.sign, op1.sign
+-            else:
+-                result.sign = 0
+-                #So we know the sign, and op1 > 0.
+-        elif op1.sign == 1:
+-            result.sign = 1
+-            op1.sign, op2.sign = (0, 0)
+-        else:
+-            result.sign = 0
+-        #Now, op1 > abs(op2) > 0
+-
+-        if op2.sign == 0:
+-            result.int = op1.int + op2.int
+-        else:
+-            result.int = op1.int - op2.int
+-
+-        result.exp = op1.exp
+-        ans = Decimal(result)
+-        if shouldround:
+-            ans = ans._fix(context)
+-        return ans
+-
+-    __radd__ = __add__
+-
+-    def __sub__(self, other, context=None):
+-        """Return self + (-other)"""
+-        other = _convert_other(other)
+-        if other is NotImplemented:
+-            return other
+-
+-        if self._is_special or other._is_special:
+-            ans = self._check_nans(other, context=context)
+-            if ans:
+-                return ans
+-
+-        # -Decimal(0) = Decimal(0), which we don't want since
+-        # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
+-        # so we change the sign directly to a copy
+-        tmp = Decimal(other)
+-        tmp._sign = 1-tmp._sign
+-
+-        return self.__add__(tmp, context=context)
+-
+-    def __rsub__(self, other, context=None):
+-        """Return other + (-self)"""
+-        other = _convert_other(other)
+-        if other is NotImplemented:
+-            return other
+-
+-        tmp = Decimal(self)
+-        tmp._sign = 1 - tmp._sign
+-        return other.__add__(tmp, context=context)
+-
+-    def _increment(self, round=1, context=None):
+-        """Special case of add, adding 1eExponent
+-
+-        Since it is common, (rounding, for example) this adds
+-        (sign)*one E self._exp to the number more efficiently than add.
+-
+-        For example:
+-        Decimal('5.624e10')._increment() == Decimal('5.625e10')
+-        """
+-        if self._is_special:
+-            ans = self._check_nans(context=context)
+-            if ans:
+-                return ans
+-
+-            return Decimal(self) # Must be infinite, and incrementing makes no difference
+-
+-        L = list(self._int)
+-        L[-1] += 1
+-        spot = len(L)-1
+-        while L[spot] == 10:
+-            L[spot] = 0
+-            if spot == 0:
+-                L[0:0] = [1]
+-                break
+-            L[spot-1] += 1
+-            spot -= 1
+-        ans = Decimal((self._sign, L, self._exp))
+-
+-        if context is None:
+-            context = getcontext()
+-        if round and context._rounding_decision == ALWAYS_ROUND:
+-            ans = ans._fix(context)
+-        return ans
+-
+-    def __mul__(self, other, context=None):
+-        """Return self * other.
+-
+-        (+-) INF * 0 (or its reverse) raise InvalidOperation.
+-        """
+-        other = _convert_other(other)
+-        if other is NotImplemented:
+-            return other
+-
+-        if context is None:
+-            context = getcontext()
+-
+-        resultsign = self._sign ^ other._sign
+-
+-        if self._is_special or other._is_special:
+-            ans = self._check_nans(other, context)
+-            if ans:
+-                return ans
+-
+-            if self._isinfinity():
+-                if not other:
+-                    return context._raise_error(InvalidOperation, '(+-)INF * 0')
+-                return Infsign[resultsign]
+-
+-            if other._isinfinity():
+-                if not self:
+-                    return context._raise_error(InvalidOperation, '0 * (+-)INF')
+-                return Infsign[resultsign]
+-
+-        resultexp = self._exp + other._exp
+-        shouldround = context._rounding_decision == ALWAYS_ROUND
+-
+-        # Special case for multiplying by zero
+-        if not self or not other:
+-            ans = Decimal((resultsign, (0,), resultexp))
+-            if shouldround:
+-                #Fixing in case the exponent is out of bounds
+-                ans = ans._fix(context)
+-            return ans
+-
+-        # Special case for multiplying by power of 10
+-        if self._int == (1,):
+-            ans = Decimal((resultsign, other._int, resultexp))
+-            if shouldround:
+-                ans = ans._fix(context)
+-            return ans
+-        if other._int == (1,):
+-            ans = Decimal((resultsign, self._int, resultexp))
+-            if shouldround:
+-                ans = ans._fix(context)
+-            return ans
+-
+-        op1 = _WorkRep(self)
+-        op2 = _WorkRep(other)
+-
+-        ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp))
+-        if shouldround:
+-            ans = ans._fix(context)
+-
+-        return ans
+-    __rmul__ = __mul__
+-
+-    def __div__(self, other, context=None):
+-        """Return self / other."""
+-        return self._divide(other, context=context)
+-    __truediv__ = __div__
+-
+-    def _divide(self, other, divmod = 0, context=None):
+-        """Return a / b, to context.prec precision.
+-
+-        divmod:
+-        0 => true division
+-        1 => (a //b, a%b)
+-        2 => a //b
+-        3 => a%b
+-
+-        Actually, if divmod is 2 or 3 a tuple is returned, but errors for
+-        computing the other value are not raised.
+-        """
+-        other = _convert_other(other)
+-        if other is NotImplemented:
+-            if divmod in (0, 1):
+-                return NotImplemented
+-            return (NotImplemented, NotImplemented)
+-
+-        if context is None:
+-            context = getcontext()
+-
+-        sign = self._sign ^ other._sign
+-
+-        if self._is_special or other._is_special:
+-            ans = self._check_nans(other, context)
+-            if ans:
+-                if divmod:
+-                    return (ans, ans)
+-                return ans
+-
+-            if self._isinfinity() and other._isinfinity():
+-                if divmod:
+-                    return (context._raise_error(InvalidOperation,
+-                                            '(+-)INF // (+-)INF'),
+-                            context._raise_error(InvalidOperation,
+-                                            '(+-)INF % (+-)INF'))
+-                return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
+-
+-            if self._isinfinity():
+-                if divmod == 1:
+-                    return (Infsign[sign],
+-                            context._raise_error(InvalidOperation, 'INF % x'))
+-                elif divmod == 2:
+-                    return (Infsign[sign], NaN)
+-                elif divmod == 3:
+-                    return (Infsign[sign],
+-                            context._raise_error(InvalidOperation, 'INF % x'))
+-                return Infsign[sign]
+-
+-            if other._isinfinity():
+-                if divmod:
+-                    return (Decimal((sign, (0,), 0)), Decimal(self))
+-                context._raise_error(Clamped, 'Division by infinity')
+-                return Decimal((sign, (0,), context.Etiny()))
+-
+-        # Special cases for zeroes
+-        if not self and not other:
+-            if divmod:
+-                return context._raise_error(DivisionUndefined, '0 / 0', 1)
+-            return context._raise_error(DivisionUndefined, '0 / 0')
+-
+-        if not self:
+-            if divmod:
+-                otherside = Decimal(self)
+-                otherside._exp = min(self._exp, other._exp)
+-                return (Decimal((sign, (0,), 0)),  otherside)
+-            exp = self._exp - other._exp
+-            if exp < context.Etiny():
+-                exp = context.Etiny()
+-                context._raise_error(Clamped, '0e-x / y')
+-            if exp > context.Emax:
+-                exp = context.Emax
+-                context._raise_error(Clamped, '0e+x / y')
+-            return Decimal( (sign, (0,), exp) )
+-
+-        if not other:
+-            if divmod:
+-                return context._raise_error(DivisionByZero, 'divmod(x,0)',
+-                                           sign, 1)
+-            return context._raise_error(DivisionByZero, 'x / 0', sign)
+-
+-        #OK, so neither = 0, INF or NaN
+-
+-        shouldround = context._rounding_decision == ALWAYS_ROUND
+-
+-        #If we're dividing into ints, and self < other, stop.
+-        #self.__abs__(0) does not round.
+-        if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
+-
+-            if divmod == 1 or divmod == 3:
+-                exp = min(self._exp, other._exp)
+-                ans2 = self._rescale(exp, context=context, watchexp=0)
+-                if shouldround:
+-                    ans2 = ans2._fix(context)
+-                return (Decimal( (sign, (0,), 0) ),
+-                        ans2)
+-
+-            elif divmod == 2:
+-                #Don't round the mod part, if we don't need it.
+-                return (Decimal( (sign, (0,), 0) ), Decimal(self))
+-
+-        op1 = _WorkRep(self)
+-        op2 = _WorkRep(other)
+-        op1, op2, adjust = _adjust_coefficients(op1, op2)
+-        res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) )
+-        if divmod and res.exp > context.prec + 1:
+-            return context._raise_error(DivisionImpossible)
+-
+-        prec_limit = 10 ** context.prec
+-        while 1:
+-            while op2.int <= op1.int:
+-                res.int += 1
+-                op1.int -= op2.int
+-            if res.exp == 0 and divmod:
+-                if res.int >= prec_limit and shouldround:
+-                    return context._raise_error(DivisionImpossible)
+-                otherside = Decimal(op1)
+-                frozen = context._ignore_all_flags()
+-
+-                exp = min(self._exp, other._exp)
+-                otherside = otherside._rescale(exp, context=context, watchexp=0)
+-                context._regard_flags(*frozen)
+-                if shouldround:
+-                    otherside = otherside._fix(context)
+-                return (Decimal(res), otherside)
+-
+-            if op1.int == 0 and adjust >= 0 and not divmod:
+-                break
+-            if res.int >= prec_limit and shouldround:
+-                if divmod:
+-                    return context._raise_error(DivisionImpossible)
+-                shouldround=1
+-                # Really, the answer is a bit higher, so adding a one to
+-                # the end will make sure the rounding is right.
+-                if op1.int != 0:
+-                    res.int *= 10
+-                    res.int += 1
+-                    res.exp -= 1
+-
+-                break
+-            res.int *= 10
+-            res.exp -= 1
+-            adjust += 1
+-            op1.int *= 10
+-            op1.exp -= 1
+-
+-            if res.exp == 0 and divmod and op2.int > op1.int:
+-                #Solves an error in precision.  Same as a previous block.
+-
+-                if res.int >= prec_limit and shouldround:
+-                    return context._raise_error(DivisionImpossible)
+-                otherside = Decimal(op1)
+-                frozen = context._ignore_all_flags()
+-
+-                exp = min(self._exp, other._exp)
+-                otherside = otherside._rescale(exp, context=context)
+-
+-                context._regard_flags(*frozen)
+-
+-                return (Decimal(res), otherside)
+-
+-        ans = Decimal(res)
+-        if shouldround:
+-            ans = ans._fix(context)
+-        return ans
+-
+-    def __rdiv__(self, other, context=None):
+-        """Swaps self/other and returns __div__."""
+-        other = _convert_other(other)
+-        if other is NotImplemented:
+-            return other
+-        return other.__div__(self, context=context)
+-    __rtruediv__ = __rdiv__
+-
+-    def __divmod__(self, other, context=None):
+-        """
+-        (self // other, self % other)
+-        """
+-        return self._divide(other, 1, context)
+-
+-    def __rdivmod__(self, other, context=None):
+-        """Swaps self/other and returns __divmod__."""
+-        other = _convert_other(other)
+-        if other is NotImplemented:
+-            return other
+-        return other.__divmod__(self, context=context)
+-
+-    def __mod__(self, other, context=None):
+-        """
+-        self % other
+-        """
+-        other = _convert_other(other)
+-        if other is NotImplemented:
+-            return other
+-
+-        if self._is_special or other._is_special:
+-            ans = self._check_nans(other, context)
+-            if ans:
+-                return ans
+-
+-        if self and not other:
+-            return context._raise_error(InvalidOperation, 'x % 0')
+-
+-        return self._divide(other, 3, context)[1]
+-
+-    def __rmod__(self, other, context=None):
+-        """Swaps self/other and returns __mod__."""
+-        other = _convert_other(other)
+-        if other is NotImplemented:
+-            return other
+-        return other.__mod__(self, context=context)
+-
+-    def remainder_near(self, other, context=None):
+-        """
+-        Remainder nearest to 0-  abs(remainder-near) <= other/2
+-        """
+-        other = _convert_other(other)
+-        if other is NotImplemented:
+-            return other
+-
+-        if self._is_special or other._is_special:
+-            ans = self._check_nans(other, context)
+-            if ans:
+-                return ans
+-        if self and not other:
+-            return context._raise_error(InvalidOperation, 'x % 0')
+-
+-        if context is None:
+-            context = getcontext()
+-        # If DivisionImpossible causes an error, do not leave Rounded/Inexact
+-        # ignored in the calling function.
+-        context = context._shallow_copy()
+-        flags = context._ignore_flags(Rounded, Inexact)
+-        #keep DivisionImpossible flags
+-        (side, r) = self.__divmod__(other, context=context)
+-
+-        if r._isnan():
+-            context._regard_flags(*flags)
+-            return r
+-
+-        context = context._shallow_copy()
+-        rounding = context._set_rounding_decision(NEVER_ROUND)
+-
+-        if other._sign:
+-            comparison = other.__div__(Decimal(-2), context=context)
+-        else:
+-            comparison = other.__div__(Decimal(2), context=context)
+-
+-        context._set_rounding_decision(rounding)
+-        context._regard_flags(*flags)
+-
+-        s1, s2 = r._sign, comparison._sign
+-        r._sign, comparison._sign = 0, 0
+-
+-        if r < comparison:
+-            r._sign, comparison._sign = s1, s2
+-            #Get flags now
+-            self.__divmod__(other, context=context)
+-            return r._fix(context)
+-        r._sign, comparison._sign = s1, s2
+-
+-        rounding = context._set_rounding_decision(NEVER_ROUND)
+-
+-        (side, r) = self.__divmod__(other, context=context)
+-        context._set_rounding_decision(rounding)
+-        if r._isnan():
+-            return r
+-
+-        decrease = not side._iseven()
+-        rounding = context._set_rounding_decision(NEVER_ROUND)
+-        side = side.__abs__(context=context)
+-        context._set_rounding_decision(rounding)
+-
+-        s1, s2 = r._sign, comparison._sign
+-        r._sign, comparison._sign = 0, 0
+-        if r > comparison or decrease and r == comparison:
+-            r._sign, comparison._sign = s1, s2
+-            context.prec += 1
+-            if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
+-                context.prec -= 1
+-                return context._raise_error(DivisionImpossible)[1]
+-            context.prec -= 1
+-            if self._sign == other._sign:
+-                r = r.__sub__(other, context=context)
+-            else:
+-                r = r.__add__(other, context=context)
+-        else:
+-            r._sign, comparison._sign = s1, s2
+-
+-        return r._fix(context)
+-
+-    def __floordiv__(self, other, context=None):
+-        """self // other"""
+-        return self._divide(other, 2, context)[0]
+-
+-    def __rfloordiv__(self, other, context=None):
+-        """Swaps self/other and returns __floordiv__."""
+-        other = _convert_other(other)
+-        if other is NotImplemented:
+-            return other
+-        return other.__floordiv__(self, context=context)
+-
+-    def __float__(self):
+-        """Float representation."""
+-        return float(str(self))
+-
+-    def __int__(self):
+-        """Converts self to an int, truncating if necessary."""
+-        if self._is_special:
+-            if self._isnan():
+-                context = getcontext()
+-                return context._raise_error(InvalidContext)
+-            elif self._isinfinity():
+-                raise OverflowError, "Cannot convert infinity to long"
+-        if self._exp >= 0:
+-            s = ''.join(map(str, self._int)) + '0'*self._exp
+-        else:
+-            s = ''.join(map(str, self._int))[:self._exp]
+-        if s == '':
+-            s = '0'
+-        sign = '-'*self._sign
+-        return int(sign + s)
+-
+-    def __long__(self):
+-        """Converts to a long.
+-
+-        Equivalent to long(int(self))
+-        """
+-        return long(self.__int__())
+-
+-    def _fix(self, context):
+-        """Round if it is necessary to keep self within prec precision.
+-
+-        Rounds and fixes the exponent.  Does not raise on a sNaN.
+-
+-        Arguments:
+-        self - Decimal instance
+-        context - context used.
+-        """
+-        if self._is_special:
+-            return self
+-        if context is None:
+-            context = getcontext()
+-        prec = context.prec
+-        ans = self._fixexponents(context)
+-        if len(ans._int) > prec:
+-            ans = ans._round(prec, context=context)
+-            ans = ans._fixexponents(context)
+-        return ans
+-
+-    def _fixexponents(self, context):
+-        """Fix the exponents and return a copy with the exponent in bounds.
+-        Only call if known to not be a special value.
+-        """
+-        folddown = context._clamp
+-        Emin = context.Emin
+-        ans = self
+-        ans_adjusted = ans.adjusted()
+-        if ans_adjusted < Emin:
+-            Etiny = context.Etiny()
+-            if ans._exp < Etiny:
+-                if not ans:
+-                    ans = Decimal(self)
+-                    ans._exp = Etiny
+-                    context._raise_error(Clamped)
+-                    return ans
+-                ans = ans._rescale(Etiny, context=context)
+-                #It isn't zero, and exp < Emin => subnormal
+-                context._raise_error(Subnormal)
+-                if context.flags[Inexact]:
+-                    context._raise_error(Underflow)
+-            else:
+-                if ans:
+-                    #Only raise subnormal if non-zero.
+-                    context._raise_error(Subnormal)
+-        else:
+-            Etop = context.Etop()
+-            if folddown and ans._exp > Etop:
+-                context._raise_error(Clamped)
+-                ans = ans._rescale(Etop, context=context)
+-            else:
+-                Emax = context.Emax
+-                if ans_adjusted > Emax:
+-                    if not ans:
+-                        ans = Decimal(self)
+-                        ans._exp = Emax
+-                        context._raise_error(Clamped)
+-                        return ans
+-                    context._raise_error(Inexact)
+-                    context._raise_error(Rounded)
+-                    return context._raise_error(Overflow, 'above Emax', ans._sign)
+-        return ans
+-
+-    def _round(self, prec=None, rounding=None, context=None):
+-        """Returns a rounded version of self.
+-
+-        You can specify the precision or rounding method.  Otherwise, the
+-        context determines it.
+-        """
+-
+-        if self._is_special:
+-            ans = self._check_nans(context=context)
+-            if ans:
+-                return ans
+-
+-            if self._isinfinity():
+-                return Decimal(self)
+-
+-        if context is None:
+-            context = getcontext()
+-
+-        if rounding is None:
+-            rounding = context.rounding
+-        if prec is None:
+-            prec = context.prec
+-
+-        if not self:
+-            if prec <= 0:
+-                dig = (0,)
+-                exp = len(self._int) - prec + self._exp
+-            else:
+-                dig = (0,) * prec
+-                exp = len(self._int) + self._exp - prec
+-            ans = Decimal((self._sign, dig, exp))
+-            context._raise_error(Rounded)
+-            return ans
+-
+-        if prec == 0:
+-            temp = Decimal(self)
+-            temp._int = (0,)+temp._int
+-            prec = 1
+-        elif prec < 0:
+-            exp = self._exp + len(self._int) - prec - 1
+-            temp = Decimal( (self._sign, (0, 1), exp))
+-            prec = 1
+-        else:
+-            temp = Decimal(self)
+-
+-        numdigits = len(temp._int)
+-        if prec == numdigits:
+-            return temp
+-
+-        # See if we need to extend precision
+-        expdiff = prec - numdigits
+-        if expdiff > 0:
+-            tmp = list(temp._int)
+-            tmp.extend([0] * expdiff)
+-            ans =  Decimal( (temp._sign, tmp, temp._exp - expdiff))
+-            return ans
+-
+-        #OK, but maybe all the lost digits are 0.
+-        lostdigits = self._int[expdiff:]
+-        if lostdigits == (0,) * len(lostdigits):
+-            ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
+-            #Rounded, but not Inexact
+-            context._raise_error(Rounded)
+-            return ans
+-
+-        # Okay, let's round and lose data
+-
+-        this_function = getattr(temp, self._pick_rounding_function[rounding])
+-        #Now we've got the rounding function
+-
+-        if prec != context.prec:
+-            context = context._shallow_copy()
+-            context.prec = prec
+-        ans = this_function(prec, expdiff, context)
+-        context._raise_error(Rounded)
+-        context._raise_error(Inexact, 'Changed in rounding')
+-
+-        return ans
+-
+-    _pick_rounding_function = {}
+-
+-    def _round_down(self, prec, expdiff, context):
+-        """Also known as round-towards-0, truncate."""
+-        return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
+-
+-    def _round_half_up(self, prec, expdiff, context, tmp = None):
+-        """Rounds 5 up (away from 0)"""
+-
+-        if tmp is None:
+-            tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
+-        if self._int[prec] >= 5:
+-            tmp = tmp._increment(round=0, context=context)
+-            if len(tmp._int) > prec:
+-                return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
+-        return tmp
+-
+-    def _round_half_even(self, prec, expdiff, context):
+-        """Round 5 to even, rest to nearest."""
+-
+-        tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
+-        half = (self._int[prec] == 5)
+-        if half:
+-            for digit in self._int[prec+1:]:
+-                if digit != 0:
+-                    half = 0
+-                    break
+-        if half:
+-            if self._int[prec-1] & 1 == 0:
+-                return tmp
+-        return self._round_half_up(prec, expdiff, context, tmp)
+-
+-    def _round_half_down(self, prec, expdiff, context):
+-        """Round 5 down"""
+-
+-        tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
+-        half = (self._int[prec] == 5)
+-        if half:
+-            for digit in self._int[prec+1:]:
+-                if digit != 0:
+-                    half = 0
+-                    break
+-        if half:
+-            return tmp
+-        return self._round_half_up(prec, expdiff, context, tmp)
+-
+-    def _round_up(self, prec, expdiff, context):
+-        """Rounds away from 0."""
+-        tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
+-        for digit in self._int[prec:]:
+-            if digit != 0:
+-                tmp = tmp._increment(round=1, context=context)
+-                if len(tmp._int) > prec:
+-                    return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
+-                else:
+-                    return tmp
+-        return tmp
+-
+-    def _round_ceiling(self, prec, expdiff, context):
+-        """Rounds up (not away from 0 if negative.)"""
+-        if self._sign:
+-            return self._round_down(prec, expdiff, context)
+-        else:
+-            return self._round_up(prec, expdiff, context)
+-
+-    def _round_floor(self, prec, expdiff, context):
+-        """Rounds down (not towards 0 if negative)"""
+-        if not self._sign:
+-            return self._round_down(prec, expdiff, context)
+-        else:
+-            return self._round_up(prec, expdiff, context)
+-
+-    def __pow__(self, n, modulo = None, context=None):
+-        """Return self ** n (mod modulo)
+-
+-        If modulo is None (default), don't take it mod modulo.
+-        """
+-        n = _convert_other(n)
+-        if n is NotImplemented:
+-            return n
+-
+-        if context is None:
+-            context = getcontext()
+-
+-        if self._is_special or n._is_special or n.adjusted() > 8:
+-            #Because the spot << doesn't work with really big exponents
+-            if n._isinfinity() or n.adjusted() > 8:
+-                return context._raise_error(InvalidOperation, 'x ** INF')
+-
+-            ans = self._check_nans(n, context)
+-            if ans:
+-                return ans
+-
+-        if not n._isinteger():
+-            return context._raise_error(InvalidOperation, 'x ** (non-integer)')
+-
+-        if not self and not n:
+-            return context._raise_error(InvalidOperation, '0 ** 0')
+-
+-        if not n:
+-            return Decimal(1)
+-
+-        if self == Decimal(1):
+-            return Decimal(1)
+-
+-        sign = self._sign and not n._iseven()
+-        n = int(n)
+-
+-        if self._isinfinity():
+-            if modulo:
+-                return context._raise_error(InvalidOperation, 'INF % x')
+-            if n > 0:
+-                return Infsign[sign]
+-            return Decimal( (sign, (0,), 0) )
+-
+-        #with ludicrously large exponent, just raise an overflow and return inf.
+-        if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
+-           and self:
+-
+-            tmp = Decimal('inf')
+-            tmp._sign = sign
+-            context._raise_error(Rounded)
+-            context._raise_error(Inexact)
+-            context._raise_error(Overflow, 'Big power', sign)
+-            return tmp
+-
+-        elength = len(str(abs(n)))
+-        firstprec = context.prec
+-
+-        if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
+-            return context._raise_error(Overflow, 'Too much precision.', sign)
+-
+-        mul = Decimal(self)
+-        val = Decimal(1)
+-        context = context._shallow_copy()
+-        context.prec = firstprec + elength + 1
+-        if n < 0:
+-            #n is a long now, not Decimal instance
+-            n = -n
+-            mul = Decimal(1).__div__(mul, context=context)
+-
+-        spot = 1
+-        while spot <= n:
+-            spot <<= 1
+-
+-        spot >>= 1
+-        #Spot is the highest power of 2 less than n
+-        while spot:
+-            val = val.__mul__(val, context=context)
+-            if val._isinfinity():
+-                val = Infsign[sign]
+-                break
+-            if spot & n:
+-                val = val.__mul__(mul, context=context)
+-            if modulo is not None:
+-                val = val.__mod__(modulo, context=context)
+-            spot >>= 1
+-        context.prec = firstprec
+-
+-        if context._rounding_decision == ALWAYS_ROUND:
+-            return val._fix(context)
+-        return val
+-
+-    def __rpow__(self, other, context=None):
+-        """Swaps self/other and returns __pow__."""
+-        other = _convert_other(other)
+-        if other is NotImplemented:
+-            return other
+-        return other.__pow__(self, context=context)
+-
+-    def normalize(self, context=None):
+-        """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
+-
+-        if self._is_special:
+-            ans = self._check_nans(context=context)
+-            if ans:
+-                return ans
+-
+-        dup = self._fix(context)
+-        if dup._isinfinity():
+-            return dup
+-
+-        if not dup:
+-            return Decimal( (dup._sign, (0,), 0) )
+-        end = len(dup._int)
+-        exp = dup._exp
+-        while dup._int[end-1] == 0:
+-            exp += 1
+-            end -= 1
+-        return Decimal( (dup._sign, dup._int[:end], exp) )
+-
+-
+-    def quantize(self, exp, rounding=None, context=None, watchexp=1):
+-        """Quantize self so its exponent is the same as that of exp.
+-
+-        Similar to self._rescale(exp._exp) but with error checking.
+-        """
+-        if self._is_special or exp._is_special:
+-            ans = self._check_nans(exp, context)
+-            if ans:
+-                return ans
+-
+-            if exp._isinfinity() or self._isinfinity():
+-                if exp._isinfinity() and self._isinfinity():
+-                    return self  #if both are inf, it is OK
+-                if context is None:
+-                    context = getcontext()
+-                return context._raise_error(InvalidOperation,
+-                                        'quantize with one INF')
+-        return self._rescale(exp._exp, rounding, context, watchexp)
+-
+-    def same_quantum(self, other):
+-        """Test whether self and other have the same exponent.
+-
+-        same as self._exp == other._exp, except NaN == sNaN
+-        """
+-        if self._is_special or other._is_special:
+-            if self._isnan() or other._isnan():
+-                return self._isnan() and other._isnan() and True
+-            if self._isinfinity() or other._isinfinity():
+-                return self._isinfinity() and other._isinfinity() and True
+-        return self._exp == other._exp
+-
+-    def _rescale(self, exp, rounding=None, context=None, watchexp=1):
+-        """Rescales so that the exponent is exp.
+-
+-        exp = exp to scale to (an integer)
+-        rounding = rounding version
+-        watchexp: if set (default) an error is returned if exp is greater
+-        than Emax or less than Etiny.
+-        """
+-        if context is None:
+-            context = getcontext()
+-
+-        if self._is_special:
+-            if self._isinfinity():
+-                return context._raise_error(InvalidOperation, 'rescale with an INF')
+-
+-            ans = self._check_nans(context=context)
+-            if ans:
+-                return ans
+-
+-        if watchexp and (context.Emax  < exp or context.Etiny() > exp):
+-            return context._raise_error(InvalidOperation, 'rescale(a, INF)')
+-
+-        if not self:
+-            ans = Decimal(self)
+-            ans._int = (0,)
+-            ans._exp = exp
+-            return ans
+-
+-        diff = self._exp - exp
+-        digits = len(self._int) + diff
+-
+-        if watchexp and digits > context.prec:
+-            return context._raise_error(InvalidOperation, 'Rescale > prec')
+-
+-        tmp = Decimal(self)
+-        tmp._int = (0,) + tmp._int
+-        digits += 1
+-
+-        if digits < 0:
+-            tmp._exp = -digits + tmp._exp
+-            tmp._int = (0,1)
+-            digits = 1
+-        tmp = tmp._round(digits, rounding, context=context)
+-
+-        if tmp._int[0] == 0 and len(tmp._int) > 1:
+-            tmp._int = tmp._int[1:]
+-        tmp._exp = exp
+-
+-        tmp_adjusted = tmp.adjusted()
+-        if tmp and tmp_adjusted < context.Emin:
+-            context._raise_error(Subnormal)
+-        elif tmp and tmp_adjusted > context.Emax:
+-            return context._raise_error(InvalidOperation, 'rescale(a, INF)')
+-        return tmp
+-
+-    def to_integral(self, rounding=None, context=None):
+-        """Rounds to the nearest integer, without raising inexact, rounded."""
+-        if self._is_special:
+-            ans = self._check_nans(context=context)
+-            if ans:
+-                return ans
+-        if self._exp >= 0:
+-            return self
+-        if context is None:
+-            context = getcontext()
+-        flags = context._ignore_flags(Rounded, Inexact)
+-        ans = self._rescale(0, rounding, context=context)
+-        context._regard_flags(flags)
+-        return ans
+-
+-    def sqrt(self, context=None):
+-        """Return the square root of self.
+-
+-        Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
+-        Should quadratically approach the right answer.
+-        """
+-        if self._is_special:
+-            ans = self._check_nans(context=context)
+-            if ans:
+-                return ans
+-
+-            if self._isinfinity() and self._sign == 0:
+-                return Decimal(self)
+-
+-        if not self:
+-            #exponent = self._exp / 2, using round_down.
+-            #if self._exp < 0:
+-            #    exp = (self._exp+1) // 2
+-            #else:
+-            exp = (self._exp) // 2
+-            if self._sign == 1:
+-                #sqrt(-0) = -0
+-                return Decimal( (1, (0,), exp))
+-            else:
+-                return Decimal( (0, (0,), exp))
+-
+-        if context is None:
+-            context = getcontext()
+-
+-        if self._sign == 1:
+-            return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
+-
+-        tmp = Decimal(self)
+-
+-        expadd = tmp._exp // 2
+-        if tmp._exp & 1:
+-            tmp._int += (0,)
+-            tmp._exp = 0
+-        else:
+-            tmp._exp = 0
+-
+-        context = context._shallow_copy()
+-        flags = context._ignore_all_flags()
+-        firstprec = context.prec
+-        context.prec = 3
+-        if tmp.adjusted() & 1 == 0:
+-            ans = Decimal( (0, (8,1,9), tmp.adjusted()  - 2) )
+-            ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
+-                                          context=context), context=context)
+-            ans._exp -= 1 + tmp.adjusted() // 2
+-        else:
+-            ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
+-            ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
+-                                          context=context), context=context)
+-            ans._exp -= 1 + tmp.adjusted()  // 2
+-
+-        #ans is now a linear approximation.
+-
+-        Emax, Emin = context.Emax, context.Emin
+-        context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
+-
+-        half = Decimal('0.5')
+-
+-        maxp = firstprec + 2
+-        rounding = context._set_rounding(ROUND_HALF_EVEN)
+-        while 1:
+-            context.prec = min(2*context.prec - 2, maxp)
+-            ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
+-                                           context=context), context=context)
+-            if context.prec == maxp:
+-                break
+-
+-        #round to the answer's precision-- the only error can be 1 ulp.
+-        context.prec = firstprec
+-        prevexp = ans.adjusted()
+-        ans = ans._round(context=context)
+-
+-        #Now, check if the other last digits are better.
+-        context.prec = firstprec + 1
+-        # In case we rounded up another digit and we should actually go lower.
+-        if prevexp != ans.adjusted():
+-            ans._int += (0,)
+-            ans._exp -= 1
+-
+-
+-        lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
+-        context._set_rounding(ROUND_UP)
+-        if lower.__mul__(lower, context=context) > (tmp):
+-            ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
+-
+-        else:
+-            upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
+-            context._set_rounding(ROUND_DOWN)
+-            if upper.__mul__(upper, context=context) < tmp:
+-                ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
+-
+-        ans._exp += expadd
+-
+-        context.prec = firstprec
+-        context.rounding = rounding
+-        ans = ans._fix(context)
+-
+-        rounding = context._set_rounding_decision(NEVER_ROUND)
+-        if not ans.__mul__(ans, context=context) == self:
+-            # Only rounded/inexact if here.
+-            context._regard_flags(flags)
+-            context._raise_error(Rounded)
+-            context._raise_error(Inexact)
+-        else:
+-            #Exact answer, so let's set the exponent right.
+-            #if self._exp < 0:
+-            #    exp = (self._exp +1)// 2
+-            #else:
+-            exp = self._exp // 2
+-            context.prec += ans._exp - exp
+-            ans = ans._rescale(exp, context=context)
+-            context.prec = firstprec
+-            context._regard_flags(flags)
+-        context.Emax, context.Emin = Emax, Emin
+-
+-        return ans._fix(context)
+-
+-    def max(self, other, context=None):
+-        """Returns the larger value.
+-
+-        like max(self, other) except if one is not a number, returns
+-        NaN (and signals if one is sNaN).  Also rounds.
+-        """
+-        other = _convert_other(other)
+-        if other is NotImplemented:
+-            return other
+-
+-        if self._is_special or other._is_special:
+-            # if one operand is a quiet NaN and the other is number, then the
+-            # number is always returned
+-            sn = self._isnan()
+-            on = other._isnan()
+-            if sn or on:
+-                if on == 1 and sn != 2:
+-                    return self
+-                if sn == 1 and on != 2:
+-                    return other
+-                return self._check_nans(other, context)
+-
+-        ans = self
+-        c = self.__cmp__(other)
+-        if c == 0:
+-            # if both operands are finite and equal in numerical value
+-            # then an ordering is applied:
+-            #
+-            # if the signs differ then max returns the operand with the
+-            # positive sign and min returns the operand with the negative sign
+-            #
+-            # if the signs are the same then the exponent is used to select
+-            # the result.
+-            if self._sign != other._sign:
+-                if self._sign:
+-                    ans = other
+-            elif self._exp < other._exp and not self._sign:
+-                ans = other
+-            elif self._exp > other._exp and self._sign:
+-                ans = other
+-        elif c == -1:
+-            ans = other
+-
+-        if context is None:
+-            context = getcontext()
+-        if context._rounding_decision == ALWAYS_ROUND:
+-            return ans._fix(context)
+-        return ans
+-
+-    def min(self, other, context=None):
+-        """Returns the smaller value.
+-
+-        like min(self, other) except if one is not a number, returns
+-        NaN (and signals if one is sNaN).  Also rounds.
+-        """
+-        other = _convert_other(other)
+-        if other is NotImplemented:
+-            return other
+-
+-        if self._is_special or other._is_special:
+-            # if one operand is a quiet NaN and the other is number, then the
+-            # number is always returned
+-            sn = self._isnan()
+-            on = other._isnan()
+-            if sn or on:
+-                if on == 1 and sn != 2:
+-                    return self
+-                if sn == 1 and on != 2:
+-                    return other
+-                return self._check_nans(other, context)
+-
+-        ans = self
+-        c = self.__cmp__(other)
+-        if c == 0:
+-            # if both operands are finite and equal in numerical value
+-            # then an ordering is applied:
+-            #
+-            # if the signs differ then max returns the operand with the
+-            # positive sign and min returns the operand with the negative sign
+-            #
+-            # if the signs are the same then the exponent is used to select
+-            # the result.
+-            if self._sign != other._sign:
+-                if other._sign:
+-                    ans = other
+-            elif self._exp > other._exp and not self._sign:
+-                ans = other
+-            elif self._exp < other._exp and self._sign:
+-                ans = other
+-        elif c == 1:
+-            ans = other
+-
+-        if context is None:
+-            context = getcontext()
+-        if context._rounding_decision == ALWAYS_ROUND:
+-            return ans._fix(context)
+-        return ans
+-
+-    def _isinteger(self):
+-        """Returns whether self is an integer"""
+-        if self._exp >= 0:
+-            return True
+-        rest = self._int[self._exp:]
+-        return rest == (0,)*len(rest)
+-
+-    def _iseven(self):
+-        """Returns 1 if self is even.  Assumes self is an integer."""
+-        if self._exp > 0:
+-            return 1
+-        return self._int[-1+self._exp] & 1 == 0
+-
+-    def adjusted(self):
+-        """Return the adjusted exponent of self"""
+-        try:
+-            return self._exp + len(self._int) - 1
+-        #If NaN or Infinity, self._exp is string
+-        except TypeError:
+-            return 0
+-
+-    # support for pickling, copy, and deepcopy
+-    def __reduce__(self):
+-        return (self.__class__, (str(self),))
+-
+-    def __copy__(self):
+-        if type(self) == Decimal:
+-            return self     # I'm immutable; therefore I am my own clone
+-        return self.__class__(str(self))
+-
+-    def __deepcopy__(self, memo):
+-        if type(self) == Decimal:
+-            return self     # My components are also immutable
+-        return self.__class__(str(self))
+-
+-##### Context class ###########################################
+-
+-
+-# get rounding method function:
+-rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
+-for name in rounding_functions:
+-    #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
+-    globalname = name[1:].upper()
+-    val = globals()[globalname]
+-    Decimal._pick_rounding_function[val] = name
+-
+-del name, val, globalname, rounding_functions
+-
+-class Context(object):
+-    """Contains the context for a Decimal instance.
+-
+-    Contains:
+-    prec - precision (for use in rounding, division, square roots..)
+-    rounding - rounding type. (how you round)
+-    _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
+-    traps - If traps[exception] = 1, then the exception is
+-                    raised when it is caused.  Otherwise, a value is
+-                    substituted in.
+-    flags  - When an exception is caused, flags[exception] is incremented.
+-             (Whether or not the trap_enabler is set)
+-             Should be reset by user of Decimal instance.
+-    Emin -   Minimum exponent
+-    Emax -   Maximum exponent
+-    capitals -      If 1, 1*10^1 is printed as 1E+1.
+-                    If 0, printed as 1e1
+-    _clamp - If 1, change exponents if too high (Default 0)
+-    """
+-
+-    def __init__(self, prec=None, rounding=None,
+-                 traps=None, flags=None,
+-                 _rounding_decision=None,
+-                 Emin=None, Emax=None,
+-                 capitals=None, _clamp=0,
+-                 _ignored_flags=None):
+-        if flags is None:
+-            flags = []
+-        if _ignored_flags is None:
+-            _ignored_flags = []
+-        if not isinstance(flags, dict):
+-            flags = dict([(s,s in flags) for s in _signals])
+-            del s
+-        if traps is not None and not isinstance(traps, dict):
+-            traps = dict([(s,s in traps) for s in _signals])
+-            del s
+-        for name, val in locals().items():
+-            if val is None:
+-                setattr(self, name, _copy.copy(getattr(DefaultContext, name)))
+-            else:
+-                setattr(self, name, val)
+-        del self.self
+-
+-    def __repr__(self):
+-        """Show the current context."""
+-        s = []
+-        s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
+-        s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
+-        s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
+-        return ', '.join(s) + ')'
+-
+-    def clear_flags(self):
+-        """Reset all flags to zero"""
+-        for flag in self.flags:
+-            self.flags[flag] = 0
+-
+-    def _shallow_copy(self):
+-        """Returns a shallow copy from self."""
+-        nc = Context(self.prec, self.rounding, self.traps, self.flags,
+-                         self._rounding_decision, self.Emin, self.Emax,
+-                         self.capitals, self._clamp, self._ignored_flags)
+-        return nc
+-
+-    def copy(self):
+-        """Returns a deep copy from self."""
+-        nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
+-                         self._rounding_decision, self.Emin, self.Emax,
+-                         self.capitals, self._clamp, self._ignored_flags)
+-        return nc
+-    __copy__ = copy
+-
+-    def _raise_error(self, condition, explanation = None, *args):
+-        """Handles an error
+-
+-        If the flag is in _ignored_flags, returns the default response.
+-        Otherwise, it increments the flag, then, if the corresponding
+-        trap_enabler is set, it reaises the exception.  Otherwise, it returns
+-        the default value after incrementing the flag.
+-        """
+-        error = _condition_map.get(condition, condition)
+-        if error in self._ignored_flags:
+-            #Don't touch the flag
+-            return error().handle(self, *args)
+-
+-        self.flags[error] += 1
+-        if not self.traps[error]:
+-            #The errors define how to handle themselves.
+-            return condition().handle(self, *args)
+-
+-        # Errors should only be risked on copies of the context
+-        #self._ignored_flags = []
+-        raise error, explanation
+-
+-    def _ignore_all_flags(self):
+-        """Ignore all flags, if they are raised"""
+-        return self._ignore_flags(*_signals)
+-
+-    def _ignore_flags(self, *flags):
+-        """Ignore the flags, if they are raised"""
+-        # Do not mutate-- This way, copies of a context leave the original
+-        # alone.
+-        self._ignored_flags = (self._ignored_flags + list(flags))
+-        return list(flags)
+-
+-    def _regard_flags(self, *flags):
+-        """Stop ignoring the flags, if they are raised"""
+-        if flags and isinstance(flags[0], (tuple,list)):
+-            flags = flags[0]
+-        for flag in flags:
+-            self._ignored_flags.remove(flag)
+-
+-    def __hash__(self):
+-        """A Context cannot be hashed."""
+-        # We inherit object.__hash__, so we must deny this explicitly
+-        raise TypeError, "Cannot hash a Context."
+-
+-    def Etiny(self):
+-        """Returns Etiny (= Emin - prec + 1)"""
+-        return int(self.Emin - self.prec + 1)
+-
+-    def Etop(self):
+-        """Returns maximum exponent (= Emax - prec + 1)"""
+-        return int(self.Emax - self.prec + 1)
+-
+-    def _set_rounding_decision(self, type):
+-        """Sets the rounding decision.
+-
+-        Sets the rounding decision, and returns the current (previous)
+-        rounding decision.  Often used like:
+-
+-        context = context._shallow_copy()
+-        # That so you don't change the calling context
+-        # if an error occurs in the middle (say DivisionImpossible is raised).
+-
+-        rounding = context._set_rounding_decision(NEVER_ROUND)
+-        instance = instance / Decimal(2)
+-        context._set_rounding_decision(rounding)
+-
+-        This will make it not round for that operation.
+-        """
+-
+-        rounding = self._rounding_decision
+-        self._rounding_decision = type
+-        return rounding
+-
+-    def _set_rounding(self, type):
+-        """Sets the rounding type.
+-
+-        Sets the rounding type, and returns the current (previous)
+-        rounding type.  Often used like:
+-
+-        context = context.copy()
+-        # so you don't change the calling context
+-        # if an error occurs in the middle.
+-        rounding = context._set_rounding(ROUND_UP)
+-        val = self.__sub__(other, context=context)
+-        context._set_rounding(rounding)
+-
+-        This will make it round up for that operation.
+-        """
+-        rounding = self.rounding
+-        self.rounding= type
+-        return rounding
+-
+-    def create_decimal(self, num='0'):
+-        """Creates a new Decimal instance but using self as context."""
+-        d = Decimal(num, context=self)
+-        return d._fix(self)
+-
+-    #Methods
+-    def abs(self, a):
+-        """Returns the absolute value of the operand.
+-
+-        If the operand is negative, the result is the same as using the minus
+-        operation on the operand. Otherwise, the result is the same as using
+-        the plus operation on the operand.
+-
+-        >>> ExtendedContext.abs(Decimal('2.1'))
+-        Decimal("2.1")
+-        >>> ExtendedContext.abs(Decimal('-100'))
+-        Decimal("100")
+-        >>> ExtendedContext.abs(Decimal('101.5'))
+-        Decimal("101.5")
+-        >>> ExtendedContext.abs(Decimal('-101.5'))
+-        Decimal("101.5")
+-        """
+-        return a.__abs__(context=self)
+-
+-    def add(self, a, b):
+-        """Return the sum of the two operands.
+-
+-        >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
+-        Decimal("19.00")
+-        >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
+-        Decimal("1.02E+4")
+-        """
+-        return a.__add__(b, context=self)
+-
+-    def _apply(self, a):
+-        return str(a._fix(self))
+-
+-    def compare(self, a, b):
+-        """Compares values numerically.
+-
+-        If the signs of the operands differ, a value representing each operand
+-        ('-1' if the operand is less than zero, '0' if the operand is zero or
+-        negative zero, or '1' if the operand is greater than zero) is used in
+-        place of that operand for the comparison instead of the actual
+-        operand.
+-
+-        The comparison is then effected by subtracting the second operand from
+-        the first and then returning a value according to the result of the
+-        subtraction: '-1' if the result is less than zero, '0' if the result is
+-        zero or negative zero, or '1' if the result is greater than zero.
+-
+-        >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
+-        Decimal("-1")
+-        >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
+-        Decimal("0")
+-        >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
+-        Decimal("0")
+-        >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
+-        Decimal("1")
+-        >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
+-        Decimal("1")
+-        >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
+-        Decimal("-1")
+-        """
+-        return a.compare(b, context=self)
+-
+-    def divide(self, a, b):
+-        """Decimal division in a specified context.
+-
+-        >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
+-        Decimal("0.333333333")
+-        >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
+-        Decimal("0.666666667")
+-        >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
+-        Decimal("2.5")
+-        >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
+-        Decimal("0.1")
+-        >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
+-        Decimal("1")
+-        >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
+-        Decimal("4.00")
+-        >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
+-        Decimal("1.20")
+-        >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
+-        Decimal("10")
+-        >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
+-        Decimal("1000")
+-        >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
+-        Decimal("1.20E+6")
+-        """
+-        return a.__div__(b, context=self)
+-
+-    def divide_int(self, a, b):
+-        """Divides two numbers and returns the integer part of the result.
+-
+-        >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
+-        Decimal("0")
+-        >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
+-        Decimal("3")
+-        >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
+-        Decimal("3")
+-        """
+-        return a.__floordiv__(b, context=self)
+-
+-    def divmod(self, a, b):
+-        return a.__divmod__(b, context=self)
+-
+-    def max(self, a,b):
+-        """max compares two values numerically and returns the maximum.
+-
+-        If either operand is a NaN then the general rules apply.
+-        Otherwise, the operands are compared as as though by the compare
+-        operation. If they are numerically equal then the left-hand operand
+-        is chosen as the result. Otherwise the maximum (closer to positive
+-        infinity) of the two operands is chosen as the result.
+-
+-        >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
+-        Decimal("3")
+-        >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
+-        Decimal("3")
+-        >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
+-        Decimal("1")
+-        >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
+-        Decimal("7")
+-        """
+-        return a.max(b, context=self)
+-
+-    def min(self, a,b):
+-        """min compares two values numerically and returns the minimum.
+-
+-        If either operand is a NaN then the general rules apply.
+-        Otherwise, the operands are compared as as though by the compare
+-        operation. If they are numerically equal then the left-hand operand
+-        is chosen as the result. Otherwise the minimum (closer to negative
+-        infinity) of the two operands is chosen as the result.
+-
+-        >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
+-        Decimal("2")
+-        >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
+-        Decimal("-10")
+-        >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
+-        Decimal("1.0")
+-        >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
+-        Decimal("7")
+-        """
+-        return a.min(b, context=self)
+-
+-    def minus(self, a):
+-        """Minus corresponds to unary prefix minus in Python.
+-
+-        The operation is evaluated using the same rules as subtract; the
+-        operation minus(a) is calculated as subtract('0', a) where the '0'
+-        has the same exponent as the operand.
+-
+-        >>> ExtendedContext.minus(Decimal('1.3'))
+-        Decimal("-1.3")
+-        >>> ExtendedContext.minus(Decimal('-1.3'))
+-        Decimal("1.3")
+-        """
+-        return a.__neg__(context=self)
+-
+-    def multiply(self, a, b):
+-        """multiply multiplies two operands.
+-
+-        If either operand is a special value then the general rules apply.
+-        Otherwise, the operands are multiplied together ('long multiplication'),
+-        resulting in a number which may be as long as the sum of the lengths
+-        of the two operands.
+-
+-        >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
+-        Decimal("3.60")
+-        >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
+-        Decimal("21")
+-        >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
+-        Decimal("0.72")
+-        >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
+-        Decimal("-0.0")
+-        >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
+-        Decimal("4.28135971E+11")
+-        """
+-        return a.__mul__(b, context=self)
+-
+-    def normalize(self, a):
+-        """normalize reduces an operand to its simplest form.
+-
+-        Essentially a plus operation with all trailing zeros removed from the
+-        result.
+-
+-        >>> ExtendedContext.normalize(Decimal('2.1'))
+-        Decimal("2.1")
+-        >>> ExtendedContext.normalize(Decimal('-2.0'))
+-        Decimal("-2")
+-        >>> ExtendedContext.normalize(Decimal('1.200'))
+-        Decimal("1.2")
+-        >>> ExtendedContext.normalize(Decimal('-120'))
+-        Decimal("-1.2E+2")
+-        >>> ExtendedContext.normalize(Decimal('120.00'))
+-        Decimal("1.2E+2")
+-        >>> ExtendedContext.normalize(Decimal('0.00'))
+-        Decimal("0")
+-        """
+-        return a.normalize(context=self)
+-
+-    def plus(self, a):
+-        """Plus corresponds to unary prefix plus in Python.
+-
+-        The operation is evaluated using the same rules as add; the
+-        operation plus(a) is calculated as add('0', a) where the '0'
+-        has the same exponent as the operand.
+-
+-        >>> ExtendedContext.plus(Decimal('1.3'))
+-        Decimal("1.3")
+-        >>> ExtendedContext.plus(Decimal('-1.3'))
+-        Decimal("-1.3")
+-        """
+-        return a.__pos__(context=self)
+-
+-    def power(self, a, b, modulo=None):
+-        """Raises a to the power of b, to modulo if given.
+-
+-        The right-hand operand must be a whole number whose integer part (after
+-        any exponent has been applied) has no more than 9 digits and whose
+-        fractional part (if any) is all zeros before any rounding. The operand
+-        may be positive, negative, or zero; if negative, the absolute value of
+-        the power is used, and the left-hand operand is inverted (divided into
+-        1) before use.
+-
+-        If the increased precision needed for the intermediate calculations
+-        exceeds the capabilities of the implementation then an Invalid operation
+-        condition is raised.
+-
+-        If, when raising to a negative power, an underflow occurs during the
+-        division into 1, the operation is not halted at that point but
+-        continues.
+-
+-        >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
+-        Decimal("8")
+-        >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
+-        Decimal("0.125")
+-        >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
+-        Decimal("69.7575744")
+-        >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
+-        Decimal("0")
+-        >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
+-        Decimal("0")
+-        >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
+-        Decimal("1")
+-        >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
+-        Decimal("Infinity")
+-        >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
+-        Decimal("Infinity")
+-        >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
+-        Decimal("0")
+-        >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
+-        Decimal("-0")
+-        >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
+-        Decimal("1")
+-        >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
+-        Decimal("-Infinity")
+-        >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
+-        Decimal("Infinity")
+-        >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
+-        Decimal("NaN")
+-        """
+-        return a.__pow__(b, modulo, context=self)
+-
+-    def quantize(self, a, b):
+-        """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
+-
+-        The coefficient of the result is derived from that of the left-hand
+-        operand. It may be rounded using the current rounding setting (if the
+-        exponent is being increased), multiplied by a positive power of ten (if
+-        the exponent is being decreased), or is unchanged (if the exponent is
+-        already equal to that of the right-hand operand).
+-
+-        Unlike other operations, if the length of the coefficient after the
+-        quantize operation would be greater than precision then an Invalid
+-        operation condition is raised. This guarantees that, unless there is an
+-        error condition, the exponent of the result of a quantize is always
+-        equal to that of the right-hand operand.
+-
+-        Also unlike other operations, quantize will never raise Underflow, even
+-        if the result is subnormal and inexact.
+-
+-        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
+-        Decimal("2.170")
+-        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
+-        Decimal("2.17")
+-        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
+-        Decimal("2.2")
+-        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
+-        Decimal("2")
+-        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
+-        Decimal("0E+1")
+-        >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
+-        Decimal("-Infinity")
+-        >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
+-        Decimal("NaN")
+-        >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
+-        Decimal("-0")
+-        >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
+-        Decimal("-0E+5")
+-        >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
+-        Decimal("NaN")
+-        >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
+-        Decimal("NaN")
+-        >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
+-        Decimal("217.0")
+-        >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
+-        Decimal("217")
+-        >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
+-        Decimal("2.2E+2")
+-        >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
+-        Decimal("2E+2")
+-        """
+-        return a.quantize(b, context=self)
+-
+-    def remainder(self, a, b):
+-        """Returns the remainder from integer division.
+-
+-        The result is the residue of the dividend after the operation of
+-        calculating integer division as described for divide-integer, rounded to
+-        precision digits if necessary. The sign of the result, if non-zero, is
+-        the same as that of the original dividend.
+-
+-        This operation will fail under the same conditions as integer division
+-        (that is, if integer division on the same two operands would fail, the
+-        remainder cannot be calculated).
+-
+-        >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
+-        Decimal("2.1")
+-        >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
+-        Decimal("1")
+-        >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
+-        Decimal("-1")
+-        >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
+-        Decimal("0.2")
+-        >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
+-        Decimal("0.1")
+-        >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
+-        Decimal("1.0")
+-        """
+-        return a.__mod__(b, context=self)
+-
+-    def remainder_near(self, a, b):
+-        """Returns to be "a - b * n", where n is the integer nearest the exact
+-        value of "x / b" (if two integers are equally near then the even one
+-        is chosen). If the result is equal to 0 then its sign will be the
+-        sign of a.
+-
+-        This operation will fail under the same conditions as integer division
+-        (that is, if integer division on the same two operands would fail, the
+-        remainder cannot be calculated).
+-
+-        >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
+-        Decimal("-0.9")
+-        >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
+-        Decimal("-2")
+-        >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
+-        Decimal("1")
+-        >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
+-        Decimal("-1")
+-        >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
+-        Decimal("0.2")
+-        >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
+-        Decimal("0.1")
+-        >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
+-        Decimal("-0.3")
+-        """
+-        return a.remainder_near(b, context=self)
+-
+-    def same_quantum(self, a, b):
+-        """Returns True if the two operands have the same exponent.
+-
+-        The result is never affected by either the sign or the coefficient of
+-        either operand.
+-
+-        >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
+-        False
+-        >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
+-        True
+-        >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
+-        False
+-        >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
+-        True
+-        """
+-        return a.same_quantum(b)
+-
+-    def sqrt(self, a):
+-        """Returns the square root of a non-negative number to context precision.
+-
+-        If the result must be inexact, it is rounded using the round-half-even
+-        algorithm.
+-
+-        >>> ExtendedContext.sqrt(Decimal('0'))
+-        Decimal("0")
+-        >>> ExtendedContext.sqrt(Decimal('-0'))
+-        Decimal("-0")
+-        >>> ExtendedContext.sqrt(Decimal('0.39'))
+-        Decimal("0.624499800")
+-        >>> ExtendedContext.sqrt(Decimal('100'))
+-        Decimal("10")
+-        >>> ExtendedContext.sqrt(Decimal('1'))
+-        Decimal("1")
+-        >>> ExtendedContext.sqrt(Decimal('1.0'))
+-        Decimal("1.0")
+-        >>> ExtendedContext.sqrt(Decimal('1.00'))
+-        Decimal("1.0")
+-        >>> ExtendedContext.sqrt(Decimal('7'))
+-        Decimal("2.64575131")
+-        >>> ExtendedContext.sqrt(Decimal('10'))
+-        Decimal("3.16227766")
+-        >>> ExtendedContext.prec
+-        9
+-        """
+-        return a.sqrt(context=self)
+-
+-    def subtract(self, a, b):
+-        """Return the difference between the two operands.
+-
+-        >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
+-        Decimal("0.23")
+-        >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
+-        Decimal("0.00")
+-        >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
+-        Decimal("-0.77")
+-        """
+-        return a.__sub__(b, context=self)
+-
+-    def to_eng_string(self, a):
+-        """Converts a number to a string, using scientific notation.
+-
+-        The operation is not affected by the context.
+-        """
+-        return a.to_eng_string(context=self)
+-
+-    def to_sci_string(self, a):
+-        """Converts a number to a string, using scientific notation.
+-
+-        The operation is not affected by the context.
+-        """
+-        return a.__str__(context=self)
+-
+-    def to_integral(self, a):
+-        """Rounds to an integer.
+-
+-        When the operand has a negative exponent, the result is the same
+-        as using the quantize() operation using the given operand as the
+-        left-hand-operand, 1E+0 as the right-hand-operand, and the precision
+-        of the operand as the precision setting, except that no flags will
+-        be set. The rounding mode is taken from the context.
+-
+-        >>> ExtendedContext.to_integral(Decimal('2.1'))
+-        Decimal("2")
+-        >>> ExtendedContext.to_integral(Decimal('100'))
+-        Decimal("100")
+-        >>> ExtendedContext.to_integral(Decimal('100.0'))
+-        Decimal("100")
+-        >>> ExtendedContext.to_integral(Decimal('101.5'))
+-        Decimal("102")
+-        >>> ExtendedContext.to_integral(Decimal('-101.5'))
+-        Decimal("-102")
+-        >>> ExtendedContext.to_integral(Decimal('10E+5'))
+-        Decimal("1.0E+6")
+-        >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
+-        Decimal("7.89E+77")
+-        >>> ExtendedContext.to_integral(Decimal('-Inf'))
+-        Decimal("-Infinity")
+-        """
+-        return a.to_integral(context=self)
+-
+-class _WorkRep(object):
+-    __slots__ = ('sign','int','exp')
+-    # sign: 0 or 1
+-    # int:  int or long
+-    # exp:  None, int, or string
+-
+-    def __init__(self, value=None):
+-        if value is None:
+-            self.sign = None
+-            self.int = 0
+-            self.exp = None
+-        elif isinstance(value, Decimal):
+-            self.sign = value._sign
+-            cum = 0
+-            for digit  in value._int:
+-                cum = cum * 10 + digit
+-            self.int = cum
+-            self.exp = value._exp
+-        else:
+-            # assert isinstance(value, tuple)
+-            self.sign = value[0]
+-            self.int = value[1]
+-            self.exp = value[2]
+-
+-    def __repr__(self):
+-        return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
+-
+-    __str__ = __repr__
+-
+-
+-
+-def _normalize(op1, op2, shouldround = 0, prec = 0):
+-    """Normalizes op1, op2 to have the same exp and length of coefficient.
+-
+-    Done during addition.
+-    """
+-    # Yes, the exponent is a long, but the difference between exponents
+-    # must be an int-- otherwise you'd get a big memory problem.
+-    numdigits = int(op1.exp - op2.exp)
+-    if numdigits < 0:
+-        numdigits = -numdigits
+-        tmp = op2
+-        other = op1
+-    else:
+-        tmp = op1
+-        other = op2
+-
+-
+-    if shouldround and numdigits > prec + 1:
+-        # Big difference in exponents - check the adjusted exponents
+-        tmp_len = len(str(tmp.int))
+-        other_len = len(str(other.int))
+-        if numdigits > (other_len + prec + 1 - tmp_len):
+-            # If the difference in adjusted exps is > prec+1, we know
+-            # other is insignificant, so might as well put a 1 after the precision.
+-            # (since this is only for addition.)  Also stops use of massive longs.
+-
+-            extend = prec + 2 - tmp_len
+-            if extend <= 0:
+-                extend = 1
+-            tmp.int *= 10 ** extend
+-            tmp.exp -= extend
+-            other.int = 1
+-            other.exp = tmp.exp
+-            return op1, op2
+-
+-    tmp.int *= 10 ** numdigits
+-    tmp.exp -= numdigits
+-    return op1, op2
+-
+-def _adjust_coefficients(op1, op2):
+-    """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
+-
+-    Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
+-
+-    Used on _WorkRep instances during division.
+-    """
+-    adjust = 0
+-    #If op1 is smaller, make it larger
+-    while op2.int > op1.int:
+-        op1.int *= 10
+-        op1.exp -= 1
+-        adjust += 1
+-
+-    #If op2 is too small, make it larger
+-    while op1.int >= (10 * op2.int):
+-        op2.int *= 10
+-        op2.exp -= 1
+-        adjust -= 1
+-
+-    return op1, op2, adjust
+-
+-##### Helper Functions ########################################
+-
+-def _convert_other(other):
+-    """Convert other to Decimal.
+-
+-    Verifies that it's ok to use in an implicit construction.
+-    """
+-    if isinstance(other, Decimal):
+-        return other
+-    if isinstance(other, (int, long)):
+-        return Decimal(other)
+-    return NotImplemented
+-
+-_infinity_map = {
+-    'inf' : 1,
+-    'infinity' : 1,
+-    '+inf' : 1,
+-    '+infinity' : 1,
+-    '-inf' : -1,
+-    '-infinity' : -1
+-}
+-
+-def _isinfinity(num):
+-    """Determines whether a string or float is infinity.
+-
+-    +1 for negative infinity; 0 for finite ; +1 for positive infinity
+-    """
+-    num = str(num).lower()
+-    return _infinity_map.get(num, 0)
+-
+-def _isnan(num):
+-    """Determines whether a string or float is NaN
+-
+-    (1, sign, diagnostic info as string) => NaN
+-    (2, sign, diagnostic info as string) => sNaN
+-    0 => not a NaN
+-    """
+-    num = str(num).lower()
+-    if not num:
+-        return 0
+-
+-    #get the sign, get rid of trailing [+-]
+-    sign = 0
+-    if num[0] == '+':
+-        num = num[1:]
+-    elif num[0] == '-':  #elif avoids '+-nan'
+-        num = num[1:]
+-        sign = 1
+-
+-    if num.startswith('nan'):
+-        if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
+-            return 0
+-        return (1, sign, num[3:].lstrip('0'))
+-    if num.startswith('snan'):
+-        if len(num) > 4 and not num[4:].isdigit():
+-            return 0
+-        return (2, sign, num[4:].lstrip('0'))
+-    return 0
+-
+-
+-##### Setup Specific Contexts ################################
+-
+-# The default context prototype used by Context()
+-# Is mutable, so that new contexts can have different default values
+-
+-DefaultContext = Context(
+-        prec=28, rounding=ROUND_HALF_EVEN,
+-        traps=[DivisionByZero, Overflow, InvalidOperation],
+-        flags=[],
+-        _rounding_decision=ALWAYS_ROUND,
+-        Emax=999999999,
+-        Emin=-999999999,
+-        capitals=1
+-)
+-
+-# Pre-made alternate contexts offered by the specification
+-# Don't change these; the user should be able to select these
+-# contexts and be able to reproduce results from other implementations
+-# of the spec.
+-
+-BasicContext = Context(
+-        prec=9, rounding=ROUND_HALF_UP,
+-        traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
+-        flags=[],
+-)
+-
+-ExtendedContext = Context(
+-        prec=9, rounding=ROUND_HALF_EVEN,
+-        traps=[],
+-        flags=[],
+-)
+-
+-
+-##### Useful Constants (internal use only) ####################
+-
+-#Reusable defaults
+-Inf = Decimal('Inf')
+-negInf = Decimal('-Inf')
+-
+-#Infsign[sign] is infinity w/ that sign
+-Infsign = (Inf, negInf)
+-
+-NaN = Decimal('NaN')
+-
+-
+-##### crud for parsing strings #################################
+-import re
+-
+-# There's an optional sign at the start, and an optional exponent
+-# at the end.  The exponent has an optional sign and at least one
+-# digit.  In between, must have either at least one digit followed
+-# by an optional fraction, or a decimal point followed by at least
+-# one digit.  Yuck.
+-
+-_parser = re.compile(r"""
+-#    \s*
+-    (?P<sign>[-+])?
+-    (
+-        (?P<int>\d+) (\. (?P<frac>\d*))?
+-    |
+-        \. (?P<onlyfrac>\d+)
+-    )
+-    ([eE](?P<exp>[-+]? \d+))?
+-#    \s*
+-    $
+-""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
+-
+-del re
+-
+-# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
+-
+-def _string2exact(s):
+-    m = _parser(s)
+-    if m is None:
+-        raise ValueError("invalid literal for Decimal: %r" % s)
+-
+-    if m.group('sign') == "-":
+-        sign = 1
+-    else:
+-        sign = 0
+-
+-    exp = m.group('exp')
+-    if exp is None:
+-        exp = 0
+-    else:
+-        exp = int(exp)
+-
+-    intpart = m.group('int')
+-    if intpart is None:
+-        intpart = ""
+-        fracpart = m.group('onlyfrac')
+-    else:
+-        fracpart = m.group('frac')
+-        if fracpart is None:
+-            fracpart = ""
+-
+-    exp -= len(fracpart)
+-
+-    mantissa = intpart + fracpart
+-    tmp = map(int, mantissa)
+-    backup = tmp
+-    while tmp and tmp[0] == 0:
+-        del tmp[0]
+-
+-    # It's a zero
+-    if not tmp:
+-        if backup:
+-            return (sign, tuple(backup), exp)
+-        return (sign, (0,), exp)
+-    mantissa = tuple(tmp)
+-
+-    return (sign, mantissa, exp)
+-
+-
+-if __name__ == '__main__':
+-    import doctest, sys
+-    doctest.testmod(sys.modules[__name__])
++from decimal import *
--- python-django-1.1.1.orig/debian/patches/16_fix_cross_site_scripting_in_authentication.diff
+++ python-django-1.1.1/debian/patches/16_fix_cross_site_scripting_in_authentication.diff
@@ -0,0 +1,55 @@
+Description: Fix cross site scripting issue in authentication views
+Origin: backport, https://github.com/django/django/commit/4dea4883e6c50d75f215a6b9bcbd95273f57c72d
+Forwarded: not needed, it comes from upstream
+Bug-Debian: http://bugs.debian.org/683364
+
+Index: python-django-1.1.1/django/http/__init__.py
+===================================================================
+--- python-django-1.1.1.orig/django/http/__init__.py	2012-09-06 09:51:32.000000000 -0400
++++ python-django-1.1.1/django/http/__init__.py	2012-09-06 09:53:36.104092814 -0400
+@@ -3,13 +3,14 @@
+ from Cookie import SimpleCookie, CookieError
+ from pprint import pformat
+ from urllib import urlencode
+-from urlparse import urljoin
++from urlparse import urljoin, urlparse
+ try:
+     # The mod_python version is more efficient, so try importing it first.
+     from mod_python.util import parse_qsl
+ except ImportError:
+     from cgi import parse_qsl
+ 
++from django.core.exceptions import SuspiciousOperation
+ from django.utils.datastructures import MultiValueDict, ImmutableList
+ from django.utils.encoding import smart_str, iri_to_uri, force_unicode
+ from django.http.multipartparser import MultiPartParser
+@@ -400,19 +401,21 @@
+             raise Exception("This %s instance cannot tell its position" % self.__class__)
+         return sum([len(chunk) for chunk in self._container])
+ 
+-class HttpResponseRedirect(HttpResponse):
+-    status_code = 302
++class HttpResponseRedirectBase(HttpResponse):
++    allowed_schemes = ['http', 'https', 'ftp']
+ 
+     def __init__(self, redirect_to):
+-        HttpResponse.__init__(self)
++        super(HttpResponseRedirectBase, self).__init__()
++        parsed = urlparse(redirect_to)
++        if parsed[0] and parsed[0] not in self.allowed_schemes:
++            raise SuspiciousOperation("Unsafe redirect to URL with scheme '%s'" % parsed[0])
+         self['Location'] = redirect_to
+ 
+-class HttpResponsePermanentRedirect(HttpResponse):
+-    status_code = 301
++class HttpResponseRedirect(HttpResponseRedirectBase):
++    status_code = 302
+ 
+-    def __init__(self, redirect_to):
+-        HttpResponse.__init__(self)
+-        self['Location'] = redirect_to
++class HttpResponsePermanentRedirect(HttpResponseRedirectBase):
++    status_code = 301
+ 
+ class HttpResponseNotModified(HttpResponse):
+     status_code = 304
--- python-django-1.1.1.orig/debian/patches/08_security_admin_infoleak.diff
+++ python-django-1.1.1/debian/patches/08_security_admin_infoleak.diff
@@ -0,0 +1,146 @@
+Origin: http://code.djangoproject.com/changeset/15035
+Description: Information leakage in Django administrative interface
+ (CVE-2010-4534)
+
+Index: python-django-1.1.1/django/contrib/admin/options.py
+===================================================================
+--- python-django-1.1.1.orig/django/contrib/admin/options.py	2011-01-03 11:29:23.000000000 -0600
++++ python-django-1.1.1/django/contrib/admin/options.py	2011-01-03 11:29:27.000000000 -0600
+@@ -8,7 +8,9 @@
+ from django.contrib.admin.util import unquote, flatten_fieldsets, get_deleted_objects, model_ngettext, model_format_dict
+ from django.core.exceptions import PermissionDenied
+ from django.db import models, transaction
+-from django.db.models.fields import BLANK_CHOICE_DASH
++from django.db.models.related import RelatedObject
++from django.db.models.fields import BLANK_CHOICE_DASH, FieldDoesNotExist
++from django.db.models.sql.constants import LOOKUP_SEP, QUERY_TERMS
+ from django.http import Http404, HttpResponse, HttpResponseRedirect
+ from django.shortcuts import get_object_or_404, render_to_response
+ from django.utils.datastructures import SortedDict
+@@ -172,6 +174,30 @@
+         return None
+     declared_fieldsets = property(_declared_fieldsets)
+ 
++    def lookup_allowed(self, lookup):
++        parts = lookup.split(LOOKUP_SEP)
++
++        # Last term in lookup is a query term (__exact, __startswith etc)
++        # This term can be ignored.
++        if len(parts) > 1 and parts[-1] in QUERY_TERMS:
++            parts.pop()
++
++        # Special case -- foo__id__exact and foo__id queries are implied
++        # if foo has been specificially included in the lookup list; so
++        # drop __id if it is the last part.
++        if len(parts) > 1 and parts[-1] == self.model._meta.pk.name:
++            parts.pop()
++
++        try:
++            self.model._meta.get_field_by_name(parts[0])
++        except FieldDoesNotExist:
++            # Lookups on non-existants fields are ok, since they're ignored
++            # later.
++            return True
++        else:
++            clean_lookup = LOOKUP_SEP.join(parts)
++            return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy
++
+ class ModelAdmin(BaseModelAdmin):
+     "Encapsulates all admin options and functionality for a given model."
+     __metaclass__ = forms.MediaDefiningClass
+Index: python-django-1.1.1/django/contrib/admin/views/main.py
+===================================================================
+--- python-django-1.1.1.orig/django/contrib/admin/views/main.py	2011-01-03 11:29:23.000000000 -0600
++++ python-django-1.1.1/django/contrib/admin/views/main.py	2011-01-03 11:29:27.000000000 -0600
+@@ -1,6 +1,7 @@
+ from django.contrib.admin.filterspecs import FilterSpec
+ from django.contrib.admin.options import IncorrectLookupParameters
+ from django.contrib.admin.util import quote
++from django.core.exceptions import SuspiciousOperation
+ from django.core.paginator import Paginator, InvalidPage
+ from django.db import models
+ from django.db.models.query import QuerySet
+@@ -185,13 +186,18 @@
+             if key.endswith('__in'):
+                 lookup_params[key] = value.split(',')
+ 
++            if not self.model_admin.lookup_allowed(key):
++                raise SuspiciousOperation(
++                    "Filtering by %s not allowed" % key
++                )
++
+         # Apply lookup parameters from the query string.
+         try:
+             qs = qs.filter(**lookup_params)
+         # Naked except! Because we don't have any other way of validating "params".
+         # They might be invalid if the keyword arguments are incorrect, or if the
+         # values are not in the correct type, so we might get FieldError, ValueError,
+-        # ValicationError, or ? from a custom field that raises yet something else 
++        # ValicationError, or ? from a custom field that raises yet something else
+         # when handed impossible data.
+         except:
+             raise IncorrectLookupParameters
+Index: python-django-1.1.1/tests/regressiontests/admin_views/models.py
+===================================================================
+--- python-django-1.1.1.orig/tests/regressiontests/admin_views/models.py	2011-01-03 11:29:23.000000000 -0600
++++ python-django-1.1.1/tests/regressiontests/admin_views/models.py	2011-01-03 11:29:27.000000000 -0600
+@@ -5,7 +5,7 @@
+ from django.db import models
+ from django.contrib import admin
+ from django.core.mail import EmailMessage
+-
++from django.contrib.auth.models import User
+ class Section(models.Model):
+     """
+     A simple section that links to articles, to test linking to related items
+@@ -82,7 +82,7 @@
+ 
+ class ArticleAdmin(admin.ModelAdmin):
+     list_display = ('content', 'date', callable_year, 'model_year', 'modeladmin_year')
+-    list_filter = ('date',)
++    list_filter = ('date', 'section')
+ 
+     def changelist_view(self, request):
+         "Test that extra_context works"
+@@ -185,6 +185,13 @@
+     def __unicode__(self):
+         return self.name
+ 
++class Album(models.Model):
++    owner = models.ForeignKey(User)
++    title = models.CharField(max_length=30)
++
++class AlbumAdmin(admin.ModelAdmin):
++    list_filter = ['title']
++
+ class Account(models.Model):
+     """
+     A simple, generic account encapsulating the information shared by all
+@@ -456,3 +463,4 @@
+ admin.site.register(Book, inlines=[ChapterInline])
+ admin.site.register(Promo)
+ admin.site.register(ChapterXtra1)
++admin.site.register(Album, AlbumAdmin)
+Index: python-django-1.1.1/tests/regressiontests/admin_views/tests.py
+===================================================================
+--- python-django-1.1.1.orig/tests/regressiontests/admin_views/tests.py	2011-01-03 11:29:23.000000000 -0600
++++ python-django-1.1.1/tests/regressiontests/admin_views/tests.py	2011-01-03 11:29:27.000000000 -0600
+@@ -3,6 +3,7 @@
+ import re
+ import datetime
+ from django.core.files import temp as tempfile
++from django.core.exceptions import SuspiciousOperation
+ from django.test import TestCase
+ from django.contrib.auth.models import User, Permission
+ from django.contrib.contenttypes.models import ContentType
+@@ -678,6 +679,10 @@
+         should_contain = """<h1>Change model with string primary key</h1>"""
+         self.assertContains(response, should_contain)
+ 
++    def test_disallowed_filtering(self):
++        self.assertRaises(SuspiciousOperation,
++            self.client.get, "/test_admin/admin/admin_views/album/?owner__email__startswith=fuzzy"
++        )
+ 
+ class SecureViewTest(TestCase):
+     fixtures = ['admin-views-users.xml']
--- python-django-1.1.1.orig/debian/patches/07_test_client_cookie_fix.diff
+++ python-django-1.1.1/debian/patches/07_test_client_cookie_fix.diff
@@ -0,0 +1,19 @@
+From: James Henstridge <jamesh@ubuntu.com>
+Subject: Fix Django test client cookie handling with latest python2.6 upload
+Origin: upstream, http://code.djangoproject.com/changeset/12343
+Bug: http://code.djangoproject.com/ticket/12720
+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/python-django/+bug/513719
+Reviewed-By: Elliot Murphy <elliot@ubuntu.com>
+Last-Update: 2010-01-30
+
+--- python-django.orig/django/test/client.py	2010-01-29 13:09:25.885960656 -0500
++++ python-django/django/test/client.py	2010-01-29 13:10:15.622491350 -0500
+@@ -193,7 +193,7 @@
+         using the arguments to the request.
+         """
+         environ = {
+-            'HTTP_COOKIE':      self.cookies,
++            'HTTP_COOKIE':      self.cookies.output(header='', sep='; '),
+             'PATH_INFO':         '/',
+             'QUERY_STRING':      '',
+             'REMOTE_ADDR':       '127.0.0.1',
--- python-django-1.1.1.orig/debian/patches/06_python_2.6.3_regression.diff
+++ python-django-1.1.1/debian/patches/06_python_2.6.3_regression.diff
@@ -0,0 +1,14 @@
+Forwarded-Upstream: http://code.djangoproject.com/changeset/11619
+Comment:
+ Fix FTBFS under Python 2.6.3; int(Decimal('nan')) raises ValueError instead
+ of returning None.
+
+--- ./django/template/defaultfilters.py (revision 10543)
++++ ./django/template/defaultfilters.py (revision 11619)
+@@ -163,5 +163,5 @@
+     try:
+         m = int(d) - d
+-    except (OverflowError, InvalidOperation):
++    except (ValueError, OverflowError, InvalidOperation):
+         return input_val
+ 
--- python-django-1.1.1.orig/debian/patches/CVE-2011-4139.patch
+++ python-django-1.1.1/debian/patches/CVE-2011-4139.patch
@@ -0,0 +1,281 @@
+Origin: backport, https://code.djangoproject.com/changeset/16764
+Description: Added protection against spoofing of X_FORWARDED_HOST headers.
+ Also apply the following for the regression patch (and it will make future
+ updates easier):
+ - https://code.djangoproject.com/changeset/13930
+ - https://code.djangoproject.com/changeset/13949
+
+Index: python-django-1.1.1/django/http/__init__.py
+===================================================================
+--- python-django-1.1.1.orig/django/http/__init__.py	2009-05-08 06:31:36.000000000 -0500
++++ python-django-1.1.1/django/http/__init__.py	2011-12-07 16:02:04.000000000 -0600
+@@ -45,7 +45,8 @@
+     def get_host(self):
+         """Returns the HTTP host using the environment or request headers."""
+         # We try three options, in order of decreasing preference.
+-        if 'HTTP_X_FORWARDED_HOST' in self.META:
++        if settings.USE_X_FORWARDED_HOST and (
++            'HTTP_X_FORWARDED_HOST' in self.META):
+             host = self.META['HTTP_X_FORWARDED_HOST']
+         elif 'HTTP_HOST' in self.META:
+             host = self.META['HTTP_HOST']
+Index: python-django-1.1.1/django/conf/global_settings.py
+===================================================================
+--- python-django-1.1.1.orig/django/conf/global_settings.py	2009-05-26 00:32:52.000000000 -0500
++++ python-django-1.1.1/django/conf/global_settings.py	2011-12-07 16:02:04.000000000 -0600
+@@ -290,6 +290,8 @@
+ DEFAULT_TABLESPACE = ''
+ DEFAULT_INDEX_TABLESPACE = ''
+ 
++USE_X_FORWARDED_HOST = False
++
+ ##############
+ # MIDDLEWARE #
+ ##############
+Index: python-django-1.1.1/docs/ref/request-response.txt
+===================================================================
+--- python-django-1.1.1.orig/docs/ref/request-response.txt	2009-09-13 01:31:17.000000000 -0500
++++ python-django-1.1.1/docs/ref/request-response.txt	2011-12-07 16:02:04.000000000 -0600
+@@ -193,12 +193,11 @@
+ 
+    .. versionadded:: 1.0
+ 
+-   Returns the originating host of the request using information from the
+-   ``HTTP_X_FORWARDED_HOST`` and ``HTTP_HOST`` headers (in that order). If
+-   they don't provide a value, the method uses a combination of
+-   ``SERVER_NAME`` and ``SERVER_PORT`` as detailed in `PEP 333`_.
+-
+-   .. _PEP 333: http://www.python.org/dev/peps/pep-0333/
++   Returns the originating host of the request using information from
++   the ``HTTP_X_FORWARDED_HOST`` (if enabled in the settings) and
++   ``HTTP_HOST`` headers (in that order). If they don't provide a value,
++   the method uses a combination of ``SERVER_NAME`` and ``SERVER_PORT`` as
++   detailed in :pep:`3333`.
+ 
+    Example: ``"127.0.0.1:8000"``
+ 
+Index: python-django-1.1.1/docs/ref/settings.txt
+===================================================================
+--- python-django-1.1.1.orig/docs/ref/settings.txt	2009-06-18 08:33:18.000000000 -0500
++++ python-django-1.1.1/docs/ref/settings.txt	2011-12-07 16:02:04.000000000 -0600
+@@ -1189,6 +1189,19 @@
+ set to ``False``, Django will make some optimizations so as not to load the
+ internationalization machinery.
+ 
++.. setting:: USE_X_FORWARDED_HOST
++
++USE_X_FORWARDED_HOST
++--------------------
++
++.. versionadded:: 1.3.1
++
++Default: ``False``
++
++A boolean that specifies whether to use the X-Forwarded-Host header in
++preference to the Host header. This should only be enabled if a proxy
++which sets this header is in use.
++
+ .. setting:: YEAR_MONTH_FORMAT
+ 
+ YEAR_MONTH_FORMAT
+Index: python-django-1.1.1/tests/regressiontests/requests/tests.py
+===================================================================
+--- python-django-1.1.1.orig/tests/regressiontests/requests/tests.py	2008-08-23 12:28:12.000000000 -0500
++++ python-django-1.1.1/tests/regressiontests/requests/tests.py	2011-12-07 16:02:04.000000000 -0600
+@@ -1,47 +1,149 @@
+-"""
+->>> from django.http import HttpRequest
+->>> print repr(HttpRequest())
+-<HttpRequest
+-GET:{},
+-POST:{},
+-COOKIES:{},
+-META:{}>
+-
+->>> from django.core.handlers.wsgi import WSGIRequest
+->>> print repr(WSGIRequest({'PATH_INFO': 'bogus', 'REQUEST_METHOD': 'bogus'}))
+-<WSGIRequest
+-GET:<QueryDict: {}>,
+-POST:<QueryDict: {}>,
+-COOKIES:{},
+-META:{...}>
+-
+->>> from django.core.handlers.modpython import ModPythonRequest
+->>> class FakeModPythonRequest(ModPythonRequest):
+-...    def __init__(self, *args, **kwargs):
+-...        super(FakeModPythonRequest, self).__init__(*args, **kwargs)
+-...        self._get = self._post = self._meta = self._cookies = {}
+->>> class Dummy:
+-...     def get_options(self):
+-...         return {}
+->>> req = Dummy()
+->>> req.uri = 'bogus'
+->>> print repr(FakeModPythonRequest(req))
+-<ModPythonRequest
+-path:bogus,
+-GET:{},
+-POST:{},
+-COOKIES:{},
+-META:{}>
+-
+->>> from django.http import parse_cookie
+->>> parse_cookie('invalid:key=true')
+-{}
+-
+->>> request = HttpRequest()
+->>> print request.build_absolute_uri(location="https://www.example.com/asdf")
+-https://www.example.com/asdf
+->>> request.get_host = lambda: 'www.example.com'
+->>> request.path = ''
+->>> print request.build_absolute_uri(location="/path/with:colons")
+-http://www.example.com/path/with:colons
+-"""
++from datetime import datetime, timedelta
++import time
++import unittest
++
++from django.conf import settings
++from django.http import HttpRequest, HttpResponse, parse_cookie
++from django.core.handlers.wsgi import WSGIRequest
++from django.core.handlers.modpython import ModPythonRequest
++from django.utils.http import cookie_date
++
++
++class RequestsTests(unittest.TestCase):
++
++    def test_httprequest(self):
++        request = HttpRequest()
++        self.assertEqual(request.GET.keys(), [])
++        self.assertEqual(request.POST.keys(), [])
++        self.assertEqual(request.COOKIES.keys(), [])
++        self.assertEqual(request.META.keys(), [])
++
++    def test_wsgirequest(self):
++        request = WSGIRequest({'PATH_INFO': 'bogus', 'REQUEST_METHOD': 'bogus'})
++        self.assertEqual(request.GET.keys(), [])
++        self.assertEqual(request.POST.keys(), [])
++        self.assertEqual(request.COOKIES.keys(), [])
++        self.assertEqual(set(request.META.keys()), set(['PATH_INFO', 'REQUEST_METHOD', 'SCRIPT_NAME']))
++        self.assertEqual(request.META['PATH_INFO'], 'bogus')
++        self.assertEqual(request.META['REQUEST_METHOD'], 'bogus')
++        self.assertEqual(request.META['SCRIPT_NAME'], '')
++
++    def test_modpythonrequest(self):
++        class FakeModPythonRequest(ModPythonRequest):
++           def __init__(self, *args, **kwargs):
++               super(FakeModPythonRequest, self).__init__(*args, **kwargs)
++               self._get = self._post = self._meta = self._cookies = {}
++
++        class Dummy:
++            def get_options(self):
++                return {}
++
++        req = Dummy()
++        req.uri = 'bogus'
++        request = FakeModPythonRequest(req)
++        self.assertEqual(request.path, 'bogus')
++        self.assertEqual(request.GET.keys(), [])
++        self.assertEqual(request.POST.keys(), [])
++        self.assertEqual(request.COOKIES.keys(), [])
++        self.assertEqual(request.META.keys(), [])
++
++    def test_parse_cookie(self):
++        self.assertEqual(parse_cookie('invalid:key=true'), {})
++
++    def test_httprequest_location(self):
++        request = HttpRequest()
++        self.assertEqual(request.build_absolute_uri(location="https://www.example.com/asdf"),
++            'https://www.example.com/asdf')
++
++        request.get_host = lambda: 'www.example.com'
++        request.path = ''
++        self.assertEqual(request.build_absolute_uri(location="/path/with:colons"),
++            'http://www.example.com/path/with:colons')
++
++    def test_http_get_host(self):
++        old_USE_X_FORWARDED_HOST = settings.USE_X_FORWARDED_HOST
++        try:
++            settings.USE_X_FORWARDED_HOST = False
++
++            # Check if X_FORWARDED_HOST is provided.
++            request = HttpRequest()
++            request.META = {
++                u'HTTP_X_FORWARDED_HOST': u'forward.com',
++                u'HTTP_HOST': u'example.com',
++                u'SERVER_NAME': u'internal.com',
++                u'SERVER_PORT': 80,
++            }
++            # X_FORWARDED_HOST is ignored.
++            self.assertEqual(request.get_host(), 'example.com')
++
++            # Check if X_FORWARDED_HOST isn't provided.
++            request = HttpRequest()
++            request.META = {
++                u'HTTP_HOST': u'example.com',
++                u'SERVER_NAME': u'internal.com',
++                u'SERVER_PORT': 80,
++            }
++            self.assertEqual(request.get_host(), 'example.com')
++
++            # Check if HTTP_HOST isn't provided.
++            request = HttpRequest()
++            request.META = {
++                u'SERVER_NAME': u'internal.com',
++                u'SERVER_PORT': 80,
++            }
++            self.assertEqual(request.get_host(), 'internal.com')
++
++            # Check if HTTP_HOST isn't provided, and we're on a nonstandard port
++            request = HttpRequest()
++            request.META = {
++                u'SERVER_NAME': u'internal.com',
++                u'SERVER_PORT': 8042,
++            }
++            self.assertEqual(request.get_host(), 'internal.com:8042')
++
++        finally:
++            settings.USE_X_FORWARDED_HOST = old_USE_X_FORWARDED_HOST
++
++    def test_http_get_host_with_x_forwarded_host(self):
++        old_USE_X_FORWARDED_HOST = settings.USE_X_FORWARDED_HOST
++        try:
++            settings.USE_X_FORWARDED_HOST = True
++
++            # Check if X_FORWARDED_HOST is provided.
++            request = HttpRequest()
++            request.META = {
++                u'HTTP_X_FORWARDED_HOST': u'forward.com',
++                u'HTTP_HOST': u'example.com',
++                u'SERVER_NAME': u'internal.com',
++                u'SERVER_PORT': 80,
++            }
++            # X_FORWARDED_HOST is obeyed.
++            self.assertEqual(request.get_host(), 'forward.com')
++
++            # Check if X_FORWARDED_HOST isn't provided.
++            request = HttpRequest()
++            request.META = {
++                u'HTTP_HOST': u'example.com',
++                u'SERVER_NAME': u'internal.com',
++                u'SERVER_PORT': 80,
++            }
++            self.assertEqual(request.get_host(), 'example.com')
++
++            # Check if HTTP_HOST isn't provided.
++            request = HttpRequest()
++            request.META = {
++                u'SERVER_NAME': u'internal.com',
++                u'SERVER_PORT': 80,
++            }
++            self.assertEqual(request.get_host(), 'internal.com')
++
++            # Check if HTTP_HOST isn't provided, and we're on a nonstandard port
++            request = HttpRequest()
++            request.META = {
++                u'SERVER_NAME': u'internal.com',
++                u'SERVER_PORT': 8042,
++            }
++            self.assertEqual(request.get_host(), 'internal.com:8042')
++
++        finally:
++            settings.USE_X_FORWARDED_HOST = old_USE_X_FORWARDED_HOST
--- python-django-1.1.1.orig/debian/patches/series
+++ python-django-1.1.1/debian/patches/series
@@ -0,0 +1,20 @@
+01_disable_url_verify_regression_tests.diff
+02-embedded_code_copies.diff
+03_manpage.diff
+04_hyphen-manpage.diff
+05_ftbfs_in_november.diff
+06_python_2.6.3_regression.diff
+07_test_client_cookie_fix.diff
+08_security_admin_infoleak.diff
+09_security_pasword_reset_dos.diff
+10_CVE-2011-0696.diff
+11_CVE-2011-0697.diff
+CVE-2011-4136.patch
+CVE-2011-4137+4138.patch
+CVE-2011-4139.patch
+16_fix_cross_site_scripting_in_authentication.diff
+17_fix_dos_in_image_validation.diff
+18_fix_dos_via_get_image_dimensions.diff
+CVE-2012-4520.patch
+CVE-2012-4520-additional-tests.diff
+lp1080204.diff
--- python-django-1.1.1.orig/debian/patches/03_manpage.diff
+++ python-django-1.1.1/debian/patches/03_manpage.diff
@@ -0,0 +1,23 @@
+Forwarded-Upstream: not needed
+Author: Brett Parker <iDunno@sommitrealweird.co.uk>
+Comment:
+ Update the manual page to speak of django-admin instead of
+ django-admin.py as that's the name used by the Debian package.
+ .
+ This is a Debian specific patch.
+
+--- a/docs/man/django-admin.1	2007-09-08 10:47:27.516890257 +0100
++++ b/docs/man/django-admin.1	2007-09-08 10:48:01.822845242 +0100
+@@ -1,9 +1,9 @@
+-.TH "django-admin.py" "1" "March 2008" "Django Project" ""
++.TH "django-admin" "1" "March 2008" "Django Project" ""
+ .SH "NAME"
+-django\-admin.py \- Utility script for the Django web framework
++django\-admin \- Utility script for the Django web framework
+ .SH "SYNOPSIS"
+-.B django\-admin.py
++.B django\-admin
+ .I <action>
+ .B [options]
+ .sp
+ .SH "DESCRIPTION"
--- python-django-1.1.1.orig/debian/patches/10_CVE-2011-0696.diff
+++ python-django-1.1.1/debian/patches/10_CVE-2011-0696.diff
@@ -0,0 +1,118 @@
+Origin: http://code.djangoproject.com/changeset/15466
+Description: Don't exempt AJAX from CSRF validation
+Bug-Ubuntu: https://launchpad.net/bugs/719031
+
+Index: python-django-1.1.1/django/contrib/csrf/middleware.py
+===================================================================
+--- python-django-1.1.1.orig/django/contrib/csrf/middleware.py	2011-02-15 16:43:55.000000000 -0600
++++ python-django-1.1.1/django/contrib/csrf/middleware.py	2011-02-15 16:44:00.000000000 -0600
+@@ -37,9 +37,6 @@
+             if getattr(callback, 'csrf_exempt', False):
+                 return None
+ 
+-            if request.is_ajax():
+-                return None
+-
+             try:
+                 session_id = request.COOKIES[settings.SESSION_COOKIE_NAME]
+             except KeyError:
+@@ -48,9 +45,12 @@
+ 
+             csrf_token = _make_token(session_id)
+             # check incoming token
+-            try:
+-                request_csrf_token = request.POST['csrfmiddlewaretoken']
+-            except KeyError:
++            request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
++            if request_csrf_token == "":
++                # Fall back to X-CSRFToken, to make things easier for AJAX
++                request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')
++
++            if request_csrf_token == "":
+                 return HttpResponseForbidden(_ERROR_MSG)
+ 
+             if request_csrf_token != csrf_token:
+Index: python-django-1.1.1/django/contrib/csrf/tests.py
+===================================================================
+--- python-django-1.1.1.orig/django/contrib/csrf/tests.py	2011-02-15 16:43:55.000000000 -0600
++++ python-django-1.1.1/django/contrib/csrf/tests.py	2011-02-15 16:44:00.000000000 -0600
+@@ -134,11 +134,11 @@
+         req2 = CsrfMiddleware().process_view(req, csrf_exempt(self.get_view()), (), {})
+         self.assertEquals(None, req2)
+ 
+-    def test_ajax_exemption(self):
++    def test_csrf_token_in_header(self):
+         """
+-        Check that AJAX requests are automatically exempted.
++        Check that we can pass in the token in a header instead of in the form
+         """
+         req = self._get_POST_session_request()
+-        req.META['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
++        req.META['HTTP_X_CSRFTOKEN'] = _make_token(self._session_id)
+         req2 = CsrfMiddleware().process_view(req, self.get_view(), (), {})
+         self.assertEquals(None, req2)
+Index: python-django-1.1.1/docs/ref/contrib/csrf.txt
+===================================================================
+--- python-django-1.1.1.orig/docs/ref/contrib/csrf.txt	2011-02-15 16:43:55.000000000 -0600
++++ python-django-1.1.1/docs/ref/contrib/csrf.txt	2011-02-15 16:44:00.000000000 -0600
+@@ -39,6 +39,34 @@
+     (previous versions of Django did not provide these two components
+     of ``CsrfMiddleware`` as described above)
+ 
++AJAX
++----
++
++While the above method can be used with AJAX POST requests, it has some
++inconveniences: you have to remember to get the CSRF token from the HTML
++document and pass it in as POST data with every POST request. For this reason,
++there is an alternative method: on each XMLHttpRequest, set a custom
++`X-CSRFToken` header to the value of the CSRF token. This is often easier,
++because many javascript frameworks provide hooks that allow headers to be set on
++every request. In jQuery, you can use the ``beforeSend`` hook as follows:
++
++.. code-block:: javascript
++
++    $.ajaxSetup({
++        beforeSend: function(xhr, settings) {
++            if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
++                // Only send the token to relative URLs i.e. locally.
++                xhr.setRequestHeader("X-CSRFToken",
++                                     $("#csrfmiddlewaretoken").val());
++            }
++        }
++    });
++
++Adding this to a javascript file that is included on your site will ensure that
++AJAX POST requests that are made via jQuery will not be caught by the CSRF
++protection. This will only work if you remember to include a form on the page,
++so that the input with id 'csrfmiddlewaretoken' will be found.
++
+ Exceptions
+ ----------
+ 
+@@ -61,10 +89,6 @@
+ response post-processing (``CsrfResponseMiddleware``) respectively.
+ They can be used individually if required.
+ 
+-You don't have to worry about doing this for most AJAX views. Any
+-request sent with "X-Requested-With: XMLHttpRequest" is automatically
+-exempt. (See the next section.)
+-
+ How it works
+ ============
+ 
+@@ -98,14 +122,6 @@
+ pages that are served as 'text/html' or 'application/xml+xhtml'
+ are modified.
+ 
+-The middleware tries to be smart about requests that come in via AJAX. Many
+-JavaScript toolkits send an "X-Requested-With: XMLHttpRequest" HTTP header;
+-these requests are detected and automatically *not* handled by this middleware.
+-We can do this safely because, in the context of a browser, the header can only
+-be added by using ``XMLHttpRequest``, and browsers already implement a
+-same-domain policy for ``XMLHttpRequest``. (Note that this is not secure if you
+-don't trust content within the same domain or subdomains.)
+-
+ 
+ .. _9.1.1 Safe Methods, HTTP 1.1, RFC 2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
+ 
--- python-django-1.1.1.orig/debian/patches/04_hyphen-manpage.diff
+++ python-django-1.1.1/debian/patches/04_hyphen-manpage.diff
@@ -0,0 +1,17 @@
+Forwarded-Upstream: not yet
+Author: Raphael Hertzog <hertzog@debian.org>
+Comment:
+ Fix a lintian I: message about improper usage of minus instead
+ of hyphen.
+
+--- a/docs/man/django-admin.1	2008-09-04 08:51:48.000000000 +0200
++++ b/docs/man/django-admin.1	2008-09-04 08:52:47.000000000 +0200
+@@ -153,7 +153,7 @@
+ .TP
+ .I \-e, \-\-extension=EXTENSION
+ The file extension(s) to examine (default: ".html", separate multiple
+-extensions with commas, or use -e multiple times).
++extensions with commas, or use \-e multiple times).
+ .TP
+ .I \-a, \-\-all
+ Process all available locales when using makemessages..SH "ENVIRONMENT"
--- python-django-1.1.1.orig/debian/patches/11_CVE-2011-0697.diff
+++ python-django-1.1.1/debian/patches/11_CVE-2011-0697.diff
@@ -0,0 +1,42 @@
+Origin: http://code.djangoproject.com/changeset/15472
+Description: Fixed XSS in AdminFileWidget. Added AdminFileWidgetTest() class
+ and tests
+Bug-Ubuntu: https://launchpad.net/bugs/719031
+
+Index: python-django-1.1.1/django/contrib/admin/widgets.py
+===================================================================
+--- python-django-1.1.1.orig/django/contrib/admin/widgets.py	2011-02-15 16:44:55.000000000 -0600
++++ python-django-1.1.1/django/contrib/admin/widgets.py	2011-02-15 16:44:59.000000000 -0600
+@@ -93,7 +93,7 @@
+         output = []
+         if value and hasattr(value, "url"):
+             output.append('%s <a target="_blank" href="%s">%s</a> <br />%s ' % \
+-                (_('Currently:'), value.url, value, _('Change:')))
++                (_('Currently:'), escape(value.url), escape(value), _('Change:')))
+         output.append(super(AdminFileWidget, self).render(name, value, attrs))
+         return mark_safe(u''.join(output))
+ 
+Index: python-django-1.1.1/tests/regressiontests/admin_widgets/tests.py
+===================================================================
+--- python-django-1.1.1.orig/tests/regressiontests/admin_widgets/tests.py	2011-02-15 16:44:55.000000000 -0600
++++ python-django-1.1.1/tests/regressiontests/admin_widgets/tests.py	2011-02-15 16:44:59.000000000 -0600
+@@ -130,3 +130,19 @@
+ class OldAdminForeignKeyWidgetChangeList(AdminForeignKeyWidgetChangeList):
+     urls = 'regressiontests.admin_widgets.urls2'
+     admin_root = '/deep/down/admin'
++
++class AdminFileWidgetTest(DjangoTestCase):
++    def test_render_escapes_html(self):
++        class StrangeFieldFile(object):
++            url = "something?chapter=1&sect=2&copy=3&lang=en"
++
++            def __unicode__(self):
++                return u'''something<div onclick="alert('oops')">.jpg'''
++
++        widget = widgets.AdminFileWidget()
++        field = StrangeFieldFile()
++        output = widget.render('myfile', field)
++        self.assertFalse(field.url in output)
++        self.assertTrue(u'href="something?chapter=1&amp;sect=2&amp;copy=3&amp;lang=en"' in output)
++        self.assertFalse(unicode(field) in output)
++        self.assertTrue(u'something&lt;div onclick=&quot;alert(&#39;oops&#39;)&quot;&gt;.jpg' in output)
