[thunderbird-lightning/el5: 15/15] Update to 3.3; sync with EL5 TB

Orion Poplawski orion at fedoraproject.org
Tue Oct 28 17:01:16 UTC 2014


commit 02ec8090ec5530171c1cb9e12af160034ee5e9ed
Merge: 7aa7389 049260e
Author: Orion Poplawski <orion at cora.nwra.com>
Date:   Tue Oct 28 11:00:27 2014 -0600

    Update to 3.3; sync with EL5 TB

 .gitignore                            |    6 +
 array_len.patch                       |   12 +
 disable-webm.patch                    |   11 +
 firefox-system-nss-3.16.2.patch       |   12 +
 mozilla-build-arm.patch               |   12 +-
 mozilla-python.patch                  | 3286 ++++++-
 mozilla-python3.patch                 |17643 +++++++++++++++++++++++++++++++++
 nullptr.patch                         |   11 +
 pango-backport.patch                  |   60 +
 rebase-dir.patch                      | 7577 ++++++++++++++
 remove-ogg.patch                      |  449 +
 rhbz-966424.patch                     |   23 +
 sources                               |    6 +-
 thunderbird-lightning-lightning.patch |    9 +
 thunderbird-lightning.spec            |  214 +-
 thunderbird-mozconfig                 |   22 +-
 thunderbird-objdir.patch              |   13 +
 xulrunner-10.0-secondary-ipc.patch    |   36 -
 xulrunner-24.0-jemalloc-ppc.patch     |   12 +
 xulrunner-24.0-s390-inlines.patch     |   12 +
 xulrunner-missing-pysqlite.patch      |   22 -
 21 files changed, 29210 insertions(+), 238 deletions(-)
---
diff --cc .gitignore
index 128fde8,b20d235..a84d5fe
--- a/.gitignore
+++ b/.gitignore
@@@ -43,8 -42,13 +43,14 @@@
  /thunderbird-24.1.0.source.tar.bz2
  /l10n-2.6.2.tar.xz
  /lightning-2.6.2.source.tar.bz2
 -/lighting-2.6.4.source.tar.bz2
 -/l10n-2.6.4.tar.xz
  /lightning-2.6.4.source.tar.bz2
 +/l10n-2.6.4.tar.xz
 +/setuptools-0.6c11-py2.4.egg
  /lightning-2.6.5.source.tar.bz2
  /l10n-2.6.5.tar.xz
+ /lightning-2.6.6.source.tar.bz2
+ /l10n-2.6.6.tar.xz
+ /lightning-3.3.source.tar.bz2
+ /l10n-3.3.tar.xz
+ /simplejson-2.1.1.tar.gz
++/virtualtools-1.7.2.zip
diff --cc mozilla-python3.patch
index 0000000,0000000..8530518
new file mode 100644
--- /dev/null
+++ b/mozilla-python3.patch
@@@ -1,0 -1,0 +1,17643 @@@
++diff -up comm-esr31/calendar/base/backend/icaljs/Makefile.in.python3 comm-esr31/calendar/base/backend/icaljs/Makefile.in
++--- comm-esr31/calendar/base/backend/icaljs/Makefile.in.python3	2014-07-17 18:04:04.000000000 -0600
+++++ comm-esr31/calendar/base/backend/icaljs/Makefile.in	2014-10-24 11:49:02.077039926 -0600
++@@ -36,7 +36,7 @@ libs:: $(BACKEND_MANIFESTS)
++ 	  fname=`basename $$i`; \
++ 	  dest=$(FINAL_TARGET)/components/$${fname}; \
++ 	  $(RM) -f $$dest; \
++-	  $(PYTHON) -m mozbuild.action.preprocessor $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i -o $$dest; \
+++	  $(PYTHON) $(topsrcdir)/mozilla/python/mozbuild/mozbuild/action/preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i -o $$dest; \
++ 	done
++ 
++ # The install target must use SYSINSTALL, which is NSINSTALL in copy mode.
++diff -up comm-esr31/calendar/base/backend/libical/build/Makefile.in.python3 comm-esr31/calendar/base/backend/libical/build/Makefile.in
++--- comm-esr31/calendar/base/backend/libical/build/Makefile.in.python3	2014-07-17 18:04:04.000000000 -0600
+++++ comm-esr31/calendar/base/backend/libical/build/Makefile.in	2014-10-24 11:49:00.807045321 -0600
++@@ -44,5 +44,5 @@ libs:: $(BACKEND_MANIFESTS)
++ 	  fname=`basename $$i`; \
++ 	  dest=$(FINAL_TARGET)/components/$${fname}; \
++ 	  $(RM) -f $$dest; \
++-	  $(PYTHON) -m mozbuild.action.preprocessor $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i -o $$dest; \
+++	  $(PYTHON) $(topsrcdir)/mozilla/python/mozbuild/mozbuild/action/preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i -o $$dest; \
++ 	done
++diff -up comm-esr31/client.mk.python3 comm-esr31/client.mk
++--- comm-esr31/client.mk.python3	2014-10-24 11:41:35.433880337 -0600
+++++ comm-esr31/client.mk	2014-10-24 11:41:35.437880320 -0600
++@@ -125,7 +125,8 @@ MOZCONFIG_OUT_FILTERED := $(filter-out $
++ 
++ # Automatically add -jN to make flags if not defined. N defaults to number of cores.
++ ifeq (,$(findstring -j,$(MOZ_MAKE_FLAGS)))
++-  cores=$(shell $(PYTHON) -c 'import multiprocessing; print(multiprocessing.cpu_count())')
+++  #cores=$(shell $(PYTHON) -c 'import multiprocessing; print(multiprocessing.cpu_count())')
+++  cores=1
++   MOZ_MAKE_FLAGS += -j$(cores)
++ endif
++ 
++diff -up comm-esr31/config/config.mk.python3 comm-esr31/config/config.mk
++--- comm-esr31/config/config.mk.python3	2014-07-17 18:04:05.000000000 -0600
+++++ comm-esr31/config/config.mk	2014-10-24 11:41:35.438880316 -0600
++@@ -794,4 +794,5 @@ DEFINES += -DNO_NSPR_10_SUPPORT
++ #
++ #   libs::
++ #       $(call py_action,purge_manifests,_build_manifests/purge/foo.manifest)
++-py_action = $(PYTHON) -m mozbuild.action.$(1) $(2)
+++py_action = $(PYTHON) $(topsrcdir)/mozilla/python/mozbuild/mozbuild/action/$(1).py $(2)
+++#py_action = $(PYTHON) -m mozbuild.action.$(1) $(2)
++diff -up comm-esr31/configure.in.python3 comm-esr31/configure.in
++--- comm-esr31/configure.in.python3	2014-07-17 18:04:05.000000000 -0600
+++++ comm-esr31/configure.in	2014-10-24 11:41:35.438880316 -0600
++@@ -7,6 +7,7 @@ dnl file, You can obtain one at http://m
++ dnl Process this file with autoconf to produce a configure script.
++ dnl ========================================================
++ 
+++dnl do some changes
++ AC_PREREQ(2.13)
++ AC_INIT(config/config.mk)
++ MOZILLA_SRCDIR=$topsrcdir/mozilla
++diff -up comm-esr31/mozilla/addon-sdk/source/python-lib/cuddlefish/__init__.py.python3 comm-esr31/mozilla/addon-sdk/source/python-lib/cuddlefish/__init__.py
++--- comm-esr31/mozilla/addon-sdk/source/python-lib/cuddlefish/__init__.py.python3	2014-07-17 18:05:06.000000000 -0600
+++++ comm-esr31/mozilla/addon-sdk/source/python-lib/cuddlefish/__init__.py	2014-10-24 11:41:35.438880316 -0600
++@@ -318,7 +318,10 @@ def parse_args(arguments, global_options
++         # a[0][1] = long name
++         names = []
++         for seq in (a, b):
++-            names.append(seq[0][0][1:] if seq[0][0] else seq[0][1][2:])
+++            if seq[0][0]:
+++              names.append(seq[0][0][1:])
+++            else:
+++              names.append(seq[0][1][2:])
++         return cmp(*names)
++ 
++     global_options.sort(name_cmp)
++diff -up comm-esr31/mozilla/addon-sdk/source/python-lib/cuddlefish/rdf.py.python3 comm-esr31/mozilla/addon-sdk/source/python-lib/cuddlefish/rdf.py
++--- comm-esr31/mozilla/addon-sdk/source/python-lib/cuddlefish/rdf.py.python3	2014-07-17 18:05:06.000000000 -0600
+++++ comm-esr31/mozilla/addon-sdk/source/python-lib/cuddlefish/rdf.py	2014-10-24 11:41:35.438880316 -0600
++@@ -131,7 +131,7 @@ def gen_manifest(template_root_dir, targ
++     # XPIs remain packed by default, but package.json can override that. The
++     # RDF format accepts "true" as True, anything else as False. We expect
++     # booleans in the .json file, not strings.
++-    manifest.set("em:unpack", "true" if target_cfg.get("unpack") else "false")
+++    manifest.set("em:unpack", ("false", "true")[target_cfg.get("unpack")])
++ 
++     for translator in target_cfg.get("translators", [ ]):
++         elem = dom.createElement("em:translator");
++diff -up comm-esr31/mozilla/addon-sdk/source/python-lib/cuddlefish/runner.py.python3 comm-esr31/mozilla/addon-sdk/source/python-lib/cuddlefish/runner.py
++--- comm-esr31/mozilla/addon-sdk/source/python-lib/cuddlefish/runner.py.python3	2014-07-17 18:05:06.000000000 -0600
+++++ comm-esr31/mozilla/addon-sdk/source/python-lib/cuddlefish/runner.py	2014-10-24 11:41:35.439880312 -0600
++@@ -293,8 +293,7 @@ class XulrunnerAppRunner(mozrunner.Runne
++ 
++     profile_class = XulrunnerAppProfile
++ 
++-    # This is a default, and will be overridden in the instance if
++-    # Firefox is used in XULRunner mode.
+++    # This is a default, and will be overridden in the instance if # Firefox is used in XULRunner mode.
++     names = ['xulrunner']
++ 
++     # Default location of XULRunner on OS X.
++diff -up comm-esr31/mozilla/b2g/simulator/build_xpi.py.python3 comm-esr31/mozilla/b2g/simulator/build_xpi.py
++--- comm-esr31/mozilla/b2g/simulator/build_xpi.py.python3	2014-07-17 18:05:06.000000000 -0600
+++++ comm-esr31/mozilla/b2g/simulator/build_xpi.py	2014-10-24 11:41:35.439880312 -0600
++@@ -40,9 +40,11 @@ class GaiaBuilder(object):
++     def override_prefs(self, srcfile):
++         # Note that each time we call `make profile` in gaia, a fresh new pref file is created
++         # cat srcfile >> profile/user.js
++-        with open(os.path.join(self.gaia_path, "profile", "user.js"), "a") as userJs:
+++        userJs = open(os.path.join(self.gaia_path, "profile", "user.js"), "a")
+++        if 1:
++             userJs.write(open(srcfile).read())
++ 
+++        userJs.close()
++ def process_package_overload(src, dst, version, app_buildid):
++     ensureParentDir(dst)
++     # First replace numeric version like '1.3'
++@@ -57,10 +59,14 @@ def process_package_overload(src, dst, v
++     }
++     pp = Preprocessor(defines=defines)
++     pp.do_filter("substitution")
++-    with open(dst, "w") as output:
++-        with open(src, "r") as input:
+++    output = open(dst, "w")
+++    if 1:
+++        input = open(src, "r")
+++        if 1:
++             pp.processFile(input=input, output=output)
++ 
+++        input.close()
+++    output.close()
++ def add_dir_to_zip(zip, top, pathInZip, blacklist=()):
++     zf = ZipFile(zip, "a")
++     for dirpath, subdirs, files in os.walk(top):
++diff -up comm-esr31/mozilla/browser/locales/filter.py.python3 comm-esr31/mozilla/browser/locales/filter.py
++--- comm-esr31/mozilla/browser/locales/filter.py.python3	2014-07-17 18:05:09.000000000 -0600
+++++ comm-esr31/mozilla/browser/locales/filter.py	2014-10-24 11:41:35.439880312 -0600
++@@ -20,12 +20,12 @@ def test(mod, path, entity = None):
++     if mod == "extensions/spellcheck":
++       return "ignore"
++     # browser
++-    return "ignore" if re.match(r"searchplugins\/.+\.xml", path) else "error"
+++    return ("error", "ignore")[re.match(r"searchplugins\/.+\.xml", path)]
++   if mod == "extensions/spellcheck":
++     # l10n ships en-US dictionary or something, do compare
++     return "error"
++   if path == "defines.inc":
++-    return "ignore" if entity == "MOZ_LANGPACK_CONTRIBUTORS" else "error"
+++    return ("error", "ignore")[entity == "MOZ_LANGPACK_CONTRIBUTORS"]
++ 
++   if mod == "browser" and path == "chrome/browser-region/region.properties":
++     # only region.properties exceptions remain, compare all others
++diff -up comm-esr31/mozilla/build/appini_header.py.python3 comm-esr31/mozilla/build/appini_header.py
++--- comm-esr31/mozilla/build/appini_header.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/appini_header.py	2014-10-24 11:41:35.439880312 -0600
++@@ -25,8 +25,15 @@ def main(file):
++             flags.add('NS_XRE_ENABLE_CRASH_REPORTER')
++     except: pass
++     appdata = dict(("%s:%s" % (s, o), config.get(s, o)) for s in config.sections() for o in config.options(s))
++-    appdata['flags'] = ' | '.join(flags) if flags else '0'
++-    appdata['App:profile'] = '"%s"' % appdata['App:profile'] if 'App:profile' in appdata else 'NULL'
+++    if flags:
+++      appdata['flags'] = ' | '.join(flags)
+++    else:
+++      appdata['flags'] = '0'
+++    if 'App:profile' in appdata:
+++      appdata['App:profile'] = '"%s"' % appdata['App:profile']
+++    else:
+++      appdata['App:profile'] = 'NULL'
+++    #appdata['flags'] = ' | '.join(flags)flags else '0' appdata['App:profile'] = '"%s"' % appdata['App:profile'] if 'App:profile' in appdata = ('NULL', )[]
++     expected = ('App:vendor', 'App:name', 'App:version', 'App:buildid',
++                 'App:id', 'Gecko:minversion', 'Gecko:maxversion')
++     missing = [var for var in expected if var not in appdata]
++diff -up comm-esr31/mozilla/build/autoconf/config.status.m4.python3 comm-esr31/mozilla/build/autoconf/config.status.m4
++--- comm-esr31/mozilla/build/autoconf/config.status.m4.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/autoconf/config.status.m4	2014-10-24 11:41:35.439880312 -0600
++@@ -133,7 +133,8 @@ rm confdefs.pytmp confdefs.h
++ cat >> $CONFIG_STATUS <<\EOF
++ ] ]
++ 
++-substs = [(name[1:-1], value[1:-1] if isinstance(value, types.StringTypes) else value) for name, value in [
+++substs = []
+++mylist = [
++ EOF
++ 
++ dnl The MOZ_DIVERSION_SUBST output diversion contains AC_SUBSTs, in the
++@@ -149,7 +150,12 @@ for ac_subst_arg in $_subconfigure_ac_su
++ done
++ 
++ cat >> $CONFIG_STATUS <<\EOF
++-] ]
+++]
+++for name, value in mylist:
+++  if isinstance(value, types.StringTypes):
+++    substs.append( (name[1:-1], value[1:-1]) )
+++  else:
+++    substs.append( (name[1:-1], value) )
++ 
++ dnl List of AC_DEFINEs that aren't to be exposed in ALLDEFINES
++ non_global_defines = [
++diff -up comm-esr31/mozilla/build/automationutils.py.python3 comm-esr31/mozilla/build/automationutils.py
++--- comm-esr31/mozilla/build/automationutils.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/automationutils.py	2014-10-24 11:41:35.440880307 -0600
++@@ -3,7 +3,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import with_statement
+++
++ import glob, logging, os, platform, shutil, subprocess, sys, tempfile, urllib2, zipfile
++ import base64
++ import re
++@@ -102,8 +102,7 @@ class ZipFileReader(object):
++ 
++   def _getnormalizedpath(self, path):
++     """
++-    Gets a normalized path from 'path' (or the current working directory if
++-    'path' is None). Also asserts that the path exists.
+++    Gets a normalized path from 'path' (or the current working directory if 'path' is None). Also asserts that the path exists.
++     """
++     if path is None:
++       path = os.curdir
++@@ -123,9 +122,11 @@ class ZipFileReader(object):
++       path = os.path.split(filename)[0]
++       if not os.path.isdir(path):
++         os.makedirs(path)
++-      with open(filename, "wb") as dest:
+++      dest = open(filename, "wb")
+++      if 1:
++         dest.write(self._zipfile.read(name))
++ 
+++      dest.close()
++   def namelist(self):
++     return self._zipfile.namelist()
++ 
++@@ -281,9 +282,11 @@ def dumpLeakLog(leakLogFile, filter = Fa
++   if not os.path.exists(leakLogFile):
++     return
++ 
++-  with open(leakLogFile, "r") as leaks:
+++  leaks = open(leakLogFile, "r")
+++  if 1:
++     leakReport = leaks.read()
++ 
+++  leaks.close()
++   # Only |XPCOM_MEM_LEAK_LOG| reports can be actually filtered out.
++   # Only check whether an actual leak was reported.
++   if filter and not "0 TOTAL " in leakReport:
++@@ -312,7 +315,8 @@ def processSingleLeakFile(leakLogFileNam
++   totalBytesLeaked = None
++   leakAnalysis = []
++   leakedObjectNames = []
++-  with open(leakLogFileName, "r") as leaks:
+++  leaks = open(leakLogFileName, "r")
+++  if 1:
++     for line in leaks:
++       if line.find("purposefully crash") > -1:
++         crashedOnPurpose = True
++@@ -340,6 +344,7 @@ def processSingleLeakFile(leakLogFileNam
++         leakedObjectNames.append(name)
++         leakAnalysis.append("TEST-INFO | leakcheck |%s leaked %d %s (%s bytes)"
++                             % (processString, numLeaked, name, bytesLeaked))
+++  leaks.close()
++   log.info('\n'.join(leakAnalysis))
++ 
++   if totalBytesLeaked is None:
++@@ -451,7 +456,11 @@ def systemMemory():
++ def environment(xrePath, env=None, crashreporter=True, debugger=False, dmdPath=None):
++   """populate OS environment variables for mochitest"""
++ 
++-  env = os.environ.copy() if env is None else env
+++  env = None
+++  if env is None:
+++    env = os.environ.copy()
+++  else:
+++    env = env
++ 
++   assert os.path.isabs(xrePath)
++ 
++diff -up comm-esr31/mozilla/build/checksums.py.python3 comm-esr31/mozilla/build/checksums.py
++--- comm-esr31/mozilla/build/checksums.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/checksums.py	2014-10-24 11:41:35.440880307 -0600
++@@ -3,7 +3,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import with_statement
+++
++ 
++ from optparse import OptionParser
++ import logging
++@@ -26,13 +26,15 @@ def digest_file(filename, digest, chunk_
++     if hashlib is not None:
++         logger.debug('Creating new %s object' % digest)
++         h = hashlib.new(digest)
++-        with open(filename, 'rb') as f:
+++        f = open(filename, 'rb')
+++        if 1:
++             while True:
++                 data = f.read(chunk_size)
++                 if not data:
++                     logger.debug('Finished reading in file')
++                     break
++                 h.update(data)
+++        f.close()
++         hash = h.hexdigest()
++         logger.debug('Hash for %s is %s' % (filename, hash))
++         return hash
++@@ -65,7 +67,8 @@ def process_files(files, output_filename
++                      output_filename)
++     else:
++         logger.debug('Creating a new checksums file "%s"' % output_filename)
++-    with open(output_filename, 'w+') as output:
+++    output = open(output_filename, 'w+')
+++    if 1:
++         for file in files:
++             if os.path.isdir(file):
++                 logger.warn('%s is a directory, skipping' % file)
++@@ -85,6 +88,7 @@ def process_files(files, output_filename
++                                                      os.path.getsize(file),
++                                                      short_file)
++ 
+++    output.close()
++ def setup_logging(level=logging.DEBUG):
++     '''This function sets up the logging module using a speficiable logging
++     module logging level.  The default log level is DEBUG.
++diff -up comm-esr31/mozilla/build/compare-mozconfig/compare-mozconfigs.py.python3 comm-esr31/mozilla/build/compare-mozconfig/compare-mozconfigs.py
++--- comm-esr31/mozilla/build/compare-mozconfig/compare-mozconfigs.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/compare-mozconfig/compare-mozconfigs.py	2014-10-24 11:41:35.440880307 -0600
++@@ -5,7 +5,7 @@
++ 
++ # originally from http://hg.mozilla.org/build/tools/file/4ab9c1a4e05b/scripts/release/compare-mozconfigs.py
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import logging
++ import os
++diff -up comm-esr31/mozilla/build/compare-mozconfig/compare-mozconfigs-wrapper.py.python3 comm-esr31/mozilla/build/compare-mozconfig/compare-mozconfigs-wrapper.py
++--- comm-esr31/mozilla/build/compare-mozconfig/compare-mozconfigs-wrapper.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/compare-mozconfig/compare-mozconfigs-wrapper.py	2014-10-24 11:41:35.440880307 -0600
++@@ -3,7 +3,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import subprocess
++ import sys
++diff -up comm-esr31/mozilla/build/gyp.mozbuild.python3 comm-esr31/mozilla/build/gyp.mozbuild
++--- comm-esr31/mozilla/build/gyp.mozbuild.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/gyp.mozbuild	2014-10-24 11:41:35.440880307 -0600
++@@ -8,10 +8,10 @@ gyp_vars = {
++     'build_with_mozilla': 1,
++     'build_with_chromium': 0,
++     'use_official_google_api_keys': 0,
++-    'have_clock_monotonic': 1 if CONFIG['HAVE_CLOCK_MONOTONIC'] else 0,
++-    'have_ethtool_cmd_speed_hi': 1 if CONFIG['MOZ_WEBRTC_HAVE_ETHTOOL_SPEED_HI'] else 0,
++-    'include_alsa_audio': 1 if CONFIG['MOZ_ALSA'] else 0,
++-    'include_pulse_audio': 1 if CONFIG['MOZ_PULSEAUDIO'] else 0,
+++    'have_clock_monotonic': (0, 1)[CONFIG['HAVE_CLOCK_MONOTONIC'] == '1'],
+++    'have_ethtool_cmd_speed_hi': (0, 1)[CONFIG['MOZ_WEBRTC_HAVE_ETHTOOL_SPEED_HI'] == '1'],
+++    'include_alsa_audio': (0, 1)[CONFIG['MOZ_ALSA'] == '1'],
+++    'include_pulse_audio': (0, 1)[CONFIG['MOZ_PULSEAUDIO'] == '1'],
++     # basic stuff for everything
++     'include_internal_video_render': 0,
++     'clang_use_chrome_plugins': 0,
++@@ -26,7 +26,7 @@ gyp_vars = {
++     'build_libvpx': 0,
++     'build_libyuv': 0,
++     'libyuv_dir': '/media/libyuv',
++-    'yuv_disable_avx2': 0 if CONFIG['HAVE_X86_AVX2'] else 1,
+++    'yuv_disable_avx2': (1, 0)[CONFIG['HAVE_X86_AVX2'] == '1'],
++ 
++     # saves 4MB when webrtc_trace is off
++     'enable_lazy_trace_alloc': 1,
++@@ -57,7 +57,7 @@ os = CONFIG['OS_TARGET']
++ if os == 'WINNT':
++     gyp_vars.update(
++         MSVS_VERSION=CONFIG['_MSVS_VERSION'],
++-        MSVS_OS_BITS=64 if CONFIG['HAVE_64BIT_OS'] else 32,
+++        MSVS_OS_BITS=(32, 64)[CONFIG['HAVE_64BIT_OS'] == '1'],
++     )
++ elif os == 'Android':
++     if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
++@@ -73,9 +73,9 @@ elif os == 'Android':
++ 
++ flavors = {
++     'WINNT': 'win',
++-    'Android': 'linux' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' else 'android',
+++    'Android': ('android', 'linux')[CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk'],
++     'Linux': 'linux',
++-    'Darwin': 'mac' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa' else 'ios',
+++    'Darwin': ('ios', 'mac')[CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa'],
++     'SunOS': 'solaris',
++     'GNU/kFreeBSD': 'freebsd',
++     'DragonFly': 'dragonfly',
++diff -up comm-esr31/mozilla/build/link.py.python3 comm-esr31/mozilla/build/link.py
++--- comm-esr31/mozilla/build/link.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/link.py	2014-10-24 11:41:35.441880303 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import with_statement
+++
++ import os, subprocess, sys, threading, time
++ from win32 import procmem
++ 
++@@ -25,9 +25,11 @@ def measure_vsize_threadfunc(proc, outpu
++           sys.stdout.flush()
++           idleTime = 0
++     print "TinderboxPrint: linker max vsize: %d" % maxvsize
++-    with open(output_file, "w") as f:
+++    f = open(output_file, "w")
+++    if 1:
++         f.write("%d\n" % maxvsize)
++ 
+++    f.close()
++ def measure_link_vsize(output_file, args):
++     """
++     Execute |args|, and measure the maximum virtual memory usage of the process,
++diff -up comm-esr31/mozilla/build/mach_bootstrap.py.python3 comm-esr31/mozilla/build/mach_bootstrap.py
++--- comm-esr31/mozilla/build/mach_bootstrap.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/mach_bootstrap.py	2014-10-24 11:41:35.441880303 -0600
++@@ -2,7 +2,11 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ import os
++ import platform
++@@ -150,7 +154,7 @@ def bootstrap(topsrcdir, mozilla_dir=Non
++         if not os.path.exists(state_env_dir):
++             print('Creating global state directory from environment variable: %s'
++                 % state_env_dir)
++-            os.makedirs(state_env_dir, mode=0o770)
+++            os.makedirs(state_env_dir, mode=0770)
++             print('Please re-run mach.')
++             sys.exit(1)
++         state_dir = state_env_dir
++diff -up comm-esr31/mozilla/build/pgo/genpgocert.py.python3 comm-esr31/mozilla/build/pgo/genpgocert.py
++--- comm-esr31/mozilla/build/pgo/genpgocert.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/pgo/genpgocert.py	2014-10-24 11:41:35.441880303 -0600
++@@ -52,7 +52,7 @@ def runUtil(util, args, inputdata = None
++     else:
++       env[pathvar] = app_path
++   proc = subprocess.Popen([util] + args, env=env,
++-                          stdin=subprocess.PIPE if inputdata else None)
+++                          stdin=(None, subprocess.PIPE)[inputdata])
++   proc.communicate(inputdata)
++   return proc.returncode
++ 
++@@ -68,7 +68,8 @@ def createCertificateAuthority(build, sr
++ 
++   #TODO: mozfile.TemporaryDirectory
++   tempDbDir = tempfile.mkdtemp()
++-  with NamedTemporaryFile() as pwfile, NamedTemporaryFile() as rndfile:
+++  pwfile, NamedTemporaryFile() = rndfile = NamedTemporaryFile().__enter__()
+++  if 1:
++     pgoCAModulePathSrc = os.path.join(srcDir, "pgoca.p12")
++     pgoCAPathSrc = os.path.join(srcDir, "pgoca.ca")
++ 
++@@ -92,6 +93,7 @@ def createCertificateAuthority(build, sr
++     if status:
++       return status
++ 
+++  rndfile.__exit__(0, 0, 0)
++   shutil.rmtree(tempDbDir)
++   return 0
++ 
++@@ -100,7 +102,8 @@ def createSSLServerCertificate(build, sr
++   certutil = build.get_binary_path(what="certutil")
++   pk12util = build.get_binary_path(what="pk12util")
++ 
++-  with NamedTemporaryFile() as pwfile, NamedTemporaryFile() as rndfile:
+++  pwfile, NamedTemporaryFile() = rndfile = NamedTemporaryFile().__enter__()
+++  if 1:
++     pgoCAPath = os.path.join(srcDir, "pgoca.p12")
++ 
++     pwfile.write("\n")
++@@ -159,6 +162,7 @@ def createSSLServerCertificate(build, sr
++       if status:
++         return status
++ 
+++  rndfile.__exit__(0, 0, 0)
++   return 0
++ 
++ if len(sys.argv) == 1:
++diff -up comm-esr31/mozilla/build/pymake/pymake/builtins.py.python3 comm-esr31/mozilla/build/pymake/pymake/builtins.py
++--- comm-esr31/mozilla/build/pymake/pymake/builtins.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/pymake/pymake/builtins.py	2014-10-24 11:41:35.441880303 -0600
++@@ -109,7 +109,10 @@ def touch(args):
++                     y += 1900
++                 return y
++             if m.group(f) is None:
++-                return localtime()[0] if f == 'Y' else 0
+++                if f == 'Y':
+++                  return localtime()[0]
+++                else:
+++                  return 0
++             return int(m.group(f))
++         time = [normalized_field(m, f) for f in ['Y', 'M', 'D', 'h', 'm', 's']] + [0, 0, -1]
++         time = mktime(time)
++diff -up comm-esr31/mozilla/build/pymake/pymake/data.py.python3 comm-esr31/mozilla/build/pymake/pymake/data.py
++--- comm-esr31/mozilla/build/pymake/pymake/data.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/pymake/pymake/data.py	2014-10-24 11:41:35.442880299 -0600
++@@ -53,7 +53,10 @@ def getmtime(path):
++ def stripdotslash(s):
++     if s.startswith('./'):
++         st = s[2:]
++-        return st if st != '' else '.'
+++        if st != '':
+++          return st
+++        else:
+++          return '.'
++     return s
++ 
++ def stripdotslashes(sl):
++diff -up comm-esr31/mozilla/build/pymake/pymake/functions.py.python3 comm-esr31/mozilla/build/pymake/pymake/functions.py
++--- comm-esr31/mozilla/build/pymake/pymake/functions.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/pymake/pymake/functions.py	2014-10-24 11:41:35.442880299 -0600
++@@ -27,8 +27,10 @@ def emit_expansions(descend, *expansions
++ class Function(object):
++     """
++     An object that represents a function call. This class is always subclassed
++-    with the following methods and attributes:
+++    the following methods and attributes.__enter__()
+++    if 1:
++ 
+++    the following methods and attributes.__exit__(0, 0, 0)
++     minargs = minimum # of arguments
++     maxargs = maximum # of arguments (0 means unlimited)
++ 
++diff -up comm-esr31/mozilla/build/pymake/pymake/process.py.python3 comm-esr31/mozilla/build/pymake/pymake/process.py
++--- comm-esr31/mozilla/build/pymake/pymake/process.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/pymake/pymake/process.py	2014-10-24 11:41:35.442880299 -0600
++@@ -382,7 +382,7 @@ class PythonJob(Job):
++             if self.module not in sys.modules:
++                 try:
++                     __import__(self.module)
++-                except Exception as e:
+++                except Exception, e:
++                     print >>sys.stderr, 'Error importing %s: %s' % (
++                         self.module, e)
++                     return -127
++@@ -396,7 +396,7 @@ class PythonJob(Job):
++                 print >>sys.stderr, (
++                     "Native command '%s %s' returned value '%s'" %
++                     (self.module, self.method, rv))
++-                return (rv if isinstance(rv, int) else 1)
+++                return ((1, rv)[isinstance(rv, int)])
++ 
++         except PythonException, e:
++             print >>sys.stderr, e
++diff -up comm-esr31/mozilla/build/pymake/tests/formattingtests.py.python3 comm-esr31/mozilla/build/pymake/tests/formattingtests.py
++--- comm-esr31/mozilla/build/pymake/tests/formattingtests.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/pymake/tests/formattingtests.py	2014-10-24 11:41:35.442880299 -0600
++@@ -253,9 +253,11 @@ class MakefileCorupusTest(TestBase):
++                 continue
++ 
++             source = None
++-            with open(makefile, 'rU') as fh:
+++            fh = open(makefile, 'rU')
+++            if 1:
++                 source = fh.read()
++ 
+++            fh.close()
++             try:
++                 yield (makefile, source, parsestring(source, makefile))
++             except SyntaxError:
++diff -up comm-esr31/mozilla/build/pymake/tests/pycmd.py.python3 comm-esr31/mozilla/build/pymake/tests/pycmd.py
++--- comm-esr31/mozilla/build/pymake/tests/pycmd.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/pymake/tests/pycmd.py	2014-10-24 11:41:35.443880295 -0600
++@@ -1,15 +1,20 @@
++ import os, sys, subprocess
++ 
++ def writetofile(args):
++-  with open(args[0], 'w') as f:
+++  f = open(args[0], 'w')
+++  if 1:
++     f.write(' '.join(args[1:]))
++ 
+++  f.close()
++ def writeenvtofile(args):
++-  with open(args[0], 'w') as f:
+++  f = open(args[0], 'w')
+++  if 1:
++     f.write(os.environ[args[1]])
++ 
+++  f.close()
++ def writesubprocessenvtofile(args):
++-  with open(args[0], 'w') as f:
+++  f = open(args[0], 'w')
+++  if 1:
++     p = subprocess.Popen([sys.executable, "-c",
++                           "import os; print os.environ['%s']" % args[1]],
++                           stdout=subprocess.PIPE, stderr=subprocess.PIPE)
++@@ -17,11 +22,12 @@ def writesubprocessenvtofile(args):
++     assert p.returncode == 0
++     f.write(stdout)
++ 
+++  f.close()
++ def convertasplode(arg):
++   try:
++     return int(arg)
++   except:
++-    return (None if arg == "None" else arg)
+++    return ((arg, None)[arg == "None"])
++ 
++ def asplode(args):
++   arg0 = convertasplode(args[0])
++diff -up comm-esr31/mozilla/build/pymake/tests/subdir/pymod.py.python3 comm-esr31/mozilla/build/pymake/tests/subdir/pymod.py
++--- comm-esr31/mozilla/build/pymake/tests/subdir/pymod.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/pymake/tests/subdir/pymod.py	2014-10-24 11:41:35.443880295 -0600
++@@ -1,5 +1,8 @@
++ import testmodule
++ 
++ def writetofile(args):
++-  with open(args[0], 'w') as f:
+++  f = open(args[0], 'w')
+++  if 1:
++     f.write(' '.join(args[1:]))
+++  f.close()
+++
++diff -up comm-esr31/mozilla/build/subconfigure.py.python3 comm-esr31/mozilla/build/subconfigure.py
++--- comm-esr31/mozilla/build/subconfigure.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/subconfigure.py	2014-10-24 11:41:35.443880295 -0600
++@@ -63,11 +63,13 @@ PRECIOUS_VARS = set([
++ def maybe_clear_cache():
++     comment = re.compile(r'^\s+#')
++     cache = {}
++-    with open('config.cache') as f:
+++    f = open('config.cache')
+++    if 1:
++         for line in f.readlines():
++             if not comment.match(line) and '=' in line:
++                 key, value = line.split('=', 1)
++                 cache[key] = value
+++    f.close()
++     for precious in PRECIOUS_VARS:
++         entry = 'ac_cv_env_%s_value' % precious
++         if entry in cache and (not precious in os.environ or os.environ[precious] != cache[entry]):
++@@ -87,9 +89,10 @@ def dump(dump_file, shell):
++ 
++     # Scan the config.status output for information about configuration files
++     # it generates.
++-    config_status_output = subprocess.check_output(
++-        [shell, '-c', './config.status --help'],
++-        stderr=subprocess.STDOUT).splitlines()
+++    config_status_output = subprocess.Popen([shell, '-c', './config.status --help'], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0].splitlines()
+++    #config_status_output = subprocess.check_output(
+++    #    [shell, '-c', './config.status --help'],
+++    #    stderr=subprocess.STDOUT).splitlines()
++     state = None
++     for line in config_status_output:
++         if line.startswith('Configuration') and line.endswith(':'):
++@@ -101,10 +104,12 @@ def dump(dump_file, shell):
++                 if os.path.isfile(f):
++                     config_files.append(File(f))
++ 
++-    with open(dump_file, 'wb') as f:
+++    f = open(dump_file, 'wb')
+++    if 1:
++         pickle.dump(config_files, f)
++ 
++ 
+++    f.close()
++ def adjust(dump_file, configure):
++     if not os.path.exists(dump_file):
++         return
++@@ -112,8 +117,10 @@ def adjust(dump_file, configure):
++     config_files = []
++ 
++     try:
++-        with open(dump_file, 'rb') as f:
+++        f = open(dump_file, 'rb')
+++        if 1:
++             config_files = pickle.load(f)
+++        f.close()
++     except Exception:
++         pass
++ 
++@@ -134,4 +141,7 @@ if __name__ == '__main__':
++     if sys.argv[1] == 'dump':
++         dump(CONFIG_DUMP, sys.argv[2])
++     elif sys.argv[1] == 'adjust':
++-        adjust(CONFIG_DUMP, sys.argv[2] if len(sys.argv) > 2 else None)
+++        if len(sys.argv) > 2:
+++           adjust(CONFIG_DUMP, sys.argv[2])
+++        else:
+++           adjust(CONFIG_DUMP,  None)
++diff -up comm-esr31/mozilla/build/unix/add_phony_targets.py.python3 comm-esr31/mozilla/build/unix/add_phony_targets.py
++--- comm-esr31/mozilla/build/unix/add_phony_targets.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/unix/add_phony_targets.py	2014-10-24 11:41:35.443880295 -0600
++@@ -24,10 +24,12 @@ def add_phony_targets(path):
++     phony_targets = deps - targets
++     if not phony_targets:
++         return
++-    with open(path, 'a') as f:
+++    f = open(path, 'a')
+++    if 1:
++         f.writelines('%s:\n' % d for d in phony_targets)
++ 
++ 
+++    f.close()
++ if __name__ == '__main__':
++     for f in sys.argv[1:]:
++         add_phony_targets(f)
++diff -up comm-esr31/mozilla/build/unix/build-clang/tooltool.py.python3 comm-esr31/mozilla/build/unix/build-clang/tooltool.py
++--- comm-esr31/mozilla/build/unix/build-clang/tooltool.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/unix/build-clang/tooltool.py	2014-10-24 11:41:35.443880295 -0600
++@@ -86,8 +86,10 @@ class FileRecord(object):
++ 
++     def validate_digest(self):
++         if self.present():
++-            with open(self.filename, 'rb') as f:
+++            f = open(self.filename, 'rb')
+++            if 1:
++                 return self.digest == digest_file(f, self.algorithm)
+++            f.close()
++         else:
++             log.debug("trying to validate digest on a missing file, %s', self.filename")
++             raise MissingFileException(filename=self.filename)
++@@ -265,9 +267,11 @@ def open_manifest(manifest_file):
++     """I know how to take a filename and load it into a Manifest object"""
++     if os.path.exists(manifest_file):
++         manifest = Manifest()
++-        with open(manifest_file) as f:
+++        f = open(manifest_file)
+++        if 1:
++             manifest.load(f)
++             log.debug("loaded manifest from file '%s'" % manifest_file)
+++        f.close()
++         return manifest
++     else:
++         log.debug("tried to load absent file '%s' as manifest" % manifest_file)
++@@ -282,8 +286,7 @@ def list_manifest(manifest_file):
++         log.error("failed to load manifest file at '%s'" % manifest_file)
++         return False
++     for f in manifest.file_records:
++-        print "%s\t%s\t%s" % ("P" if f.present() else "-",
++-                              "V" if f.present() and f.validate() else "-",
+++        print "%s\t%s\t%s" % (("P", "-")[f.present() else "-", "V" if f.present() and f.validate()],
++                               f.filename)
++     return True
++ 
++@@ -345,8 +348,10 @@ def add_files(manifest_file, algorithm,
++             log.debug("added '%s' to manifest" % filename)
++         else:
++             all_files_added = False
++-    with open(manifest_file, 'wb') as output:
+++    output = open(manifest_file, 'wb')
+++    if 1:
++         new_manifest.dump(output, fmt='json')
+++    output.close()
++     return all_files_added
++ 
++ 
++@@ -364,8 +369,10 @@ def fetch_file(base_url, file_record, ov
++             log.info("overwriting '%s' as requested" % file_record.filename)
++         else:
++             # All of the following is for a useful error message
++-            with open(file_record.filename, 'rb') as f:
+++            f = open(file_record.filename, 'rb')
+++            if 1:
++                 d = digest_file(f, file_record.algorithm)
+++            f.close()
++             log.error("digest mismatch between manifest(%s...) and local file(%s...)" % \
++                     (file_record.digest[:8], d[:8]))
++             log.debug("full digests: manifest (%s) local file (%s)" % (file_record.digest, d))
++@@ -382,7 +389,8 @@ def fetch_file(base_url, file_record, ov
++     try:
++         f = urllib2.urlopen(url)
++         log.debug("opened %s for reading" % url)
++-        with open(file_record.filename, 'wb') as out:
+++        out = open(file_record.filename, 'wb')
+++        if 1:
++             k = True
++             size = 0
++             while k:
++@@ -398,7 +406,8 @@ def fetch_file(base_url, file_record, ov
++                             file_record.filename, file_record.size - size))
++                 return False
++             log.info("fetched %s" % file_record.filename)
++-    except (urllib2.URLError, urllib2.HTTPError) as e:
+++        out.close()
+++    except (urllib2.URLError, urllib2.HTTPError), e:
++         log.error("failed to fetch '%s': %s" % (file_record.filename, e),
++                   exc_info=True)
++         return False
++@@ -544,7 +553,7 @@ def main():
++             try:
++                 options[option] = cfg_file.get('general', option)
++                 log.debug("read '%s' as '%s' from cfg_file" % (option, options[option]))
++-            except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e:
+++            except (ConfigParser.NoSectionError, ConfigParser.NoOptionError), e:
++                 log.debug("%s in config file" % e, exc_info=True)
++ 
++     if not options.has_key('manifest'):
++@@ -552,7 +561,7 @@ def main():
++ 
++     if len(args) < 1:
++         parser.error('You must specify a command')
++-    exit(0 if process_command(options, args) else 1)
+++    exit((1, 0)[process_command(options, args)])
++ 
++ if __name__ == "__main__":
++     main()
++diff -up comm-esr31/mozilla/build/util/hg.py.python3 comm-esr31/mozilla/build/util/hg.py
++--- comm-esr31/mozilla/build/util/hg.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/util/hg.py	2014-10-24 11:41:35.444880290 -0600
++@@ -140,8 +140,7 @@ def clone(repo, dest, branch=None, revis
++     If `revision` is set, only the specified revision and its ancestors will
++     be cloned.
++ 
++-    If `update_dest` is set, then `dest` will be updated to `revision` if
++-    set, otherwise to `branch`, otherwise to the head of default.
+++    If `update_dest` is set, then `dest` will be updated to `revision` if set, otherwise to `branch`, otherwise to the head of default.
++ 
++     If `mirrors` is set, will try and clone from the mirrors before
++     cloning from `repo`.
++@@ -242,8 +241,7 @@ def common_args(revision=None, branch=No
++ def pull(repo, dest, update_dest=True, mirrors=None, **kwargs):
++     """Pulls changes from hg repo and places it in `dest`.
++ 
++-    If `update_dest` is set, then `dest` will be updated to `revision` if
++-    set, otherwise to `branch`, otherwise to the head of default.
+++    If `update_dest` is set, then `dest` will be updated to `revision` if set, otherwise to `branch`, otherwise to the head of default.
++ 
++     If `mirrors` is set, will try and pull from the mirrors first before
++     `repo`."""
++@@ -262,8 +260,7 @@ def pull(repo, dest, update_dest=True, m
++     repo = _make_absolute(repo)
++     cmd = ['hg', 'pull']
++     # Don't pass -r to "hg pull", except when it's a valid HG revision.
++-    # Pulling using tag names is dangerous: it uses the local .hgtags, so if
++-    # the tag has moved on the remote side you won't pull the new revision the
+++    # Pulling using tag names is dangerous: it uses the local .hgtags, so if # the tag has moved on the remote side you won't pull the new revision the
++     # remote tag refers to.
++     pull_kwargs = kwargs.copy()
++     if 'revision' in pull_kwargs and \
++diff -up comm-esr31/mozilla/build/valgrind/mach_commands.py.python3 comm-esr31/mozilla/build/valgrind/mach_commands.py
++--- comm-esr31/mozilla/build/valgrind/mach_commands.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/valgrind/mach_commands.py	2014-10-24 11:41:35.444880290 -0600
++@@ -2,7 +2,11 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ import os
++ import re
++@@ -62,7 +66,8 @@ class MachCommands(MachCommandBase):
++         httpd = MozHttpd(docroot=os.path.join(build_dir, 'pgo'))
++         httpd.start(block=False)
++ 
++-        with TemporaryDirectory() as profilePath:
+++        profilePath = TemporaryDirectory().__enter__()
+++        if 1:
++             #TODO: refactor this into mozprofile
++             prefpath = os.path.join(self.topsrcdir, 'testing', 'profiles', 'prefs_general.js')
++             prefs = {}
++@@ -156,3 +161,5 @@ class MachCommands(MachCommandBase):
++                 httpd.stop()
++ 
++             return status
+++        profilePath.__exit__(0, 0, 0)
+++
++diff -up comm-esr31/mozilla/build/valgrind/output_handler.py.python3 comm-esr31/mozilla/build/valgrind/output_handler.py
++--- comm-esr31/mozilla/build/valgrind/output_handler.py.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/valgrind/output_handler.py	2014-10-24 11:41:35.444880290 -0600
++@@ -2,7 +2,11 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ import re
++ 
++@@ -28,8 +32,7 @@ class OutputHandler(object):
++     It buffers these lines from which text is extracted so that the
++     TEST-UNEXPECTED-FAIL message can be printed before the full error.
++ 
++-    Parsing the Valgrind output isn't ideal, and it may break in the future if
++-    Valgrind changes the format of the messages, or introduces new error kinds.
+++    Parsing the Valgrind output isn't ideal, and it may break in the future if Valgrind changes the format of the messages, or introduces new error kinds.
++     To protect against this, we also count how many lines containing
++     "<insert_a_suppression_name_here>" are seen. Thanks to the use of
++     --gen-suppressions=yes, exactly one of these lines is present per error. If
++diff -up comm-esr31/mozilla/build/virtualenv_packages.txt.python3 comm-esr31/mozilla/build/virtualenv_packages.txt
++--- comm-esr31/mozilla/build/virtualenv_packages.txt.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/build/virtualenv_packages.txt	2014-10-24 11:41:35.444880290 -0600
++@@ -22,3 +22,5 @@ copy:build/buildconfig.py
++ packages.txt:testing/mozbase/packages.txt
++ objdir:build
++ gyp.pth:media/webrtc/trunk/tools/gyp/pylib
+++rebase.pth:rebase
+++action.pth:python/mozbuild/action
++diff -up comm-esr31/mozilla/client.mk.python3 comm-esr31/mozilla/client.mk
++--- comm-esr31/mozilla/client.mk.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/client.mk	2014-10-24 11:41:35.444880290 -0600
++@@ -137,7 +137,8 @@ endif
++ 
++ # Automatically add -jN to make flags if not defined. N defaults to number of cores.
++ ifeq (,$(findstring -j,$(MOZ_MAKE_FLAGS)))
++-  cores=$(shell $(PYTHON) -c 'import multiprocessing; print(multiprocessing.cpu_count())')
+++  #cores=$(shell $(PYTHON) -c 'import multiprocessing; print(multiprocessing.cpu_count())')
+++  cores=1 # $(shell $(PYTHON) -c 'import multiprocessing; print(multiprocessing.cpu_count())')
++   MOZ_MAKE_FLAGS += -j$(cores)
++ endif
++ 
++diff -up comm-esr31/mozilla/config/configobj.py.python3 comm-esr31/mozilla/config/configobj.py
++--- comm-esr31/mozilla/config/configobj.py.python3	2014-07-17 18:05:11.000000000 -0600
+++++ comm-esr31/mozilla/config/configobj.py	2014-10-24 11:41:35.445880286 -0600
++@@ -542,8 +542,7 @@ class Section(dict):
++         (We have to special case 'Section' instances - which are also dicts)
++         
++         Keys must be strings.
++-        Values need only be strings (or lists of strings) if
++-        ``main.stringify`` is set.
+++        Values need only be strings (or lists of strings) if ``main.stringify`` is set.
++         
++         `unrepr`` must be set when setting a value to a dictionary, without
++         creating a new sub-section.
++diff -up comm-esr31/mozilla/config/expandlibs_exec.py.python3 comm-esr31/mozilla/config/expandlibs_exec.py
++--- comm-esr31/mozilla/config/expandlibs_exec.py.python3	2014-07-17 18:05:11.000000000 -0600
+++++ comm-esr31/mozilla/config/expandlibs_exec.py	2014-10-24 11:41:35.445880286 -0600
++@@ -20,7 +20,7 @@ With the --symbol-order argument, follow
++ relevant linker options to change the order in which the linker puts the
++ symbols appear in the resulting binary. Only works for ELF targets.
++ '''
++-from __future__ import with_statement
+++
++ import sys
++ import os
++ from expandlibs import (
++@@ -186,8 +186,10 @@ class ExpandArgsMore(ExpandArgs):
++     def orderSymbols(self, order):
++         '''Given a file containing a list of symbols, adds the appropriate
++         argument to make the linker put the symbols in that order.'''
++-        with open(order) as file:
+++        file = open(order)
+++        if 1:
++             sections = self._getOrderedSections([l.strip() for l in file.readlines() if l.strip()])
+++        file.close()
++         split_sections = {}
++         linked_sections = [s[0] for s in SECTION_INSERT_BEFORE]
++         for s in sections:
++@@ -292,8 +294,10 @@ def print_command(out, args):
++     print >>out, "Executing: " + " ".join(args)
++     for tmp in [f for f in args.tmp if os.path.isfile(f)]:
++         print >>out, tmp + ":"
++-        with open(tmp) as file:
+++        file = open(tmp)
+++        if 1:
++             print >>out, "".join(["    " + l for l in file.readlines()])
+++        file.close()
++     out.flush()
++ 
++ def main():
++@@ -322,7 +326,8 @@ def main():
++             deps.pop(0)
++         # Remove command
++         deps.pop(0)
++-    with ExpandArgsMore(args) as args:
+++    args = ExpandArgsMore(args).__enter__()
+++    if 1:
++         if options.extract:
++             args.extract()
++         if options.symbol_order:
++@@ -344,6 +349,7 @@ def main():
++         sys.stderr.flush()
++         if proc.returncode:
++             exit(proc.returncode)
+++    args.__exit__(0, 0, 0)
++     if not options.depend:
++         return
++     ensureParentDir(options.depend)
++@@ -355,8 +361,10 @@ def main():
++     if len(deps) != len(no_dynamic_lib):
++         mk.create_rule(['%s_order_only' % options.target]).add_dependencies(dep for dep in deps if isDynamicLib(dep))
++ 
++-    with open(options.depend, 'w') as depfile:
+++    depfile = open(options.depend, 'w')
+++    if 1:
++         mk.dump(depfile, removal_guard=True)
++ 
+++    depfile.close()
++ if __name__ == '__main__':
++     main()
++diff -up comm-esr31/mozilla/config/expandlibs_gen.py.python3 comm-esr31/mozilla/config/expandlibs_gen.py
++--- comm-esr31/mozilla/config/expandlibs_gen.py.python3	2014-07-17 18:05:11.000000000 -0600
+++++ comm-esr31/mozilla/config/expandlibs_gen.py	2014-10-24 11:41:35.445880286 -0600
++@@ -5,7 +5,7 @@
++ '''Given a list of object files and library names, prints a library
++ descriptor to standard output'''
++ 
++-from __future__ import with_statement
+++
++ import sys
++ import os
++ import expandlibs_config as conf
++@@ -39,12 +39,17 @@ if __name__ == '__main__':
++         raise Exception("Missing option: -o")
++ 
++     ensureParentDir(options.output)
++-    with open(options.output, 'w') as outfile:
+++    outfile = open(options.output, 'w')
+++    if 1:
++         print >>outfile, generate(args)
+++    outfile.close()
++     if options.depend:
++         ensureParentDir(options.depend)
++-        with open(options.depend, 'w') as depfile:
+++        depfile = open(options.depend, 'w')
+++        if 1:
++             deps = ExpandLibsDeps(args)
++             depfile.write("%s : %s\n" % (options.output, ' '.join(deps)))
++             for dep in deps:
++                 depfile.write("%s :\n" % dep)
+++        depfile.close()
+++
++diff -up comm-esr31/mozilla/config/expandlibs.py.python3 comm-esr31/mozilla/config/expandlibs.py
++--- comm-esr31/mozilla/config/expandlibs.py.python3	2014-07-17 18:05:11.000000000 -0600
+++++ comm-esr31/mozilla/config/expandlibs.py	2014-10-24 11:41:35.446880282 -0600
++@@ -26,9 +26,10 @@ ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} follo
++   descriptor contains. And for each of these LIBS, also apply the same
++   rules.
++ '''
++-from __future__ import with_statement
+++
++ import sys, os, errno
++ import expandlibs_config as conf
+++from rhrebase import all, any
++ 
++ def ensureParentDir(file):
++     '''Ensures the directory parent to the given file exists'''
++@@ -125,8 +126,10 @@ class ExpandArgs(list):
++     def _expand_desc(self, arg):
++         '''Internal function taking care of lib descriptor expansion only'''
++         if os.path.exists(arg + conf.LIBS_DESC_SUFFIX):
++-            with open(arg + conf.LIBS_DESC_SUFFIX, 'r') as f:
+++            f = open(arg + conf.LIBS_DESC_SUFFIX, 'r')
+++            if 1:
++                 desc = LibDescriptor(f.readlines())
+++            f.close()
++             objs = [relativize(o) for o in desc['OBJS']]
++             for lib in desc['LIBS']:
++                 objs += self._expand(lib)
++diff -up comm-esr31/mozilla/config/Makefile.in.python3 comm-esr31/mozilla/config/Makefile.in
++--- comm-esr31/mozilla/config/Makefile.in.python3	2014-07-17 18:05:10.000000000 -0600
+++++ comm-esr31/mozilla/config/Makefile.in	2014-10-24 11:41:35.446880282 -0600
++@@ -66,7 +66,7 @@ export-preqs = \
++   $(NULL)
++ 
++ export:: $(export-preqs)
++-	$(PYTHON) -m mozbuild.action.preprocessor $(DEFINES) $(ACDEFINES) \
+++	$(PYTHON) $(topsrcdir)/python/mozbuild/mozbuild/action/preprocessor.py $(DEFINES) $(ACDEFINES) \
++ 		-DMOZ_TREE_CAIRO=$(MOZ_TREE_CAIRO) \
++ 		-DMOZ_TREE_PIXMAN=$(MOZ_TREE_PIXMAN) \
++ 		-DMOZ_NATIVE_HUNSPELL=$(MOZ_NATIVE_HUNSPELL) \
++diff -up comm-esr31/mozilla/config/makefiles/functions.mk.python3 comm-esr31/mozilla/config/makefiles/functions.mk
++--- comm-esr31/mozilla/config/makefiles/functions.mk.python3	2014-07-17 18:05:11.000000000 -0600
+++++ comm-esr31/mozilla/config/makefiles/functions.mk	2014-10-24 11:41:35.446880282 -0600
++@@ -30,5 +30,6 @@ core_winabspath = $(error core_winabspat
++ ifdef .PYMAKE
++ py_action = %mozbuild.action.$(1) main $(2)
++ else
++-py_action = $(PYTHON) -m mozbuild.action.$(1) $(2)
+++#py_action = $(PYTHON) -m mozbuild.action.$(1) $(2)
+++py_action = $(PYTHON) $(topsrcdir)/python/mozbuild/mozbuild/action/$(1).py $(2)
++ endif
++diff -up comm-esr31/mozilla/config/make-stl-wrappers.py.python3 comm-esr31/mozilla/config/make-stl-wrappers.py
++--- comm-esr31/mozilla/config/make-stl-wrappers.py.python3	2014-07-17 18:05:11.000000000 -0600
+++++ comm-esr31/mozilla/config/make-stl-wrappers.py	2014-10-24 11:41:35.446880282 -0600
++@@ -1,10 +1,13 @@
++ # This Source Code Form is subject to the terms of the Mozilla Public
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++-from __future__ import print_function
++ import os, re, string, sys
++ from mozbuild.util import FileAvoidWrite
++ 
+++
+++def print24(msg, file=sys.stdout, end="\n"):
+++  file.write(msg + end)
+++
++ def find_in_path(file, searchpath):
++     for dir in searchpath.split(os.pathsep):
++         f = os.path.join(dir, file)
++@@ -33,22 +36,26 @@ def main(outdir, compiler, template_file
++     path_to_new = header_path('new', compiler)
++ 
++     for header in open(header_list_file, 'r'):
+++        #print "NEW HEADER" + header
++         header = header.rstrip()
++         if 0 == len(header) or is_comment(header):
++             continue
++ 
++         path = header_path(header, compiler)
++-        with FileAvoidWrite(os.path.join(outdir, header)) as f:
+++        f = FileAvoidWrite(os.path.join(outdir, header)).__enter__()
+++        if 1:
++             f.write(string.Template(template).substitute(HEADER=header,
++                                                          HEADER_PATH=path,
++                                                          NEW_HEADER_PATH=path_to_new))
+++        #f.__exit(0, 0, 0)
+++        f.close()
++ 
++ 
++ if __name__ == '__main__':
++     if 5 != len(sys.argv):
++-        print("""Usage:
++-  python {0} OUT_DIR ('msvc'|'gcc') TEMPLATE_FILE HEADER_LIST_FILE
++-""".format(sys.argv[0]), file=sys.stderr)
+++        print24("""Usage:
+++  python %s OUT_DIR ('msvc'|'gcc') TEMPLATE_FILE HEADER_LIST_FILE
+++""" % (sys.argv[0]), file=sys.stderr)
++         sys.exit(1)
++ 
++     main(*sys.argv[1:])
++diff -up comm-esr31/mozilla/config/mozunit.py.python3 comm-esr31/mozilla/config/mozunit.py
++--- comm-esr31/mozilla/config/mozunit.py.python3	2014-07-17 18:05:11.000000000 -0600
+++++ comm-esr31/mozilla/config/mozunit.py	2014-10-24 11:41:35.446880282 -0600
++@@ -93,18 +93,22 @@ class MockedOpen(object):
++     Context manager diverting the open builtin such that opening files
++     can open "virtual" file instances given when creating a MockedOpen.
++ 
++-    with MockedOpen({'foo': 'foo', 'bar': 'bar'}):
+++    MockedOpen({'foo': 'foo', 'bar': 'bar'}).__enter__()
+++    if 1:
++         f = open('foo', 'r')
++ 
+++    MockedOpen({'foo': 'foo', 'bar': 'bar'}).__exit__(0, 0, 0)
++     will thus open the virtual file instance for the file 'foo' to f.
++ 
++     MockedOpen also masks writes, so that creating or replacing files
++     doesn't touch the file system, while subsequently opening the file
++     will return the recorded content.
++ 
++-    with MockedOpen():
+++    MockedOpen().__enter__()
+++    if 1:
++         f = open('foo', 'w')
++         f.write('foo')
+++    MockedOpen().__exit__(0, 0, 0)
++     self.assertRaises(Exception,f.open('foo', 'r'))
++     '''
++     def __init__(self, files = {}):
++diff -up comm-esr31/mozilla/config/nsinstall.py.python3 comm-esr31/mozilla/config/nsinstall.py
++--- comm-esr31/mozilla/config/nsinstall.py.python3	2014-07-17 18:05:11.000000000 -0600
+++++ comm-esr31/mozilla/config/nsinstall.py	2014-10-24 11:41:35.447880278 -0600
++@@ -9,7 +9,6 @@
++ # a full build environment set up.
++ # The basic limitation is, it doesn't even try to link and ignores
++ # all related options.
++-from __future__ import print_function
++ from optparse import OptionParser
++ import os
++ import os.path
++@@ -17,6 +16,9 @@ import sys
++ import shutil
++ import stat
++ 
+++def print24(msg, file=sys.stdout, end="\n"):
+++  file.write(msg + end)
+++
++ def _nsinstall_internal(argv):
++   usage = "usage: %prog [options] arg1 [arg2 ...] target-directory"
++   p = OptionParser(usage=usage)
++@@ -65,7 +67,7 @@ def _nsinstall_internal(argv):
++     dir = os.path.abspath(dir)
++     if os.path.exists(dir):
++       if not os.path.isdir(dir):
++-        print('nsinstall: {0} is not a directory'.format(dir), file=sys.stderr)
+++        print24('nsinstall: %s is not a directory' % (dir), file=sys.stderr)
++         return 1
++       if mode:
++         os.chmod(dir, mode)
++@@ -76,7 +78,7 @@ def _nsinstall_internal(argv):
++         os.makedirs(dir, mode)
++       else:
++         os.makedirs(dir)
++-    except Exception as e:
+++    except Exception, e:
++       # We might have hit EEXIST due to a race condition (see bug 463411) -- try again once
++       if try_again:
++         return maybe_create_dir(dir, mode, False)
++diff -up comm-esr31/mozilla/config/rebuild_check.py.python3 comm-esr31/mozilla/config/rebuild_check.py
++--- comm-esr31/mozilla/config/rebuild_check.py.python3	2014-07-17 18:05:11.000000000 -0600
+++++ comm-esr31/mozilla/config/rebuild_check.py	2014-10-24 11:41:35.447880278 -0600
++@@ -8,7 +8,7 @@ import errno
++ def mtime(path):
++     try:
++         return os.stat(path).st_mtime
++-    except OSError as e:
+++    except OSError, e:
++         if e.errno == errno.ENOENT:
++             return -1
++         raise
++diff -up comm-esr31/mozilla/config/tests/unit-expandlibs.py.python3 comm-esr31/mozilla/config/tests/unit-expandlibs.py
++--- comm-esr31/mozilla/config/tests/unit-expandlibs.py.python3	2014-07-17 18:05:11.000000000 -0600
+++++ comm-esr31/mozilla/config/tests/unit-expandlibs.py	2014-10-24 11:41:35.447880278 -0600
++@@ -161,11 +161,15 @@ class TestExpandInit(TestCaseWithTmpDir)
++         self.libx_files = [self.tmpfile('libx', Obj(f)) for f in ['g', 'h', 'i']]
++         self.liby_files = [self.tmpfile('liby', Obj(f)) for f in ['j', 'k', 'l']] + [self.tmpfile('liby', Lib('z'))]
++         self.touch(self.libx_files + self.liby_files)
++-        with open(self.tmpfile('libx', Lib('x') + config.LIBS_DESC_SUFFIX), 'w') as f:
+++        f = open(self.tmpfile('libx', Lib('x') + config.LIBS_DESC_SUFFIX), 'w')
+++        if 1:
++             f.write(str(generate(self.libx_files)))
++-        with open(self.tmpfile('liby', Lib('y') + config.LIBS_DESC_SUFFIX), 'w') as f:
+++        f.close()
+++        f = open(self.tmpfile('liby', Lib('y') + config.LIBS_DESC_SUFFIX), 'w')
+++        if 1:
++             f.write(str(generate(self.liby_files + [self.tmpfile('libx', Lib('x'))])))
++ 
+++        f.close()
++         # Create various objects and libraries 
++         self.arg_files = [self.tmpfile(f) for f in [Lib('a'), Obj('b'), Obj('c'), Lib('d'), Obj('e')]]
++         # We always give library names (LIB_PREFIX/SUFFIX), even for
++@@ -218,7 +222,8 @@ class TestExpandArgsMore(TestExpandInit)
++     def test_makelist(self):
++         '''Test grouping object files in lists'''
++         # ExpandArgsMore does the same as ExpandArgs
++-        with ExpandArgsMore(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))]) as args:
+++        args = ExpandArgsMore(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))]).__enter__()
+++        if 1:
++             self.assertRelEqual(args, ['foo', '-bar'] + self.files + self.liby_files + self.libx_files) 
++ 
++             # But also has an extra method replacing object files with a list
++@@ -233,16 +238,21 @@ class TestExpandArgsMore(TestExpandInit)
++                 self.assertNotEqual(args[3][0], '@')
++                 filename = args[3]
++                 content = ['INPUT("{0}")'.format(relativize(f)) for f in objs]
++-                with open(filename, 'r') as f:
+++                f = open(filename, 'r')
+++                if 1:
++                     self.assertEqual([l.strip() for l in f.readlines() if len(l.strip())], content)
+++                f.close()
++             elif config.EXPAND_LIBS_LIST_STYLE == "list":
++                 self.assertEqual(args[3][0], '@')
++                 filename = args[3][1:]
++                 content = objs
++-                with open(filename, 'r') as f:
+++                f = open(filename, 'r')
+++                if 1:
++                     self.assertRelEqual([l.strip() for l in f.readlines() if len(l.strip())], content)
++ 
+++                f.close()
++             tmp = args.tmp
+++        args.__exit__(0, 0, 0)
++         # Check that all temporary files are properly removed
++         self.assertEqual(True, all([not os.path.exists(f) for f in tmp]))
++ 
++@@ -294,7 +304,8 @@ class TestExpandArgsMore(TestExpandInit)
++ 
++         # ExpandArgsMore does the same as ExpandArgs
++         self.touch([self.tmpfile('liby', Lib('y'))])
++-        with ExpandArgsMore(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))]) as args:
+++        args = ExpandArgsMore(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))]).__enter__()
+++        if 1:
++             self.assertRelEqual(args, ['foo', '-bar'] + self.files + [self.tmpfile('liby', Lib('y'))])
++ 
++             # ExpandArgsMore also has an extra method extracting static libraries
++@@ -314,6 +325,7 @@ class TestExpandArgsMore(TestExpandInit)
++             self.assertRelEqual(args, ['foo', '-bar'] + extracted_args)
++ 
++             tmp = args.tmp
+++        args.__exit__(0, 0, 0)
++         # Check that all temporary files are properly removed
++         self.assertEqual(True, all([not os.path.exists(f) for f in tmp]))
++ 
++diff -up comm-esr31/mozilla/config/tests/unit-mozunit.py.python3 comm-esr31/mozilla/config/tests/unit-mozunit.py
++--- comm-esr31/mozilla/config/tests/unit-mozunit.py.python3	2014-07-17 18:05:11.000000000 -0600
+++++ comm-esr31/mozilla/config/tests/unit-mozunit.py	2014-10-24 11:41:35.447880278 -0600
++@@ -12,9 +12,11 @@ class TestMozUnit(unittest.TestCase):
++     def test_mocked_open(self):
++         # Create a temporary file on the file system.
++         (fd, path) = mkstemp()
++-        with os.fdopen(fd, 'w') as file:
+++        file = os.fdopen(fd, 'w')
+++        if 1:
++             file.write('foobar');
++ 
+++        file.close()
++         self.assertFalse(os.path.exists('file1'))
++         self.assertFalse(os.path.exists('file2'))
++ 
++@@ -29,8 +31,10 @@ class TestMozUnit(unittest.TestCase):
++             self.assertEqual(open('file2', 'r').read(), 'content2')
++ 
++             # Check that overwriting these files alters their content.
++-            with open('file1', 'w') as file:
+++            file = open('file1', 'w')
+++            if 1:
++                 file.write('foo')
+++            file.close()
++             self.assertTrue(os.path.exists('file1'))
++             self.assertEqual(open('file1', 'r').read(), 'foo')
++ 
++@@ -42,8 +46,10 @@ class TestMozUnit(unittest.TestCase):
++             self.assertEqual(open('file2', 'r').read(), 'bar')
++ 
++             # Check that appending to a file does append
++-            with open('file1', 'a') as file:
+++            file = open('file1', 'a')
+++            if 1:
++                 file.write('bar')
+++            file.close()
++             self.assertEqual(open('file1', 'r').read(), 'foobar')
++ 
++             self.assertFalse(os.path.exists('file3'))
++@@ -53,8 +59,10 @@ class TestMozUnit(unittest.TestCase):
++             self.assertFalse(os.path.exists('file3'))
++ 
++             # Check that writing a new file does create the file.
++-            with open('file3', 'w') as file:
+++            file = open('file3', 'w')
+++            if 1:
++                 file.write('baz')
+++            file.close()
++             self.assertEqual(open('file3', 'r').read(), 'baz')
++             self.assertTrue(os.path.exists('file3'))
++ 
++@@ -63,17 +71,23 @@ class TestMozUnit(unittest.TestCase):
++ 
++             # Check that overwriting a file existing on the file system
++             # does modify its content.
++-            with open(path, 'w') as file:
+++            file = open(path, 'w')
+++            if 1:
++                 file.write('bazqux')
+++            file.close()
++             self.assertEqual(open(path, 'r').read(), 'bazqux')
++ 
++-        with MockedOpen():
+++        MockedOpen().__enter__()
+++        if 1:
++             # Check that appending to a file existing on the file system
++             # does modify its content.
++-            with open(path, 'a') as file:
+++            file = open(path, 'a')
+++            if 1:
++                 file.write('bazqux')
+++            file.close()
++             self.assertEqual(open(path, 'r').read(), 'foobarbazqux')
++ 
+++        MockedOpen().__exit__(0, 0, 0)
++         # Check that the file was not actually modified on the file system.
++         self.assertEqual(open(path, 'r').read(), 'foobar')
++         os.remove(path)
++diff -up comm-esr31/mozilla/content/canvas/test/webgl-conformance/writemanifest.py.python3 comm-esr31/mozilla/content/canvas/test/webgl-conformance/writemanifest.py
++--- comm-esr31/mozilla/content/canvas/test/webgl-conformance/writemanifest.py.python3	2014-07-17 18:05:12.000000000 -0600
+++++ comm-esr31/mozilla/content/canvas/test/webgl-conformance/writemanifest.py	2014-10-24 11:41:35.447880278 -0600
++@@ -25,8 +25,10 @@ def listfiles(dir, rel):
++ def writemanifest():
++     script_dir = os.path.dirname(__file__)
++     list_dirs = [os.path.join(script_dir, d) for d in CONFORMANCE_DIRS]
++-    with open(os.path.join(script_dir, 'mochitest-conformance-files.ini'), 'w') as f:
+++    f = open(os.path.join(script_dir, 'mochitest-conformance-files.ini'), 'w')
+++    if 1:
++         f.write("""[DEFAULT]
+++    f.close()
++ support-files =
++   %s
++ """ % "\n  ".join(sorted(chain.from_iterable(listfiles(d, script_dir)
++diff -up comm-esr31/mozilla/dom/bindings/Codegen.py.python3 comm-esr31/mozilla/dom/bindings/Codegen.py
++--- comm-esr31/mozilla/dom/bindings/Codegen.py.python3	2014-07-17 18:05:14.000000000 -0600
+++++ comm-esr31/mozilla/dom/bindings/Codegen.py	2014-10-24 11:41:35.450880265 -0600
++@@ -9,7 +9,8 @@ import re
++ import string
++ import math
++ import textwrap
++-
+++from rhrebase import any
+++from rhrebase import all
++ from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType, IDLAttribute, IDLUndefinedValue
++ from Configuration import NoSuchDescriptorError, getTypesFromDescriptor, getTypesFromDictionary, getTypesFromCallback, Descriptor
++ 
++@@ -152,7 +153,7 @@ def fill(template, **args):
++     return t.substitute(args)
++ 
++ 
++-class CGThing():
+++class CGThing:
++     """
++     Abstract base class for things that spit out code.
++     """
++@@ -276,8 +277,11 @@ class CGNativePropertyHooks(CGThing):
++         else:
++             prototypeID += "_ID_Count"
++         parent = self.descriptor.interface.parent
++-        parentHooks = (toBindingNamespace(parent.identifier.name) + "::sNativePropertyHooks"
++-                       if parent else 'nullptr')
+++        parentHooks = ""
+++        if parent:
+++          parentHooks = toBindingNamespace(parent.identifier.name) + "::sNativePropertyHooks"
+++        else:
+++          parentHooks = 'nullptr'
++ 
++         return fill(
++             """
++@@ -300,12 +304,15 @@ class CGNativePropertyHooks(CGThing):
++ 
++ 
++ def NativePropertyHooks(descriptor):
++-    return "&sWorkerNativePropertyHooks" if descriptor.workers else "sNativePropertyHooks"
+++    if descriptor.workers:
+++      return "&sWorkerNativePropertyHooks"
+++    else:
+++      return "sNativePropertyHooks"
++ 
++ 
++ def DOMClass(descriptor):
++     def make_name(d):
++-        return "%s%s" % (d.interface.identifier.name, '_workers' if d.workers else '')
+++        return "%s%s" % (d.interface.identifier.name, ('', '_workers')[d.workers])
++ 
++     protoList = ['prototypes::id::' + make_name(descriptor.getDescriptor(proto)) for proto in descriptor.prototypeChain]
++     # Pad out the list to the right length with _ID_Count so we
++@@ -343,7 +350,11 @@ class CGDOMJSClass(CGThing):
++ 
++     def define(self):
++         traceHook = 'nullptr'
++-        callHook = LEGACYCALLER_HOOK_NAME if self.descriptor.operations["LegacyCaller"] else 'nullptr'
+++        callHook = None
+++        if self.descriptor.operations["LegacyCaller"]:
+++          callHook = LEGACYCALLER_HOOK_NAME
+++        else:
+++          callHook = 'nullptr'
++         slotCount = INSTANCE_RESERVED_SLOTS + self.descriptor.interface.totalMembersInSlots
++         classFlags = "JSCLASS_IS_DOMJSCLASS | "
++         classExtensionAndObjectOps = """\
++@@ -426,7 +437,7 @@ JS_NULL_OBJECT_OPS
++             """,
++             name=self.descriptor.interface.identifier.name,
++             flags=classFlags,
++-            addProperty=ADDPROPERTY_HOOK_NAME if wantsAddProperty(self.descriptor) else 'JS_PropertyStub',
+++            addProperty=('JS_PropertyStub', ADDPROPERTY_HOOK_NAME)[wantsAddProperty(self.descriptor)],
++             enumerate=enumerateHook,
++             resolve=newResolveHook,
++             finalize=FINALIZE_HOOK_NAME,
++@@ -454,7 +465,11 @@ class CGDOMProxyJSClass(CGThing):
++         # HTMLAllCollection.  So just hardcode it here.
++         if self.descriptor.interface.identifier.name == "HTMLAllCollection":
++             flags.append("JSCLASS_EMULATES_UNDEFINED")
++-        callHook = LEGACYCALLER_HOOK_NAME if self.descriptor.operations["LegacyCaller"] else 'nullptr'
+++        callHook = None
+++        if self.descriptor.operations["LegacyCaller"]:
+++          callHook = LEGACYCALLER_HOOK_NAME
+++        else:
+++          callHook = 'nullptr'
++         return fill(  # BOGUS extra blank line at the top
++             """
++ 
++@@ -689,7 +704,12 @@ class CGList(CGThing):
++         self.children.extend(kids)
++ 
++     def join(self, iterable):
++-        return self.joiner.join(s for s in iterable if len(s) > 0)
+++        l = []
+++        for s in iterable:
+++           if len(s) > 0:
+++              l.append(s)
+++        
+++        return self.joiner.join(l)
++ 
++     def declare(self):
++         return self.join(child.declare() for child in self.children if child is not None)
++@@ -840,9 +860,9 @@ class CGElseChain(CGThing):
++ 
++ class CGTemplatedType(CGWrapper):
++     def __init__(self, templateName, child, isConst=False, isReference=False):
++-        const = "const " if isConst else ""
+++        const = ("", "const ")[isConst]
++         pre = "%s%s<" % (const, templateName)
++-        ref = "&" if isReference else ""
+++        ref = ("", "&")[isReference]
++         post = ">%s" % ref
++         CGWrapper.__init__(self, child, pre=pre, post=post)
++ 
++@@ -1280,7 +1300,7 @@ def UnionConversions(descriptors, dictio
++                       post="\n\n"))
++ 
++ 
++-class Argument():
+++class Argument:
++     """
++     A class for outputting the type and name of an argument
++     """
++@@ -1337,7 +1357,13 @@ class CGAbstractMethod(CGThing):
++         self.templateArgs = templateArgs
++ 
++     def _argstring(self, declare):
++-        return ', '.join([a.declare() if declare else a.define() for a in self.args])
+++        l = []
+++        for a in self.args:
+++          if declare:
+++            l.append(a.declare())
+++          else:
+++            l.append(a.define())
+++        return ', '.join(l)
++ 
++     def _template(self):
++         if self.templateArgs is None:
++@@ -1353,7 +1379,7 @@ class CGAbstractMethod(CGThing):
++         if self.static:
++             decorators.append('static')
++         decorators.append(self.returnType)
++-        maybeNewline = " " if self.inline else "\n"
+++        maybeNewline = ("\n", " ")[self.inline]
++         return ' '.join(decorators) + maybeNewline
++ 
++     def declare(self):
++@@ -1365,7 +1391,10 @@ class CGAbstractMethod(CGThing):
++         return self.definition_prologue(fromDeclare) + self.definition_body() + self.definition_epilogue()
++ 
++     def define(self):
++-        return "" if self.inline else self._define()
+++        if self.inline:
+++          return ""
+++        else:
+++          return self._define()
++ 
++     def definition_prologue(self, fromDeclare):
++         return "%s%s%s(%s)\n{\n" % (self._template(), self._decorators(),
++@@ -2184,7 +2213,7 @@ class AttrDefiner(PropertyDefiner):
++             return ""
++ 
++         def flags(attr):
++-            unforgeable = " | JSPROP_PERMANENT" if self.unforgeable else ""
+++            unforgeable = ("", " | JSPROP_PERMANENT")[self.unforgeable]
++             return ("JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS" +
++                     unforgeable)
++ 
++@@ -2265,7 +2294,7 @@ class ConstDefiner(PropertyDefiner):
++             PropertyDefiner.getControllingCondition, specData, doIdArrays)
++ 
++ 
++-class PropertyArrays():
+++class PropertyArrays:
++     def __init__(self, descriptor):
++         self.staticMethods = MethodDefiner(descriptor, "StaticMethods",
++                                            static=True)
++@@ -2299,7 +2328,10 @@ class CGNativeProperties(CGList):
++     def __init__(self, descriptor, properties):
++         def generateNativeProperties(name, chrome):
++             def check(p):
++-                return p.hasChromeOnly() if chrome else p.hasNonChromeOnly()
+++                if chrome:
+++                  return p.hasChromeOnly()
+++                else:
+++                  return p.hasNonChromeOnly()
++ 
++             nativeProps = []
++             for array in properties.arrayNames():
++@@ -2507,7 +2539,9 @@ class CGCreateInterfaceObjectsMethod(CGA
++             chromeProperties = accessCheck + " ? &sChromeOnlyNativeProperties : nullptr"
++         else:
++             chromeProperties = "nullptr"
++-
+++        back_name = "nullptr"
+++        if needInterfaceObject:
+++           back_name =   '"' + self.descriptor.interface.identifier.name + '"'
++         call = fill(
++             """
++             dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
++@@ -2529,7 +2563,7 @@ class CGCreateInterfaceObjectsMethod(CGA
++             domClass=domClass,
++             properties=properties,
++             chromeProperties=chromeProperties,
++-            name='"' + self.descriptor.interface.identifier.name + '"' if needInterfaceObject else "nullptr")
+++            name=back_name)
++ 
++         if UseHolderForUnforgeable(self.descriptor):
++             assert needInterfacePrototypeObject
++@@ -2765,6 +2799,9 @@ def InitUnforgeablePropertiesOnObject(de
++     """
++     properties is a PropertyArrays instance
++     """
+++    retval = ""
+++    if failureReturnValue:
+++       retval = " " + failureReturnValue
++     defineUnforgeables = fill(
++         """
++         if (!DefineUnforgeableAttributes(aCx, ${obj}, %s)) {
++@@ -2772,7 +2809,7 @@ def InitUnforgeablePropertiesOnObject(de
++         }
++         """,
++         obj=obj,
++-        rv=" " + failureReturnValue if failureReturnValue else "")
+++        rv=retval)
++ 
++     unforgeableAttrs = properties.unforgeableAttrs
++     unforgeables = []
++@@ -3172,6 +3209,8 @@ numericSuffixes = {
++     IDLType.Tags.double: ''
++ }
++ 
+++def isnan(f):
+++  return str(float(f)) == "nan"
++ 
++ def numericValue(t, v):
++     if (t == IDLType.Tags.unrestricted_double or
++@@ -3181,12 +3220,12 @@ def numericValue(t, v):
++             return "mozilla::PositiveInfinity<%s>()" % typeName
++         if v == float("-inf"):
++             return "mozilla::NegativeInfinity<%s>()" % typeName
++-        if math.isnan(v):
+++        if isnan(v):
++             return "mozilla::UnspecifiedNaN<%s>()" % typeName
++     return "%s%s" % (v, numericSuffixes[t])
++ 
++ 
++-class CastableObjectUnwrapper():
+++class CastableObjectUnwrapper:
++     """
++     A class for unwrapping an object named by the "source" argument
++     based on the passed-in descriptor and storing it in a variable
++@@ -3315,7 +3354,7 @@ class CGCallbackTempRoot(CGGeneric):
++         CGGeneric.__init__(self, define=define)
++ 
++ 
++-class JSToNativeConversionInfo():
+++class JSToNativeConversionInfo:
++     """
++     An object representing information about a JS-to-native conversion.
++     """
++@@ -3857,11 +3896,17 @@ def getJSToNativeConversionInfo(type, de
++         if nullable:
++             type = type.inner
++ 
++-        unionArgumentObj = "${declName}" if isMember else "${holderName}"
+++        unionArgumentObj = "${holderName}"
+++        if isMember:
+++          unionArgumentObj = "${declName}"
+++        #unionArgumentObj = ("${holderName}", "${declName}")[isMember == true]
++         if nullable:
++             # If we're a member, we're a Nullable, which hasn't been told it has
++             # a value.  Otherwise we're an already-constructed Maybe.
++-            unionArgumentObj += ".SetValue()" if isMember else ".ref()"
+++            if isMember:
+++              unionArgumentObj += ".SetValue()"
+++            else:
+++              unionArgumentObj += ".ref()"
++ 
++         memberTypes = type.flatMemberTypes
++         names = []
++@@ -3971,9 +4016,18 @@ def getJSToNativeConversionInfo(type, de
++             templateBody = CGList([templateBody,
++                                    CGIfWrapper(setDictionary, "!done")])
++ 
++-        stringTypes = [t for t in memberTypes if t.isString() or t.isEnum()]
++-        numericTypes = [t for t in memberTypes if t.isNumeric()]
++-        booleanTypes = [t for t in memberTypes if t.isBoolean()]
+++        stringTypes = []
+++        for t in memberTypes:
+++          if t.isString() or t.isEnum():
+++            stringTypes.append(t)
+++        numericTypes = []
+++        for t in memberTypes:
+++          if t.isNumeric():
+++            numericTypes.append(t)
+++        booleanTypes = []
+++        for t in memberTypes:
+++          if t.isBoolean():
+++            booleanTypes.append(t)
++         if stringTypes or numericTypes or booleanTypes:
++             assert len(stringTypes) <= 1
++             assert len(numericTypes) <= 1
++@@ -4100,7 +4154,7 @@ def getJSToNativeConversionInfo(type, de
++ 
++             if tag in numericSuffixes or tag is IDLType.Tags.bool:
++                 defaultStr = getHandleDefault(defaultValue)
++-                value = declLoc + (".Value()" if nullable else "")
+++                value = declLoc + (("", ".Value()")[nullable])
++                 default = CGGeneric("%s.RawSetAs%s() = %s;\n" %
++                                     (value, defaultValue.type, defaultStr))
++             else:
++@@ -4836,17 +4890,19 @@ def instantiateJSToNativeConversion(info
++ 
++     if checkForValue:
++         if dealWithOptional:
+++            bp_args = ""
+++            if info.declArgs:
+++              bp_args = getArgsCGThing(info.declArgs).define()
++             declConstruct = CGIndenter(
++                 CGGeneric("%s.Construct(%s);\n" %
++-                          (originalDeclName,
++-                           getArgsCGThing(info.declArgs).define() if
++-                           info.declArgs else "")))
+++                          (originalDeclName, bp_args)))
+++            bp_holderArgs = ""
+++            if info.holderArgs:
+++              bp_holderArgs = getArgsCGThing(info.holderArgs).define()
++             if holderType is not None:
++                 holderConstruct = CGIndenter(
++                     CGGeneric("%s.construct(%s);\n" %
++-                              (originalHolderName,
++-                               getArgsCGThing(info.holderArgs).define() if
++-                               info.holderArgs else "")))
+++                              (originalHolderName, bp_holderArgs)))
++             else:
++                 holderConstruct = None
++         else:
++@@ -4880,7 +4936,7 @@ def convertConstIDLValueToJSVal(value):
++     if tag in [IDLType.Tags.int64, IDLType.Tags.uint64]:
++         return "DOUBLE_TO_JSVAL(%s)" % numericValue(tag, value.value)
++     if tag == IDLType.Tags.bool:
++-        return "JSVAL_TRUE" if value.value else "JSVAL_FALSE"
+++        return ("JSVAL_FALSE", "JSVAL_TRUE")[value.value]
++     if tag in [IDLType.Tags.float, IDLType.Tags.double]:
++         return "DOUBLE_TO_JSVAL(%s)" % (value.value)
++     raise TypeError("Const value of unhandled type: %s" % value.type)
++@@ -4940,7 +4996,7 @@ class CGArgumentConverter(CGThing):
++             isEnforceRange=self.argument.enforceRange,
++             isClamp=self.argument.clamp,
++             lenientFloatCode=self.lenientFloatCode,
++-            isMember="Variadic" if self.argument.variadic else False,
+++            isMember=(False, "Variadic")[self.argument.variadic],
++             allowTreatNonCallableAsNull=self.argument.allowTreatNonCallableAsNull(),
++             sourceDescription=self.argDescription)
++ 
++@@ -5904,7 +5960,10 @@ def wrapTypeIntoCurrentCompartment(type,
++                 if memberWrap:
++                     memberWraps.append(memberWrap)
++             myDict = myDict.parent
++-        return CGList(memberWraps) if len(memberWraps) != 0 else None
+++        if len(memberWraps) != 0:
+++          return CGList(memberWraps)
+++        else:
+++          return None
++ 
++     if type.isUnion():
++         memberWraps = []
++@@ -5919,7 +5978,10 @@ def wrapTypeIntoCurrentCompartment(type,
++                 memberWrap = CGIfWrapper(
++                     memberWrap, "%s.Is%s()" % (value, memberName))
++                 memberWraps.append(memberWrap)
++-        return CGList(memberWraps, "else ") if len(memberWraps) != 0 else None
+++        if len(memberWraps) != 0:
+++          return CGList(memberWraps, "else ")
+++        else:
+++          return None
++ 
++     if (type.isString() or type.isPrimitive() or type.isEnum() or
++         type.isGeckoInterface() or type.isCallback() or type.isDate()):
++@@ -6116,8 +6178,11 @@ class CGPerSignatureCall(CGThing):
++                 CGIfWrapper(CGList(xraySteps),
++                             "objIsXray"))
++ 
+++        errRep = None
+++        if self.isFallible():
+++          errRep = self.getErrorReport()
++         cgThings.append(CGCallGenerator(
++-            self.getErrorReport() if self.isFallible() else None,
+++            errRep,
++             self.getArguments(), argsPre, returnType,
++             self.extendedAttributes, descriptor, nativeMethodName,
++             static, argsPost=argsPost))
++@@ -6151,7 +6216,7 @@ class CGPerSignatureCall(CGThing):
++             'jsvalHandle': 'args.rval()',
++             'returnsNewObject': returnsNewObject,
++             'successCode': successCode,
++-            'obj': "reflector" if setSlot else "obj"
+++            'obj': ("obj", "reflector")[setSlot]
++         }
++         try:
++             wrapCode = wrapForType(self.returnType, self.descriptor, resultTemplateValues)
++@@ -6490,18 +6555,16 @@ class CGMethodCall(CGThing):
++             # First check for undefined and optional distinguishing arguments
++             # and output a special branch for that case.  Note that we don't
++             # use distinguishingArgument here because we actualy want to
++-            # exclude variadic arguments.  Also note that we skip this check if
++-            # we plan to output a isNullOrUndefined() special case for this
+++            # exclude variadic arguments.  Also note that we skip this check if # we plan to output a isNullOrUndefined() special case for this
++             # argument anyway, since that will subsume our isUndefined() check.
++             # This is safe, because there can be at most one nullable
++             # distinguishing argument, so if we're it we'll definitely get
++             # picked up by the nullable handling.  Also, we can skip this check
++             # if the argument has an unconditional conversion later on.
++-            undefSigs = [s for s in possibleSignatures if
++-                         distinguishingIndex < len(s[1]) and
++-                         s[1][distinguishingIndex].optional and
++-                         hasConditionalConversion(s[1][distinguishingIndex].type) and
++-                         not needsNullOrUndefinedCase(s[1][distinguishingIndex].type)]
+++            undefSigs = []
+++            for s in possibleSignatures:
+++              if distinguishingIndex < len(s[1]) and s[1][distinguishingIndex].optional and hasConditionalConversion(s[1][distinguishingIndex].type) and not needsNullOrUndefinedCase(s[1][distinguishingIndex].type):
+++                 undefSigs.append(s)
++             # Can't have multiple signatures with an optional argument at the
++             # same index.
++             assert len(undefSigs) < 2
++@@ -6682,7 +6745,7 @@ class CGGetterCall(CGPerSignatureCall):
++                                     getter=True)
++ 
++ 
++-class FakeArgument():
+++class FakeArgument:
++     """
++     A class that quacks like an IDLArgument.  This is used to make
++     setters look like method calls or for special operations.
++@@ -6701,7 +6764,7 @@ class FakeArgument():
++             self.enforceRange = False
++             self.clamp = False
++ 
++-        class FakeIdentifier():
+++        class FakeIdentifier:
++             def __init__(self):
++                 self.name = name
++         self.identifier = FakeIdentifier()
++@@ -6858,7 +6921,7 @@ class CGGenericMethod(CGAbstractBindingM
++         unwrapFailureCode = (
++             'return ThrowInvalidThis(cx, args, GetInvalidThisErrorForMethod(%%(securityError)s), "%s");\n' %
++             descriptor.interface.identifier.name)
++-        name = "genericCrossOriginMethod" if allowCrossOriginThis else "genericMethod"
+++        name = ("genericMethod", "genericCrossOriginMethod")[allowCrossOriginThis]
++         CGAbstractBindingMethod.__init__(self, descriptor, name,
++                                          args,
++                                          unwrapFailureCode=unwrapFailureCode,
++@@ -7091,7 +7154,7 @@ class CGEnumerateHook(CGAbstractBindingM
++         return prefix + CGAbstractBindingMethod.definition_body(self)
++ 
++ 
++-class CppKeywords():
+++class CppKeywords:
++     """
++     A class for checking if method names declared in webidl
++     are not in conflict with C++ keywords.
++@@ -7694,7 +7757,7 @@ class CGMemberJITInfo(CGThing):
++             return "JSJitInfo::Object"
++         if t.isUnion():
++             u = t.unroll()
++-            type = "JSJitInfo::Null" if u.hasNullableType else ""
+++            type = ("", "JSJitInfo::Null")[u.hasNullableType]
++             return ("JSJitInfo::ArgType(%s)" %
++                     reduce(CGMemberJITInfo.getSingleArgType,
++                            u.flatMemberTypes, type))
++@@ -7921,18 +7984,18 @@ def getUnionTypeTemplateVars(unionType,
++     # By the time tryNextCode is invoked, we're guaranteed the union has been
++     # constructed as some type, since we've been trying to convert into the
++     # corresponding member.
++-    prefix = "" if ownsMembers else "mUnion."
+++    prefix = ("mUnion.", "")[ownsMembers]
++     tryNextCode = ("%sDestroy%s();\n"
++                    "tryNext = true;\n"
++                    "return true;\n" % (prefix, name))
++     conversionInfo = getJSToNativeConversionInfo(
++         type, descriptorProvider, failureCode=tryNextCode,
++         isDefinitelyObject=not type.isDictionary(),
++-        isMember=("OwningUnion" if ownsMembers else None),
+++        isMember=((None, "OwningUnion")[ownsMembers]),
++         sourceDescription="member of %s" % unionType)
++ 
++     ctorNeedsCx = conversionInfo.declArgs == "cx"
++-    ctorArgs = "cx" if ctorNeedsCx else ""
+++    ctorArgs = ("", "cx")[ctorNeedsCx]
++ 
++     # This is ugly, but UnionMember needs to call a constructor with no
++     # arguments so the type can't be const.
++@@ -7992,14 +8055,17 @@ def getUnionTypeTemplateVars(unionType,
++                              bodyInHeader=not ownsMembers,
++                              body=jsConversion)
++ 
+++    holder = None
+++    if conversionInfo.holderType:
+++      holder = conversionInfo.holderType.define()
++     return {
++         "name": name,
++         "structType": structType,
++         "externalType": externalType,
++         "setter": setter,
++-        "holderType": conversionInfo.holderType.define() if conversionInfo.holderType else None,
+++        "holderType": holder,
++         "ctorArgs": ctorArgs,
++-        "ctorArgList": [Argument("JSContext*", "cx")] if ctorNeedsCx else []
+++        "ctorArgList": ([], [Argument("JSContext*", "cx")])[ctorNeedsCx]
++     }
++ 
++ 
++@@ -8218,8 +8284,16 @@ class CGUnionStruct(CGThing):
++         else:
++             disallowCopyConstruction = True
++ 
++-        friend = "  friend class %sArgument;\n" % str(self.type) if not self.ownsMembers else ""
++-        bases = [ClassBase("AllOwningUnionBase")] if self.ownsMembers else []
+++        friend = None
+++        if not self.ownsMembers:
+++          friend = "  friend class %sArgument;\n" % str(self.type)
+++        else:
+++          friend = ""
+++        bases = None
+++        if self.ownsMembers:
+++          bases = [ClassBase("AllOwningUnionBase")]
+++        else:
+++          bases = []
++         return CGClass(selfName,
++                        bases=bases,
++                        members=members,
++@@ -8257,7 +8331,10 @@ class CGUnionStruct(CGThing):
++         Returns a string name for this known union type.
++         """
++         assert type.isUnion() and not type.nullable()
++-        return ("Owning" if ownsMembers else "") + type.name
+++        if ownsMembers:
+++            return "Owning" + type.name
+++        else:
+++            return type.name
++ 
++     @staticmethod
++     def unionTypeDecl(type, ownsMembers):
++@@ -8408,8 +8485,11 @@ class ClassMethod(ClassItem):
++         return self.body
++ 
++     def declare(self, cgClass):
++-        templateClause = ('template <%s>\n' % ', '.join(self.templateArgs)
++-                          if self.bodyInHeader and self.templateArgs else '')
+++        templateClause = None
+++        if self.bodyInHeader and self.templateArgs:
+++          templateClause = ('template <%s>\n' % ', '.join(self.templateArgs))
+++        else:
+++          templateClause = ('')
++         args = ', '.join([a.declare() for a in self.args])
++         if self.bodyInHeader:
++             body = indent(self.getBody())
++@@ -8427,8 +8507,8 @@ class ClassMethod(ClassItem):
++             breakAfterReturnDecl=self.breakAfterReturnDecl,
++             name=self.name,
++             args=args,
++-            const=' const' if self.const else '',
++-            override=' MOZ_OVERRIDE' if self.override else '',
+++            const=('', ' const')[self.const],
+++            override=('', ' MOZ_OVERRIDE')[self.override],
++             body=body,
++             breakAfterSelf=self.breakAfterSelf)
++ 
++@@ -8462,7 +8542,7 @@ class ClassMethod(ClassItem):
++             className=cgClass.getNameString(),
++             name=self.name,
++             args=', '.join([a.define() for a in self.args]),
++-            const=' const' if self.const else '',
+++            const=('', ' const')[self.const],
++             body=self.getBody())
++ 
++ 
++@@ -8653,7 +8733,7 @@ class ClassMember(ClassItem):
++         ClassItem.__init__(self, name, visibility)
++ 
++     def declare(self, cgClass):
++-        return '%s%s %s;\n' % ('static ' if self.static else '', self.type,
+++        return '%s%s %s;\n' % (('', 'static ')[self.static], self.type,
++                                self.name)
++ 
++     def define(self, cgClass):
++@@ -8694,7 +8774,7 @@ class ClassEnum(ClassItem):
++             else:
++                 entry = '%s = %s' % (self.entries[i], self.values[i])
++             entries.append(entry)
++-        name = '' if not self.name else ' ' + self.name
+++        name = (' ','')[not self.name] + self.name
++         return 'enum%s\n{\n%s\n};\n' % (name, indent(',\n'.join(entries)))
++ 
++     def define(self, cgClass):
++@@ -8731,7 +8811,11 @@ class CGClass(CGThing):
++         self.constructors = constructors
++         # We store our single destructor in a list, since all of our
++         # code wants lists of members.
++-        self.destructors = [destructor] if destructor else []
+++        self.destructors = None
+++        if destructor:
+++          self.destructors = [destructor]
+++        else:
+++          self.destructors = []
++         self.methods = methods
++         self.typedefs = typedefs
++         self.enums = enums
++@@ -8741,7 +8825,7 @@ class CGClass(CGThing):
++         self.isStruct = isStruct
++         self.disallowCopyConstruction = disallowCopyConstruction
++         self.indent = indent
++-        self.defaultVisibility = 'public' if isStruct else 'private'
+++        self.defaultVisibility = ('private','public')[isStruct]
++         self.decorators = decorators
++         self.extradeclarations = extradeclarations
++         self.extradefinitions = extradefinitions
++@@ -8761,7 +8845,7 @@ class CGClass(CGThing):
++             result += ('template <%s>\n' %
++                        ','.join([str(a) for a in templateArgs]))
++ 
++-        type = 'struct' if self.isStruct else 'class'
+++        type = ('class', 'struct')[self.isStruct]
++ 
++         if self.templateSpecialization:
++             specialization = \
++@@ -8998,7 +9082,7 @@ class CGClassForwardDeclare(CGThing):
++         self.isStruct = isStruct
++ 
++     def declare(self):
++-        type = 'struct' if self.isStruct else 'class'
+++        type = ('class', 'struct')[self.isStruct]
++         return '%s %s;\n' % (type, self.name)
++ 
++     def define(self):
++@@ -10078,7 +10162,7 @@ class CGDOMJSProxyHandlerDefiner(CGThing
++ 
++ 
++ def stripTrailingWhitespace(text):
++-    tail = '\n' if text.endswith('\n') else ''
+++    tail = ('', '\n')[text.endswith('\n')]
++     lines = text.splitlines()
++     return '\n'.join(line.rstrip() for line in lines) + tail
++ 
++@@ -11005,8 +11089,10 @@ def dependencySortObjects(objects, depen
++     while len(objects) != 0:
++         # Find the dictionaries that don't depend on anything else
++         # anymore and move them over.
++-        toMove = [o for o in objects if
++-                  len(dependencyGetter(o) & objects) == 0]
+++        toMove = []
+++        for o in objects:
+++          if len(dependencyGetter(o) & objects) == 0:
+++            toMove.append(o)
++         if len(toMove) == 0:
++             raise TypeError("Loop in dependency graph\n" +
++                             "\n".join(o.location for o in objects))
++@@ -11273,14 +11359,16 @@ class CGBindingRoot(CGThing):
++         cgthings.extend([CGDescriptor(x) for x in descriptors])
++ 
++         # Do codegen for all the callback interfaces.  Skip worker callbacks.
++-        cgthings.extend([CGCallbackInterface(x) for x in callbackDescriptors if
++-                         not x.workers])
+++        cgthings.extend([CGCallbackInterface(x) for x in callbackDescriptors if not x.workers])
++ 
++         # Do codegen for JS implemented classes
++         def getParentDescriptor(desc):
++             if not desc.interface.parent:
++-                return set()
++-            return {desc.getDescriptor(desc.interface.parent.identifier.name)}
+++                return set()            
+++            #return (desc.getDescriptor(desc.interface.parent.identifier.name))
+++            s = set()
+++            s.add(desc.getDescriptor(desc.interface.parent.identifier.name))
+++            return s
++         for x in dependencySortObjects(jsImplemented, getParentDescriptor,
++                                        lambda d: d.interface.identifier.name):
++             cgthings.append(CGCallbackInterface(x))
++@@ -11363,7 +11451,7 @@ class CGNativeMember(ClassMethod):
++         self.passJSBitsAsNeeded = passJSBitsAsNeeded
++         self.jsObjectsArePtr = jsObjectsArePtr
++         self.variadicIsSequence = variadicIsSequence
++-        breakAfterSelf = "\n" if breakAfter else ""
+++        breakAfterSelf = ("", "\n")[breakAfter]
++         ClassMethod.__init__(self, name,
++                              self.getReturnType(signature[0], False),
++                              self.getArgs(signature[0], signature[1]),
++@@ -11723,7 +11811,7 @@ class CGNativeMember(ClassMethod):
++             decl = CGTemplatedType("Nullable", decl)
++             ref = True
++         if isMember == "Variadic":
++-            arrayType = "Sequence" if self.variadicIsSequence else "nsTArray"
+++            arrayType = ("nsTArray", "Sequence")[self.variadicIsSequence]
++             decl = CGTemplatedType(arrayType, decl)
++             ref = True
++         elif optional:
++@@ -11739,7 +11827,7 @@ class CGNativeMember(ClassMethod):
++         """
++         decl, ref = self.getArgType(arg.type,
++                                     arg.optional and not arg.defaultValue,
++-                                    "Variadic" if arg.variadic else False)
+++                                    (False, "Variadic")[arg.variadic])
++         if ref:
++             decl = CGWrapper(decl, pre="const ", post="&")
++ 
++@@ -12065,7 +12153,7 @@ class CGExampleClass(CGBindingImplClass)
++         return string.Template(classImpl).substitute(
++             ifaceName=self.descriptor.name,
++             nativeType=self.nativeLeafName(self.descriptor),
++-            parentType=self.nativeLeafName(self.parentDesc) if self.parentIface else "")
+++            parentType=("", self.nativeLeafName(self.parentDesc))[self.parentIface])
++ 
++     @staticmethod
++     def nativeLeafName(descriptor):
++@@ -12639,7 +12727,7 @@ class CGCallbackInterface(CGCallback):
++                             methods, getters=getters, setters=setters)
++ 
++ 
++-class FakeMember():
+++class FakeMember:
++     def __init__(self):
++         self.treatNullAs = "Default"
++ 
++@@ -12684,7 +12772,7 @@ class CallbackMember(CGNativeMember):
++         self.needThisHandling = needThisHandling
++         # If needThisHandling, we generate ourselves as private and the caller
++         # will handle generating public versions that handle the "this" stuff.
++-        visibility = "private" if needThisHandling else "public"
+++        visibility = ("public", "private")[needThisHandling]
++         self.rethrowContentException = rethrowContentException
++         # We don't care, for callback codegen, whether our original member was
++         # a method or attribute or whatnot.  Just always pass FakeMember()
++@@ -12806,7 +12894,7 @@ class CallbackMember(CGNativeMember):
++                 arg.type, self.descriptorProvider,
++                 {
++                     'result': result,
++-                    'successCode': "continue;\n" if arg.variadic else "break;\n",
+++                    'successCode': ("break;\n", "continue;\n")[arg.variadic],
++                     'jsvalRef': "argv.handleAt(%s)" % jsvalIndex,
++                     'jsvalHandle': "argv.handleAt(%s)" % jsvalIndex,
++                     # XXXbz we don't have anything better to use for 'obj',
++@@ -12816,7 +12904,7 @@ class CallbackMember(CGNativeMember):
++                     'returnsNewObject': False,
++                     'exceptionCode': self.exceptionCode
++                 })
++-        except MethodNotNewObjectError as err:
+++        except MethodNotNewObjectError, err:
++             raise TypeError("%s being passed as an argument to %s but is not "
++                             "wrapper cached, so can't be reliably converted to "
++                             "a JS object." %
++@@ -12901,7 +12989,7 @@ class CallbackMember(CGNativeMember):
++ 
++     @staticmethod
++     def ensureASCIIName(idlObject):
++-        type = "attribute" if idlObject.isAttr() else "operation"
+++        type = ("operation", "attribute")[idlObject.isAttr()]
++         if re.match("[^\x20-\x7E]", idlObject.identifier.name):
++             raise SyntaxError('Callback %s name "%s" contains non-ASCII '
++                               "characters.  We can't handle that.  %s" %
++@@ -13124,7 +13212,7 @@ class CGJSImplInitOperation(CallbackOper
++         return "__init"
++ 
++ 
++-class GlobalGenRoots():
+++class GlobalGenRoots:
++     """
++     Roots for global codegen.
++ 
++@@ -13473,7 +13561,7 @@ class CGEventMethod(CGNativeMember):
++     def getArg(self, arg):
++         decl, ref = self.getArgType(arg.type,
++                                     arg.optional and not arg.defaultValue,
++-                                    "Variadic" if arg.variadic else False)
+++                                    (False, "Variadic")[arg.variadic])
++         if ref:
++             decl = CGWrapper(decl, pre="const ", post="&")
++ 
++@@ -13676,8 +13764,7 @@ class CGEventClass(CGBindingImplClass):
++             dropJS += "mozilla::DropJSObjects(this);\n"
++         # Just override CGClass and do our own thing
++         nativeType = self.descriptor.nativeType.split('::')[-1]
++-        ctorParams = ("aOwner, nullptr, nullptr" if self.parentType == "Event"
++-                      else "aOwner")
+++        ctorParams = (("aOwner", "aOwner, nullptr, nullptr")[self.parentType == "Event"])
++ 
++         classImpl = fill(
++             """
++diff -up comm-esr31/mozilla/dom/bindings/Configuration.py.python3 comm-esr31/mozilla/dom/bindings/Configuration.py
++--- comm-esr31/mozilla/dom/bindings/Configuration.py.python3	2014-07-17 18:05:14.000000000 -0600
+++++ comm-esr31/mozilla/dom/bindings/Configuration.py	2014-10-24 11:41:35.451880261 -0600
++@@ -3,6 +3,7 @@
++ # You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++ from WebIDL import IDLInterface, IDLExternalInterface
+++from rhrebase import any, all
++ import os
++ 
++ autogenerated_comment = "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n"
++@@ -95,8 +96,7 @@ class Configuration:
++         (workerCallbacks, workerDictionaries) = findCallbacksAndDictionaries(workerTypes)
++ 
++         self.dictionaries = [d for d in parseData if d.isDictionary()]
++-        self.callbacks = [c for c in parseData if
++-                          c.isCallback() and not c.isInterface()]
+++        self.callbacks = [c for c in parseData if c.isCallback() and not c.isInterface()]
++ 
++         def flagWorkerOrMainThread(items, main, worker):
++             for item in items:
++@@ -380,7 +380,10 @@ class Descriptor(DescriptorProvider):
++                               desc.get('wrapperCache', True)))
++ 
++         def make_name(name):
++-            return name + "_workers" if self.workers else name
+++            if self.workers:
+++              return name + "_workers"
+++            else:
+++              return name
++         self.name = make_name(interface.identifier.name)
++ 
++         # self.extendedAttributes is a dict of dicts, keyed on
++@@ -463,10 +466,10 @@ class Descriptor(DescriptorProvider):
++ 
++         assert member.isAttr()
++         assert bool(getter) != bool(setter)
++-        key = 'getterOnly' if getter else 'setterOnly'
+++        key = ('setterOnly', 'getterOnly')[getter]
++         attrs = self.extendedAttributes['all'].get(name, []) + self.extendedAttributes[key].get(name, [])
++         if throws is None:
++-            throwsAttr = "GetterThrows" if getter else "SetterThrows"
+++            throwsAttr = ("SetterThrows", "GetterThrows")[getter]
++             throws = member.getExtendedAttribute(throwsAttr)
++         maybeAppendInfallibleToAttrs(attrs, throws)
++         return attrs
++diff -up comm-esr31/mozilla/dom/bindings/mach_commands.py.python3 comm-esr31/mozilla/dom/bindings/mach_commands.py
++--- comm-esr31/mozilla/dom/bindings/mach_commands.py.python3	2014-07-17 18:05:14.000000000 -0600
+++++ comm-esr31/mozilla/dom/bindings/mach_commands.py	2014-10-24 11:41:35.451880261 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, # You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import os
++ import sys
++diff -up comm-esr31/mozilla/dom/bindings/mozwebidlcodegen/__init__.py.python3 comm-esr31/mozilla/dom/bindings/mozwebidlcodegen/__init__.py
++--- comm-esr31/mozilla/dom/bindings/mozwebidlcodegen/__init__.py.python3	2014-07-17 18:05:14.000000000 -0600
+++++ comm-esr31/mozilla/dom/bindings/mozwebidlcodegen/__init__.py	2014-10-24 11:41:35.451880261 -0600
++@@ -5,11 +5,11 @@
++ # This module contains code for managing WebIDL files and bindings for
++ # the build system.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import errno
++-import hashlib
++-import json
+++import md5, sha
+++import simplejson as json
++ import logging
++ import os
++ 
++@@ -126,20 +126,20 @@ class WebIDLCodegenManager(LoggingMixin)
++     """
++ 
++     # Global parser derived declaration files.
++-    GLOBAL_DECLARE_FILES = {
+++    GLOBAL_DECLARE_FILES = [
++         'GeneratedAtomList.h',
++         'PrototypeList.h',
++         'RegisterBindings.h',
++         'UnionConversions.h',
++         'UnionTypes.h',
++-    }
+++    ]
++ 
++     # Global parser derived definition files.
++-    GLOBAL_DEFINE_FILES = {
+++    GLOBAL_DEFINE_FILES = [
++         'RegisterBindings.cpp',
++         'UnionTypes.cpp',
++         'PrototypeList.cpp',
++-    }
+++    ]
++ 
++     def __init__(self, config_path, inputs, exported_header_dir,
++         codegen_dir, state_path, cache_dir=None, make_deps_path=None,
++@@ -188,13 +188,15 @@ class WebIDLCodegenManager(LoggingMixin)
++         self._state = WebIDLCodegenManagerState()
++ 
++         if os.path.exists(state_path):
++-            with open(state_path, 'rb') as fh:
+++            fh = open(state_path, 'rb')
+++            if 1:
++                 try:
++                     self._state = WebIDLCodegenManagerState(fh=fh)
++-                except Exception as e:
+++                except Exception, e:
++                     self.log(logging.WARN, 'webidl_bad_state', {'msg': str(e)},
++                         'Bad WebIDL state: {msg}')
++ 
+++            fh.close()
++     @property
++     def config(self):
++         if not self._config:
++@@ -212,8 +214,7 @@ class WebIDLCodegenManager(LoggingMixin)
++         are present and up to date.
++ 
++         This routine is called as part of the build to ensure files that need
++-        to exist are present and up to date. This routine may not be called if
++-        the build dependencies (generated as a result of calling this the first
+++        to exist are present and up to date. This routine may not be called if the build dependencies (generated as a result of calling this the first
++         time) say everything is up to date.
++ 
++         Because reprocessing outputs for every .webidl on every invocation
++@@ -286,9 +287,11 @@ class WebIDLCodegenManager(LoggingMixin)
++             codegen_rule.add_dependencies(global_hashes.keys())
++             codegen_rule.add_dependencies(self._input_paths)
++ 
++-            with FileAvoidWrite(self._make_deps_path) as fh:
+++            fh = FileAvoidWrite(self._make_deps_path).__enter__()
+++            if 1:
++                 mk.dump(fh)
++ 
+++            fh.__exit__(0, 0, 0)
++         self._save_state()
++ 
++         return result
++@@ -313,11 +316,13 @@ class WebIDLCodegenManager(LoggingMixin)
++         parser = WebIDL.Parser(self._cache_dir)
++ 
++         for path in sorted(self._input_paths):
++-            with open(path, 'rb') as fh:
+++            fh = open(path, 'rb')
+++            if 1:
++                 data = fh.read()
++-                hashes[path] = hashlib.sha1(data).hexdigest()
+++                hashes[path] = sha.sha(data).hexdigest()
++                 parser.parse(data, path)
++ 
+++            fh.close()
++         self._parser_results = parser.finish()
++         self._config = Configuration(self._config_path, self._parser_results)
++         self._input_hashes = hashes
++@@ -363,8 +368,12 @@ class WebIDLCodegenManager(LoggingMixin)
++         # a lot of extra work and most build systems don't do that anyway.
++ 
++         # Now we move on to the input files.
++-        old_hashes = {v['filename']: v['sha1']
++-            for v in self._state['webidls'].values()}
+++        old_hashes = {}
+++        for v in self._state['webidls'].values():
+++          old_hashes[v['filename']] = v['sha1']
+++
+++        #old_hashes = {v['filename']: v['sha1']
+++        #    for v in self._state['webidls'].values()}
++ 
++         old_filenames = set(old_hashes.keys())
++         new_filenames = self._input_paths
++@@ -416,11 +425,16 @@ class WebIDLCodegenManager(LoggingMixin)
++ 
++         is_event = stem in self._generated_events_stems
++ 
+++        my_header_dir = None
+++        my_codegen_dir = None
+++        if is_event:
+++          my_header_dir = mozpath.join(header_dir, '%s.h' % stem)
+++          my_codegen_dir = mozpath.join(self._codegen_dir, '%s.cpp' % stem)
++         files = (
++             mozpath.join(header_dir, '%s.h' % binding_stem),
++             mozpath.join(self._codegen_dir, '%s.cpp' % binding_stem),
++-            mozpath.join(header_dir, '%s.h' % stem) if is_event else None,
++-            mozpath.join(self._codegen_dir, '%s.cpp' % stem) if is_event else None,
+++            my_header_dir,
+++            my_codegen_dir,
++         )
++ 
++         return stem, binding_stem, is_event, header_dir, files
++@@ -442,7 +456,9 @@ class WebIDLCodegenManager(LoggingMixin)
++ 
++         for p in self._input_paths:
++             stem, binding_stem, is_event, header_dir, files = self._binding_info(p)
++-            paths |= {f for f in files if f}
+++            for f in files:
+++               if f:
+++                 paths.add(f);
++ 
++         for interface in self._example_interfaces:
++             for p in self._example_paths(interface):
++@@ -484,11 +500,12 @@ class WebIDLCodegenManager(LoggingMixin)
++ 
++         current_hashes = {}
++         for f in current_files:
++-            # This will fail if the file doesn't exist. If a current global
++-            # dependency doesn't exist, something else is wrong.
++-            with open(f, 'rb') as fh:
++-                current_hashes[f] = hashlib.sha1(fh.read()).hexdigest()
+++            # This will failthe file doesn't exist. If a current global # dependency doesn't exist, something = (is wrong., )[]
+++            fh = open(f, 'rb')
+++            if 1:
+++                current_hashes[f] = sha.sha(fh.read()).hexdigest()
++ 
+++            fh.close()
++         # The set of files has changed.
++         if current_files ^ set(self._state['global_depends'].keys()):
++             return True, current_hashes
++@@ -501,9 +518,11 @@ class WebIDLCodegenManager(LoggingMixin)
++         return False, current_hashes
++ 
++     def _save_state(self):
++-        with open(self._state_path, 'wb') as fh:
+++        fh = open(self._state_path, 'wb')
+++        if 1:
++             self._state.dump(fh)
++ 
+++        fh.close()
++     def _maybe_write_codegen(self, obj, declare_path, define_path, result=None):
++         assert declare_path and define_path
++         if not result:
++@@ -532,16 +551,18 @@ def create_build_system_manager(topsrcdi
++     src_dir = os.path.join(topsrcdir, 'dom', 'bindings')
++     obj_dir = os.path.join(topobjdir, 'dom', 'bindings')
++ 
++-    with open(os.path.join(obj_dir, 'file-lists.json'), 'rb') as fh:
+++    fh = open(os.path.join(obj_dir, 'file-lists.json'), 'rb')
+++    if 1:
++         files = json.load(fh)
++ 
+++    fh.close()
++     inputs = (files['webidls'], files['exported_stems'],
++         files['generated_events_stems'], files['example_interfaces'])
++ 
++     cache_dir = os.path.join(obj_dir, '_cache')
++     try:
++         os.makedirs(cache_dir)
++-    except OSError as e:
+++    except OSError, e:
++         if e.errno != errno.EEXIST:
++             raise
++ 
++diff -up comm-esr31/mozilla/dom/bindings/mozwebidlcodegen/test/test_mozwebidlcodegen.py.python3 comm-esr31/mozilla/dom/bindings/mozwebidlcodegen/test/test_mozwebidlcodegen.py
++--- comm-esr31/mozilla/dom/bindings/mozwebidlcodegen/test/test_mozwebidlcodegen.py.python3	2014-07-17 18:05:14.000000000 -0600
+++++ comm-esr31/mozilla/dom/bindings/mozwebidlcodegen/test/test_mozwebidlcodegen.py	2014-10-24 11:41:35.452880257 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import imp
++ import json
++@@ -89,12 +89,14 @@ class TestWebIDLCodegenManager(unittest.
++ 
++         p = args['state_path']
++ 
++-        with open(p, 'wb') as fh:
+++        fh = open(p, 'wb')
+++        if 1:
++             json.dump({
++                 'version': WebIDLCodegenManagerState.VERSION + 1,
++                 'foobar': '1',
++             }, fh)
++ 
+++        fh.close()
++         manager = WebIDLCodegenManager(**args)
++ 
++         self.assertEqual(manager._state['version'],
++@@ -129,7 +131,8 @@ class TestWebIDLCodegenManager(unittest.
++ 
++         self.assertTrue(os.path.isfile(manager._state_path))
++ 
++-        with open(manager._state_path, 'rb') as fh:
+++        fh = open(manager._state_path, 'rb')
+++        if 1:
++             state = json.load(fh)
++             self.assertEqual(state['version'], 1)
++             self.assertIn('webidls', state)
++@@ -139,6 +142,7 @@ class TestWebIDLCodegenManager(unittest.
++             self.assertEqual(len(child['outputs']), 2)
++             self.assertEqual(child['sha1'], 'c41527cad3bc161fa6e7909e48fa11f9eca0468b')
++ 
+++        fh.close()
++     def test_generate_build_files_load_state(self):
++         """State should be equivalent when instantiating a new instance."""
++         args = self._get_manager_args()
++@@ -197,13 +201,15 @@ class TestWebIDLCodegenManager(unittest.
++         self.assertIsNotNone(child_path)
++         child_content = open(child_path, 'rb').read()
++ 
++-        with MockedOpen({child_path: child_content + '\n/* */'}):
+++        MockedOpen({child_path: child_content + '\n/* */'}).__enter__()
+++        if 1:
++             m2 = WebIDLCodegenManager(**args)
++             result = m2.generate_build_files()
++             self.assertEqual(result.inputs, set([child_path]))
++             self.assertEqual(len(result.updated), 0)
++             self.assertEqual(len(result.created), 0)
++ 
+++        MockedOpen({child_path: child_content + '\n/* */'}).__exit__(0, 0, 0)
++     def test_rebuild_dependencies(self):
++         """Ensure an input file used by others results in others rebuilding."""
++         args = self._get_manager_args()
++@@ -221,13 +227,15 @@ class TestWebIDLCodegenManager(unittest.
++         self.assertIsNotNone(parent_path)
++         parent_content = open(parent_path, 'rb').read()
++ 
++-        with MockedOpen({parent_path: parent_content + '\n/* */'}):
+++        MockedOpen({parent_path: parent_content + '\n/* */'}).__enter__()
+++        if 1:
++             m2 = WebIDLCodegenManager(**args)
++             result = m2.generate_build_files()
++             self.assertEqual(result.inputs, {child_path, parent_path})
++             self.assertEqual(len(result.updated), 0)
++             self.assertEqual(len(result.created), 0)
++ 
+++        MockedOpen({parent_path: parent_content + '\n/* */'}).__exit__(0, 0, 0)
++     def test_python_change_regenerate_everything(self):
++         """If a Python file changes, we should attempt to rebuild everything."""
++ 
++@@ -240,7 +248,8 @@ class TestWebIDLCodegenManager(unittest.
++         # the first iteration we read from a temp file. The second iteration
++         # doesn't need to import, so we are fine with a mocked file.
++         fake_path = mozpath.join(OUR_DIR, 'fakemodule.py')
++-        with NamedTemporaryFile('wt') as fh:
+++        fh = NamedTemporaryFile('wt').__enter__()
+++        if 1:
++             fh.write('# Original content')
++             fh.flush()
++             mod = imp.load_source('mozwebidlcodegen.fakemodule', fh.name)
++@@ -248,7 +257,8 @@ class TestWebIDLCodegenManager(unittest.
++ 
++             args = self._get_manager_args()
++             m1 = WebIDLCodegenManager(**args)
++-            with MockedOpen({fake_path: '# Original content'}):
+++            MockedOpen({fake_path: '# Original content'}).__enter__()
+++            if 1:
++                 old_exists = os.path.exists
++                 try:
++                     def exists(p):
++@@ -274,6 +284,8 @@ class TestWebIDLCodegenManager(unittest.
++                     os.path.exists = old_exists
++                     del sys.modules['mozwebidlcodegen.fakemodule']
++ 
+++            MockedOpen({fake_path: '# Original content'}).__exit__(0, 0, 0)
+++        fh.close()
++     def test_copy_input(self):
++         """Ensure a copied .webidl file is handled properly."""
++ 
++diff -up comm-esr31/mozilla/dom/bindings/parser/tests/test_distinguishability.py.python3 comm-esr31/mozilla/dom/bindings/parser/tests/test_distinguishability.py
++--- comm-esr31/mozilla/dom/bindings/parser/tests/test_distinguishability.py.python3	2014-07-17 18:05:14.000000000 -0600
+++++ comm-esr31/mozilla/dom/bindings/parser/tests/test_distinguishability.py	2014-10-24 11:41:35.452880257 -0600
++@@ -89,11 +89,11 @@ def WebIDLTest(parser, harness):
++             harness.check(type1.isDistinguishableFrom(type2),
++                           distinguishable,
++                           "Type %s should %sbe distinguishable from type %s" %
++-                          (type1, "" if distinguishable else "not ", type2))
+++                          (type1, ("not ", "")[distinguishable], type2))
++             harness.check(type2.isDistinguishableFrom(type1),
++                           distinguishable,
++                           "Type %s should %sbe distinguishable from type %s" %
++-                          (type2, "" if distinguishable else "not ", type1))
+++                          (type2, ("not ", "")[distinguishable], type1))
++ 
++     parser = parser.reset()
++     parser.parse("""
++diff -up comm-esr31/mozilla/dom/bindings/parser/tests/test_float_types.py.python3 comm-esr31/mozilla/dom/bindings/parser/tests/test_float_types.py
++--- comm-esr31/mozilla/dom/bindings/parser/tests/test_float_types.py.python3	2014-07-17 18:05:14.000000000 -0600
+++++ comm-esr31/mozilla/dom/bindings/parser/tests/test_float_types.py	2014-10-24 11:41:35.452880257 -0600
++@@ -57,7 +57,7 @@ def WebIDLTest(parser, harness):
++         harness.ok(type.isFloat(), "Type %d should be float" % idx)
++         harness.check(type.isUnrestricted(), idx >= 5,
++                       "Type %d should %sbe unrestricted" % (
++-                idx, "" if idx >= 4 else "not "))
+++                idx, ("not ","")[idx >= 4]))
++ 
++     parser = parser.reset()
++     threw = False
++diff -up comm-esr31/mozilla/dom/bindings/parser/WebIDL.py.python3 comm-esr31/mozilla/dom/bindings/parser/WebIDL.py
++--- comm-esr31/mozilla/dom/bindings/parser/WebIDL.py.python3	2014-07-17 18:05:14.000000000 -0600
+++++ comm-esr31/mozilla/dom/bindings/parser/WebIDL.py	2014-10-24 11:41:35.453880252 -0600
++@@ -9,6 +9,7 @@ import re
++ import os
++ import traceback
++ import math
+++from rhrebase import any, all
++ 
++ # Machinery
++ 
++@@ -69,7 +70,7 @@ class WebIDLError(Exception):
++     def __str__(self):
++         return "%s: %s%s%s" % (self.warning and 'warning' or 'error',
++                                  self.message,
++-                                 ", " if len(self.locations) != 0 else "",
+++                                 ("", ", ")[len(self.locations) != 0],
++                                  "\n".join(self.locations))
++ 
++ class Location(object):
++@@ -78,7 +79,11 @@ class Location(object):
++         self._lineno = lineno
++         self._lexpos = lexpos
++         self._lexdata = lexer.lexdata
++-        self._file = filename if filename else "<unknown>"
+++        self._file = None
+++        if filename:
+++          self._file = filename
+++        else:
+++          self._file = "<unknown>"
++ 
++     def __eq__(self, other):
++         return self._lexpos == other._lexpos and \
++@@ -551,7 +556,11 @@ class IDLInterface(IDLObjectWithScope):
++                               [self.location])
++ 
++         assert not self.parent or isinstance(self.parent, IDLIdentifierPlaceholder)
++-        parent = self.parent.finish(scope) if self.parent else None
+++        parent = None
+++        if self.parent:
+++          parent = self.parent.finish(scope)
+++        else:
+++          parent = None
++         if parent and isinstance(parent, IDLExternalInterface):
++             raise WebIDLError("%s inherits from %s which does not have "
++                               "a definition" %
++@@ -561,8 +570,8 @@ class IDLInterface(IDLObjectWithScope):
++         assert not parent or isinstance(parent, IDLInterface)
++ 
++         self.parent = parent
++-
++-        assert iter(self.members)
+++        #print "SELF_MEMB", self.members 
+++        # we may ignore it, empty array is also iterable in python 2.6 assert iter(self.members)
++ 
++         if self.parent:
++             self.parent.finish(scope)
++@@ -685,11 +694,9 @@ class IDLInterface(IDLObjectWithScope):
++             # worry about anything other than our parent, because it has already
++             # imported its ancestors unforgeable attributes into its member
++             # list.
++-            for unforgeableAttr in (attr for attr in self.parent.members if
++-                                    attr.isAttr() and not attr.isStatic() and
+++            for unforgeableAttr in (attr for attr in self.parent.members if attr.isAttr() and not attr.isStatic() and
++                                     attr.isUnforgeable()):
++-                shadows = [ m for m in self.members if
++-                            (m.isAttr() or m.isMethod()) and
+++                shadows = [ m for m in self.members if (m.isAttr() or m.isMethod()) and
++                             not m.isStatic() and
++                             m.identifier.name == unforgeableAttr.identifier.name ]
++                 if len(shadows) != 0:
++@@ -853,8 +860,7 @@ class IDLInterface(IDLObjectWithScope):
++             not any(m.isAttr() for m in self.members) and
++             # There is at least one regular operation, and all regular
++             # operations have the same identifier
++-            len(set(m.identifier.name for m in self.members if
++-                    m.isMethod() and not m.isStatic())) == 1)
+++            len(set(m.identifier.name for m in self.members if m.isMethod() and not m.isStatic())) == 1)
++ 
++     def inheritanceDepth(self):
++         depth = 0
++@@ -910,7 +916,11 @@ class IDLInterface(IDLObjectWithScope):
++                     raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible",
++                                       [self.location])
++ 
++-                args = attr.args() if attr.hasArgs() else []
+++                args = None
+++                if attr.hasArgs():
+++                  args = attr.args()
+++                else:
+++                  args = []
++ 
++                 retType = IDLWrapperType(self.location, self)
++                 
++@@ -995,7 +1005,8 @@ class IDLInterface(IDLObjectWithScope):
++                                   [attr.location])
++ 
++             attrlist = attr.listValue()
++-            self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True
+++
+++            self._extendedAttrDict[identifier] = (True, attrlist)[len(attrlist) > 0]
++ 
++     def addImplementedInterface(self, implementedInterface):
++         assert(isinstance(implementedInterface, IDLInterface))
++@@ -2666,7 +2677,7 @@ class IDLInterfaceMember(IDLObjectWithId
++         for attr in attrs:
++             self.handleExtendedAttribute(attr)
++             attrlist = attr.listValue()
++-            self._extendedAttrDict[attr.identifier()] = attrlist if len(attrlist) else True
+++            self._extendedAttrDict[attr.identifier()] = (True, attrlist)[len(attrlist)]
++ 
++     def handleExtendedAttribute(self, attr):
++         pass
++@@ -3420,8 +3431,7 @@ class IDLMethod(IDLInterfaceMember, IDLS
++                             [self.location, overload.location])
++ 
++     def overloadsForArgCount(self, argc):
++-        return [overload for overload in self._overloads if
++-                len(overload.arguments) == argc or
+++        return [overload for overload in self._overloads if len(overload.arguments) == argc or
++                 (len(overload.arguments) > argc and
++                  all(arg.optional for arg in overload.arguments[argc:])) or
++                 (len(overload.arguments) < argc and
++@@ -3890,7 +3900,10 @@ class Parser(Tokenizer):
++         """
++             InterfaceMembers : ExtendedAttributeList InterfaceMember InterfaceMembers
++         """
++-        p[0] = [p[2]] if p[2] else []
+++        if p[2]:
+++          p[0] = [p[2]]
+++        else:
+++          p[0] = []
++ 
++         assert not p[1] or p[2]
++         p[2].addExtendedAttributes(p[1])
++@@ -4183,11 +4196,27 @@ class Parser(Tokenizer):
++         # by the parser, so we can assert here.
++         assert not stringifier or len(qualifiers) == 1
++ 
++-        getter = True if IDLMethod.Special.Getter in p[1] else False
++-        setter = True if IDLMethod.Special.Setter in p[1] else False
++-        creator = True if IDLMethod.Special.Creator in p[1] else False
++-        deleter = True if IDLMethod.Special.Deleter in p[1] else False
++-        legacycaller = True if IDLMethod.Special.LegacyCaller in p[1] else False
+++        getter = False
+++        if IDLMethod.Special.Getter in p[1]:
+++          getter = True
+++        else:
+++          getter = False
+++        setter = False
+++        if IDLMethod.Special.Setter in p[1]:
+++          setter = True
+++        creator = None
+++        if IDLMethod.Special.Creator in p[1]:
+++          creator = True
+++        else:
+++          creator = False
+++        deleter = False
+++        if IDLMethod.Special.Deleter in p[1]:
+++          deleter = True
+++        legacycaller = None
+++        if IDLMethod.Special.LegacyCaller in p[1]:
+++          legacycaller = True
+++        else:
+++          legacycaller = False
++ 
++         if getter or deleter:
++             if setter or creator:
++@@ -4203,7 +4232,7 @@ class Parser(Tokenizer):
++         if getter or deleter:
++             if len(arguments) != 1:
++                 raise WebIDLError("%s has wrong number of arguments" %
++-                                  ("getter" if getter else "deleter"),
+++                                  (("deleter", "getter")[getter]),
++                                   [self.getLocation(p, 2)])
++             argType = arguments[0].type
++             if argType == BuiltinTypes[IDLBuiltinType.Types.domstring]:
++@@ -4212,12 +4241,11 @@ class Parser(Tokenizer):
++                 specialType = IDLMethod.NamedOrIndexed.Indexed
++             else:
++                 raise WebIDLError("%s has wrong argument type (must be DOMString or UnsignedLong)" %
++-                                  ("getter" if getter else "deleter"),
+++                                  (("deleter", "getter")[getter]),
++                                   [arguments[0].location])
++             if arguments[0].optional or arguments[0].variadic:
++                 raise WebIDLError("%s cannot have %s argument" %
++-                                  ("getter" if getter else "deleter",
++-                                   "optional" if arguments[0].optional else "variadic"),
+++                                  (("deleter", "getter")[getter], ("variadic", "optional")[garguments[0].optional]),
++                                    [arguments[0].location])
++         if getter:
++             if returnType.isVoid():
++@@ -4226,7 +4254,7 @@ class Parser(Tokenizer):
++         if setter or creator:
++             if len(arguments) != 2:
++                 raise WebIDLError("%s has wrong number of arguments" %
++-                                  ("setter" if setter else "creator"),
+++                                  (("creator", "setter")[setter]),
++                                   [self.getLocation(p, 2)])
++             argType = arguments[0].type
++             if argType == BuiltinTypes[IDLBuiltinType.Types.domstring]:
++@@ -4235,17 +4263,15 @@ class Parser(Tokenizer):
++                 specialType = IDLMethod.NamedOrIndexed.Indexed
++             else:
++                 raise WebIDLError("%s has wrong argument type (must be DOMString or UnsignedLong)" %
++-                                  ("setter" if setter else "creator"),
+++                                  (("creator", "setter")[setter]),
++                                   [arguments[0].location])
++             if arguments[0].optional or arguments[0].variadic:
++                 raise WebIDLError("%s cannot have %s argument" %
++-                                  ("setter" if setter else "creator",
++-                                   "optional" if arguments[0].optional else "variadic"),
+++                                  (("creator", "setter")[setter], ("variadic", "optional")[arguments[0].optional]),
++                                   [arguments[0].location])
++             if arguments[1].optional or arguments[1].variadic:
++                 raise WebIDLError("%s cannot have %s argument" %
++-                                  ("setter" if setter else "creator",
++-                                   "optional" if arguments[1].optional else "variadic"),
+++                                  (("creator", "setter")[setter], ("variadic", "optional")[arguments[1].optional]),
++                                   [arguments[1].location])
++ 
++         if stringifier:
++@@ -4264,15 +4290,21 @@ class Parser(Tokenizer):
++                                   [self.getLocation(p, 2)])
++ 
++             location = BuiltinLocation("<auto-generated-identifier>")
+++            first_parm = ""
+++            if specialType == IDLMethod.NamedOrIndexed.Named:
+++              first_parm = "named"
+++            elif specialType == IDLMethod.NamedOrIndexed.Indexed:
+++              first_parm = "indexed"
+++
++             identifier = IDLUnresolvedIdentifier(location, "__%s%s%s%s%s%s%s" %
++-                ("named" if specialType == IDLMethod.NamedOrIndexed.Named else \
++-                 "indexed" if specialType == IDLMethod.NamedOrIndexed.Indexed else "",
++-                 "getter" if getter else "",
++-                 "setter" if setter else "",
++-                 "deleter" if deleter else "",
++-                 "creator" if creator else "",
++-                 "legacycaller" if legacycaller else "",
++-                 "stringifier" if stringifier else ""), allowDoubleUnderscore=True)
+++                (first_parm,
+++                 ("", "getter")[getter], 
+++                 ("", "setter")[setter],
+++                 ("", "deleter")[deleter], 
+++                 ("", "creator")[creator],
+++                 ("", "legacycaller")[legacycaller], 
+++                 ("", "stringifier")[stringifier]), 
+++                allowDoubleUnderscore=True)
++ 
++         method = IDLMethod(self.getLocation(p, 2), identifier, returnType, arguments,
++                            static=static, getter=getter, setter=setter, creator=creator,
++@@ -4391,7 +4423,10 @@ class Parser(Tokenizer):
++         """
++             ArgumentList : Argument Arguments
++         """
++-        p[0] = [p[1]] if p[1] else []
+++        if p[1]:
+++          p[0] = [p[1]]
+++        else:
+++          p[0] = []
++         p[0].extend(p[2])
++ 
++     def p_ArgumentListEmpty(self, p):
++@@ -4404,7 +4439,10 @@ class Parser(Tokenizer):
++         """
++             Arguments : COMMA Argument Arguments
++         """
++-        p[0] = [p[2]] if p[2] else []
+++        if p[2]:
+++          p[0] = [p[2]]
+++        else:
+++          p[0] = []
++         p[0].extend(p[3])
++ 
++     def p_ArgumentsEmpty(self, p):
++@@ -4539,7 +4577,10 @@ class Parser(Tokenizer):
++         """
++             ExtendedAttributes : COMMA ExtendedAttribute ExtendedAttributes
++         """
++-        p[0] = [p[2]] if p[2] else []
+++        if p[2]:
+++          p[0] = [p[2]]
+++        else:
+++          p[0] = []
++         p[0].extend(p[3])
++ 
++     def p_ExtendedAttributesEmpty(self, p):
++@@ -5036,10 +5077,8 @@ class Parser(Tokenizer):
++         # First, finish all the IDLImplementsStatements.  In particular, we
++         # have to make sure we do those before we do the IDLInterfaces.
++         # XXX khuey hates this bit and wants to nuke it from orbit.
++-        implementsStatements = [ p for p in self._productions if
++-                                 isinstance(p, IDLImplementsStatement)]
++-        otherStatements = [ p for p in self._productions if
++-                            not isinstance(p, IDLImplementsStatement)]
+++        implementsStatements = [ p for p in self._productions if isinstance(p, IDLImplementsStatement)]
+++        otherStatements = [ p for p in self._productions if not isinstance(p, IDLImplementsStatement)]
++         for production in implementsStatements:
++             production.finish(self.globalScope())
++         for production in otherStatements:
++diff -up comm-esr31/mozilla/dom/imptests/importTestsuite.py.python3 comm-esr31/mozilla/dom/imptests/importTestsuite.py
++--- comm-esr31/mozilla/dom/imptests/importTestsuite.py.python3	2014-07-17 18:05:15.000000000 -0600
+++++ comm-esr31/mozilla/dom/imptests/importTestsuite.py	2014-10-24 11:41:35.453880252 -0600
++@@ -10,7 +10,11 @@ Note: removes both source and destinatio
++       use with outstanding changes in either directory.
++ """
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ import os
++ import shutil
++@@ -50,7 +54,8 @@ def getData(confFile):
++     iden = ""
++     directories = []
++     try:
++-        with open(confFile, 'r') as fp:
+++        fp = open(confFile, 'r')
+++        if 1:
++             first = True
++             for line in fp:
++                 if first:
++@@ -58,6 +63,7 @@ def getData(confFile):
++                     first = False
++                 else:
++                     directories.append(line.strip())
+++        fp.close()
++     finally:
++         return vcs, url, iden, directories
++ 
++@@ -129,16 +135,20 @@ def printBuildFiles(dest, directories):
++         all_support |= set('%s/%s' % (d['path'], p) for p in d['supportfiles'])
++ 
++         if d["reftests"]:
++-            with open(path + "/reftest.list", "w") as fh:
+++            fh = open(path + "/reftest.list", "w")
+++            if 1:
++                 result = writeBuildFiles.substReftestList("importTestsuite.py",
++                     d["reftests"])
++                 fh.write(result)
++ 
+++            fh.close()
++     manifest_path = dest + '/mochitest.ini'
++-    with open(manifest_path, 'w') as fh:
+++    fh = open(manifest_path, 'w')
+++    if 1:
++         result = writeBuildFiles.substManifest('importTestsuite.py',
++             all_mochitests, all_support)
++         fh.write(result)
+++    fh.close()
++     subprocess.check_call(["hg", "add", manifest_path])
++ 
++ def hgadd(dest, directories):
++@@ -176,7 +186,7 @@ def importRepo(confFile):
++         hgadd(dest, directories)
++         print("Removing %s again..." % hgdest)
++         subprocess.check_call(["rm", "-rf", hgdest])
++-    except subprocess.CalledProcessError as e:
+++    except subprocess.CalledProcessError, e:
++         print(e.returncode)
++     finally:
++         print("Done")
++diff -up comm-esr31/mozilla/dom/imptests/parseFailures.py.python3 comm-esr31/mozilla/dom/imptests/parseFailures.py
++--- comm-esr31/mozilla/dom/imptests/parseFailures.py.python3	2014-07-17 18:05:15.000000000 -0600
+++++ comm-esr31/mozilla/dom/imptests/parseFailures.py	2014-10-24 11:41:35.454880248 -0600
++@@ -2,7 +2,11 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ import collections
++ import json
++@@ -59,11 +63,13 @@ def writeFiles(files):
++         pathmap.setdefault(dirp, []).append(leaf)
++ 
++     for k, v in pathmap.items():
++-        with open(k + '/mochitest.ini', 'w') as fh:
+++        fh = open(k + '/mochitest.ini', 'w')
+++        if 1:
++             result = writeBuildFiles.substManifest('parseFailures.py', v, [])
++             fh.write(result)
++ 
++ 
+++        fh.close()
++ def main(logPath):
++     fp = open(logPath, 'rb')
++     lines = extractLines(fp)
++diff -up comm-esr31/mozilla/dom/imptests/updateTestharness.py.python3 comm-esr31/mozilla/dom/imptests/updateTestharness.py
++--- comm-esr31/mozilla/dom/imptests/updateTestharness.py.python3	2014-07-17 18:05:15.000000000 -0600
+++++ comm-esr31/mozilla/dom/imptests/updateTestharness.py	2014-10-24 11:41:35.454880248 -0600
++@@ -3,7 +3,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this file,
++ # You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import subprocess
++ 
++@@ -18,7 +18,11 @@ subprocess.check_call(["git", "clone", r
++ subprocess.check_call(["git", "submodule", "init"], cwd=dest)
++ subprocess.check_call(["git", "submodule", "update"], cwd=dest)
++ for f in files:
++-    path = f["d"] if "d" in f else f["f"]
+++    path = None
+++    if "d" in f:
+++      path = f["d"]
+++    else:
+++      path = f["f"]
++     subprocess.check_call(["cp", "%s/%s" % (dest, path), f["f"]])
++     subprocess.check_call(["hg", "add", f["f"]])
++ subprocess.check_call(["rm", "-rf", dest])
++diff -up comm-esr31/mozilla/dom/imptests/writeBuildFiles.py.python3 comm-esr31/mozilla/dom/imptests/writeBuildFiles.py
++--- comm-esr31/mozilla/dom/imptests/writeBuildFiles.py.python3	2014-07-17 18:05:15.000000000 -0600
+++++ comm-esr31/mozilla/dom/imptests/writeBuildFiles.py	2014-10-24 11:41:35.454880248 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this file,
++ # You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import string
++ 
++diff -up comm-esr31/mozilla/gfx/gl/GLParseRegistryXML.py.python3 comm-esr31/mozilla/gfx/gl/GLParseRegistryXML.py
++--- comm-esr31/mozilla/gfx/gl/GLParseRegistryXML.py.python3	2014-07-17 18:05:20.000000000 -0600
+++++ comm-esr31/mozilla/gfx/gl/GLParseRegistryXML.py	2014-10-24 11:41:35.454880248 -0600
++@@ -181,7 +181,8 @@ class GLDatabase:
++ 
++ 
++     def exportConsts(self, path):
++-        with open(getScriptDir() + path,'w') as f:
+++        f = open(getScriptDir() + path,'w')
+++        if 1:
++ 
++             headerFile = GLConstHeader(f)
++             headerFile.formatFileBegin()
++@@ -205,6 +206,7 @@ class GLDatabase:
++             headerFile.formatFileEnd()
++ 
++ 
+++        f.close()
++ glDatabase = GLDatabase()
++ 
++ success = glDatabase.loadXML('gl.xml')
++diff -up comm-esr31/mozilla/gfx/harfbuzz/src/gen-arabic-table.py.python3 comm-esr31/mozilla/gfx/harfbuzz/src/gen-arabic-table.py
++--- comm-esr31/mozilla/gfx/harfbuzz/src/gen-arabic-table.py.python3	2014-07-17 18:05:20.000000000 -0600
+++++ comm-esr31/mozilla/gfx/harfbuzz/src/gen-arabic-table.py	2014-10-24 11:41:35.454880248 -0600
++@@ -122,10 +122,14 @@ def print_shaping_table(f):
++ 	keys = shapes.keys ()
++ 	min_u, max_u = min (keys), max (keys)
++ 	for u in range (min_u, max_u + 1):
++-		s = [shapes[u][shape] if u in shapes and shape in shapes[u] else 0
+++		s = None
+++if u in shapes and shape in shapes[u]:
+++  s = [shapes[u][shape]
+++else:
+++  s = 0
++ 		     for shape in  ['initial', 'medial', 'final', 'isolated']]
++ 		value = ', '.join ("0x%04X" % c for c in s)
++-		print "  {%s}, /* U+%04X %s */" % (value, u, names[u] if u in names else "")
+++		print "  {%s}, /* U+%04X %s */" % (value, u, names[u]u in names = (""), )[]
++ 
++ 	print "};"
++ 	print
++diff -up comm-esr31/mozilla/gfx/layers/genTables.py.python3 comm-esr31/mozilla/gfx/layers/genTables.py
++--- comm-esr31/mozilla/gfx/layers/genTables.py.python3	2014-07-17 18:05:20.000000000 -0600
+++++ comm-esr31/mozilla/gfx/layers/genTables.py	2014-10-24 11:41:35.455880244 -0600
++@@ -3,10 +3,12 @@
++ def table_generator(f):
++   return ",\n".join([", ".join(["0x%2.2x" % h for h in [f(i) for i in range(r,r+16)]]) for r in range(0, 65536, 16)])
++ 
++-with open("PremultiplyTables.h", "w") as f:
+++f = open("PremultiplyTables.h", "w")
+++if 1:
++   f.write("const uint8_t PremultiplyTable[256*256] = {\n");
++   f.write(table_generator(lambda i: ((i / 256) * (i % 256) + 254) / 255) + "\n")
++   f.write("};\n");
++   f.write("const uint8_t UnpremultiplyTable[256*256] = {\n");
++-  f.write(table_generator(lambda i: (i % 256) * 255 / ((i / 256) if (i / 256) > 0 else 255) % 256) + "\n")
+++  f.write(table_generator(lambda i: (i % 256) * 255 / ((255, i / 256)[(i / 256) > 0]) % 256) + "\n")
++   f.write("};\n");
+++f.close()
++diff -up comm-esr31/mozilla/gfx/thebes/gencjkcisvs.py.python3 comm-esr31/mozilla/gfx/thebes/gencjkcisvs.py
++--- comm-esr31/mozilla/gfx/thebes/gencjkcisvs.py.python3	2014-07-17 18:05:21.000000000 -0600
+++++ comm-esr31/mozilla/gfx/thebes/gencjkcisvs.py	2014-10-24 11:41:35.455880244 -0600
++@@ -6,7 +6,11 @@ import os.path
++ import re
++ import sys
++ 
++-f = open(sys.argv[1] if len(sys.argv) > 1 else 'StandardizedVariants.txt')
+++f = None
+++if len(sys.argv) > 1:
+++  f = open(sys.argv[1]
+++else:
+++  f = 'StandardizedVariants.txt')
++ 
++ line = f.readline()
++ m = re.compile('^# (StandardizedVariants(-\d+(\.\d+)*)?\.txt)').search(line)
++@@ -37,7 +41,7 @@ for (k, mappings) in sorted(vsdict.items
++     offsets.append(length)
++     length += 4 + 5 * len(mappings)
++ 
++-f = open(sys.argv[2] if len(sys.argv) > 2 else 'CJKCompatSVS.cpp', 'wb')
+++f = open(('CJKCompatSVS.cpp', sys.argv[2])[len(sys.argv) > 2], 'wb')
++ f.write("""// Generated by %s. Do not edit.
++ 
++ #include <stdint.h>
++diff -up comm-esr31/mozilla/gfx/thebes/genTables.py.python3 comm-esr31/mozilla/gfx/thebes/genTables.py
++--- comm-esr31/mozilla/gfx/thebes/genTables.py.python3	2014-07-17 18:05:21.000000000 -0600
+++++ comm-esr31/mozilla/gfx/thebes/genTables.py	2014-10-24 11:41:35.455880244 -0600
++@@ -3,10 +3,14 @@
++ def table_generator(f):
++     return ",\n".join([", ".join(["0x%2.2x" % h for h in [f(i) for i in range(r,r+16)]]) for r in range(0, 65536, 16)])
++ 
++-with open("DeprecatedPremultiplyTables.h", "w") as f:
+++f = open("DeprecatedPremultiplyTables.h", "w")
+++if 1:
++   f.write("const uint8_t gfxUtils::sPremultiplyTable[256*256] = {\n");
++   f.write(table_generator(lambda i: ((i / 256) * (i % 256) + 254) / 255) + "\n")
++   f.write("};\n");
++   f.write("const uint8_t gfxUtils::sUnpremultiplyTable[256*256] = {\n");
++-  f.write(table_generator(lambda i: (i % 256) * 255 / ((i / 256) if (i / 256) > 0 else 255) % 256) + "\n")
+++  #f.write(table_generator(lambda i: (i % 256) * 255 / ((i / 256) if (i / 256) > 0 else 255) % 256) + "\n")
+++  #f.write(table_generator(lambda i: (i % 256) * 255 / ((i / 256, 255)[(i / 256) > 0]) % 256) + "\n")
+++  f.write(table_generator(lambda i: (i % 256) * 255 / ((255, i / 256)[(i / 256) > 0]) % 256) + "\n")
++   f.write("};\n");
+++f.close()
++diff -up comm-esr31/mozilla/ipc/chromium/src/third_party/libevent/event_rpcgen.py.python3 comm-esr31/mozilla/ipc/chromium/src/third_party/libevent/event_rpcgen.py
++--- comm-esr31/mozilla/ipc/chromium/src/third_party/libevent/event_rpcgen.py.python3	2014-07-17 18:05:24.000000000 -0600
+++++ comm-esr31/mozilla/ipc/chromium/src/third_party/libevent/event_rpcgen.py	2014-10-24 11:41:35.455880244 -0600
++@@ -1628,8 +1628,7 @@ class Usage(RpcGenError):
++ 
++ class CommandLine:
++     def __init__(self, argv):
++-        """Initialize a command-line to launch event_rpcgen, as if
++-           from a command-line with CommandLine(sys.argv).  If you're
+++        """Initialize a command-line to launch event_rpcgen, as if from a command-line with CommandLine(sys.argv).  If you're
++            calling this directly, remember to provide a dummy value
++            for sys.argv[0]
++         """
++diff -up comm-esr31/mozilla/ipc/ipdl/ipdl/__init__.py.python3 comm-esr31/mozilla/ipc/ipdl/ipdl/__init__.py
++--- comm-esr31/mozilla/ipc/ipdl/ipdl/__init__.py.python3	2014-07-17 18:05:24.000000000 -0600
+++++ comm-esr31/mozilla/ipc/ipdl/ipdl/__init__.py	2014-10-24 11:41:35.456880240 -0600
++@@ -30,8 +30,7 @@ def parse(specstring, filename='/stdin',
++ 
++ 
++ def typecheck(ast, errout=sys.stderr):
++-    '''Return True iff |ast| is well typed.  Print errors to |errout| if
++-    it is not.'''
+++    '''Return True iff |ast| is well typed.  Print errors to |errout| if it is not.'''
++     return TypeCheck().check(ast, errout)
++ 
++ 
++diff -up comm-esr31/mozilla/ipc/ipdl/ipdl/lower.py.python3 comm-esr31/mozilla/ipc/ipdl/ipdl/lower.py
++--- comm-esr31/mozilla/ipc/ipdl/ipdl/lower.py.python3	2014-07-17 18:05:24.000000000 -0600
+++++ comm-esr31/mozilla/ipc/ipdl/ipdl/lower.py	2014-10-24 11:41:35.457880235 -0600
++@@ -3876,7 +3876,7 @@ class _GenerateProtocolActorCode(ipdl.as
++ 
++             registerstmt = StmtExpr(ExprCall(p.registerIDMethod(),
++                                     args=[actorvar, _actorId(actorvar)]))
++-            # Implement if (actor id > 0) then Register() else RegisterID()
+++            # Implement(actor id > 0) then Register() = (RegisterID(), )[]
++             if manageeipdltype in inoutCtorTypes:
++                 registerif = StmtIf(ExprBinary(_actorId(actorvar),
++                                                '>',
++@@ -4684,7 +4684,7 @@ class _GenerateProtocolActorCode(ipdl.as
++                 ct = c.bareType()
++                 readcase.addstmts([
++                     StmtDecl(Decl(ct, tmpvar.name),
++-                      init=c.defaultValue() if ct.ptr else None),
+++                      init=(None, c.defaultValue())[ct.ptr]),
++                     StmtExpr(ExprAssn(ExprDeref(var), tmpvar)),
++                     StmtReturn(self.read(
++                         c.ipdltype,
++@@ -5363,7 +5363,7 @@ class _GenerateProtocolActorCode(ipdl.as
++             ExprSelect(msgptr, '->', 'Log'),
++             args=[ ExprLiteral.String('['+ actorname +'] '+ pfx),
++                    self.protocol.callOtherProcess(actor),
++-                   ExprLiteral.TRUE if receiving else ExprLiteral.FALSE ])) ])
+++                   (ExprLiteral.FALSE, ExprLiteral.TRUE)[receiving] ])) ])
++ 
++     def profilerLabel(self, tag, msgname):
++         return StmtExpr(ExprCall(ExprVar('PROFILER_LABEL'),
++@@ -5393,7 +5393,11 @@ class _GenerateProtocolActorCode(ipdl.as
++             action = ExprVar('Trigger::Recv')
++         else: assert 0 and 'unknown combo %s/%s'% (self.side, direction)
++ 
++-        msgid = md.pqMsgId() if not reply else md.pqReplyId()
+++        msgid = None
+++        if not reply:
+++          msgid = md.pqMsgId()
+++        else:
+++          msgid = md.pqReplyId()
++         ifbad = StmtIf(ExprNot(
++             ExprCall(
++                 ExprVar(self.protocol.name +'::Transition'),
++diff -up comm-esr31/mozilla/js/src/builtin/embedjs.py.python3 comm-esr31/mozilla/js/src/builtin/embedjs.py
++--- comm-esr31/mozilla/js/src/builtin/embedjs.py.python3	2014-07-17 18:05:25.000000000 -0600
+++++ comm-esr31/mozilla/js/src/builtin/embedjs.py	2014-10-24 11:41:35.457880235 -0600
++@@ -36,7 +36,7 @@
++ #
++ # It uses the C preprocessor to process its inputs.
++ 
++-from __future__ import with_statement
+++
++ import re, sys, os, fileinput, subprocess
++ import shlex
++ from optparse import OptionParser
++@@ -81,8 +81,10 @@ def embed(cpp, msgs, sources, c_out, js_
++   # Clang seems to complain and not output anything if the extension of the
++   # input is not something it recognizes, so just fake a .h here.
++   tmp = 'selfhosted.js.h'
++-  with open(tmp, 'wb') as output:
+++  output = open(tmp, 'wb')
+++  if 1:
++     output.write('\n'.join([msgs] + ['#include "%(s)s"' % { 's': source } for source in sources]))
+++  output.close()
++   cmdline = cpp + ['-D%(k)s=%(v)s' % { 'k': k, 'v': env[k] } for k in env] + [tmp]
++   p = subprocess.Popen(cmdline, stdout=subprocess.PIPE)
++   processed = ''
++@@ -90,9 +92,12 @@ def embed(cpp, msgs, sources, c_out, js_
++     if not line.startswith('#'):
++       processed += line
++   os.remove(tmp)
++-  with open(js_out, 'w') as output:
+++  output = open(js_out, 'w')
+++  if 1:
++     output.write(processed)
++-  with open(c_out, 'w') as output:
+++  output.close()
+++  output = open(c_out, 'w')
+++  if 1:
++     if 'USE_ZLIB' in env:
++       import zlib
++       compressed = zlib.compress(processed)
++@@ -114,12 +119,15 @@ def embed(cpp, msgs, sources, c_out, js_
++           'raw_total_length': len(processed)
++       })
++ 
+++  output.close()
++ def process_msgs(cpp, msgs):
++   # Clang seems to complain and not output anything if the extension of the
++   # input is not something it recognizes, so just fake a .h here.
++   tmp = 'selfhosted.msg.h'
++-  with open(tmp, 'wb') as output:
+++  output = open(tmp, 'wb')
+++  if 1:
++     output.write("""\
+++  output.close()
++ #define hash #
++ #define id(x) x
++ #define hashify(x) id(hash)x
++diff -up comm-esr31/mozilla/js/src/configure.python3 comm-esr31/mozilla/js/src/configure
++--- comm-esr31/mozilla/js/src/configure.python3	2014-07-17 18:06:19.000000000 -0600
+++++ comm-esr31/mozilla/js/src/configure	2014-10-24 11:41:35.459880227 -0600
++@@ -16270,7 +16270,8 @@ rm confdefs.pytmp confdefs.h
++ cat >> $CONFIG_STATUS <<\EOF
++ ] ]
++ 
++-substs = [(name[1:-1], value[1:-1] if isinstance(value, types.StringTypes) else value) for name, value in [
+++substs = []
+++mylist = [
++ EOF
++ 
++ sed 's/$/,/' >> $CONFIG_STATUS <<EOF
++@@ -16578,7 +16579,12 @@ for ac_subst_arg in $_subconfigure_ac_su
++ done
++ 
++ cat >> $CONFIG_STATUS <<\EOF
++-] ]
+++]
+++for name, value in mylist:
+++  if isinstance(value, types.StringTypes):
+++    substs.append( (name[1:-1], value[1:-1]) )
+++  else:
+++    substs.append( (name[1:-1], value) )
++ 
++ non_global_defines = [
++ EOF
++diff -up comm-esr31/mozilla/js/src/devtools/rootAnalysis/analyze.py.python3 comm-esr31/mozilla/js/src/devtools/rootAnalysis/analyze.py
++--- comm-esr31/mozilla/js/src/devtools/rootAnalysis/analyze.py.python3	2014-07-17 18:05:25.000000000 -0600
+++++ comm-esr31/mozilla/js/src/devtools/rootAnalysis/analyze.py	2014-10-24 11:41:35.459880227 -0600
++@@ -89,11 +89,13 @@ def generate_hazards(config, outfilename
++     if final_status:
++         raise subprocess.CalledProcessError(final_status, 'analyzeRoots.js')
++ 
++-    with open(outfilename, 'w') as output:
+++    output = open(outfilename, 'w')
+++    if 1:
++         command = ['cat'] + [ 'rootingHazards.%s' % (i+1,) for i in range(config['jobs']) ]
++         print_command(command, outfile=outfilename)
++         subprocess.call(command, stdout=output)
++ 
+++    output.close()
++ JOBS = { 'dbs':
++              (('%(ANALYSIS_SCRIPTDIR)s/run_complete',
++                '--foreground',
++@@ -171,8 +173,10 @@ def run_job(name, config):
++         if stdout_filename is None:
++             subprocess.check_call(command, env=env(config))
++         else:
++-            with open(stdout_filename, 'w') as output:
+++            output = open(stdout_filename, 'w')
+++            if 1:
++                 subprocess.check_call(command, stdout=output, env=env(config))
+++            output.close()
++         for (temp, final) in temp_map.items():
++             try:
++                 os.rename(temp, final)
++diff -up comm-esr31/mozilla/js/src/devtools/rootAnalysis/explain.py.python3 comm-esr31/mozilla/js/src/devtools/rootAnalysis/explain.py
++--- comm-esr31/mozilla/js/src/devtools/rootAnalysis/explain.py.python3	2014-07-17 18:05:25.000000000 -0600
+++++ comm-esr31/mozilla/js/src/devtools/rootAnalysis/explain.py	2014-10-24 11:41:35.460880223 -0600
++@@ -65,7 +65,8 @@ try:
++                 else:
++                     hazardousGCFunctions[current_gcFunction][-1] += line
++ 
++-        with open(args.gcFunctions) as gcFunctions:
+++        gcFunctions = open(args.gcFunctions)
+++        if 1:
++             gcExplanations = {}  # gcFunction => stack showing why it can GC
++ 
++             current_func = None
++@@ -91,7 +92,8 @@ try:
++                 else:
++                     print >>hazards, gcHazards[index]
++ 
++-except IOError as e:
+++        gcFunctions.close()
+++except IOError, e:
++     print 'Failed: %s' % str(e)
++ 
++ print("Wrote %s" % args.hazards)
++diff -up comm-esr31/mozilla/js/src/gdb/lib-for-tests/catcher.py.python3 comm-esr31/mozilla/js/src/gdb/lib-for-tests/catcher.py
++--- comm-esr31/mozilla/js/src/gdb/lib-for-tests/catcher.py.python3	2014-07-17 18:05:25.000000000 -0600
+++++ comm-esr31/mozilla/js/src/gdb/lib-for-tests/catcher.py	2014-10-24 11:41:35.460880223 -0600
++@@ -16,7 +16,7 @@ try:
++     # testlibdir is set on the GDB command line, via:
++     # --eval-command python testlibdir=...
++     execfile(os.path.join(testlibdir, 'prolog.py'))
++-except Exception as err:
+++except Exception, err:
++     sys.stderr.write('Error running GDB prologue:\n')
++     traceback.print_exc()
++     sys.exit(1)
++diff -up comm-esr31/mozilla/js/src/gdb/lib-for-tests/prolog.py.python3 comm-esr31/mozilla/js/src/gdb/lib-for-tests/prolog.py
++--- comm-esr31/mozilla/js/src/gdb/lib-for-tests/prolog.py.python3	2014-07-17 18:05:25.000000000 -0600
+++++ comm-esr31/mozilla/js/src/gdb/lib-for-tests/prolog.py	2014-10-24 11:41:35.460880223 -0600
++@@ -65,7 +65,7 @@ try:
++     # testscript is set on the GDB command line, via:
++     # --eval-command python testscript=...
++     execfile(testscript)
++-except AssertionError as err:
+++except AssertionError, err:
++     sys.stderr.write('\nAssertion traceback:\n')
++     (t, v, tb) = sys.exc_info()
++     traceback.print_tb(tb)
++diff -up comm-esr31/mozilla/js/src/gdb/mozilla/JSObject.py.python3 comm-esr31/mozilla/js/src/gdb/mozilla/JSObject.py
++--- comm-esr31/mozilla/js/src/gdb/mozilla/JSObject.py.python3	2014-07-17 18:05:25.000000000 -0600
+++++ comm-esr31/mozilla/js/src/gdb/mozilla/JSObject.py	2014-10-24 11:41:35.460880223 -0600
++@@ -46,10 +46,13 @@ class JSObjectPtrOrRef(prettyprinters.Po
++                 function = function.address
++             function = function.cast(self.otc.func_ptr_type)
++             atom = deref(function['atom_'])
++-            name = str(atom) if atom else '<unnamed>'
+++            name = None
+++            if atom:
+++              name = str(atom)
+++            else:
+++              name = '<unnamed>'
++         return '[object %s%s]%s' % (class_name,
++-                                    ' ' + name if name else '',
++-                                    ' delegate' if is_delegate else '')
+++                                    ('', ' ' + name)[name], ('', ' delegate')[is_delegate])
++ 
++ @ref_pretty_printer('JSObject')
++ def JSObjectRef(value, cache): return JSObjectPtrOrRef(value, cache)
++diff -up comm-esr31/mozilla/js/src/gdb/mozilla/jsval.py.python3 comm-esr31/mozilla/js/src/gdb/mozilla/jsval.py
++--- comm-esr31/mozilla/js/src/gdb/mozilla/jsval.py.python3	2014-07-17 18:05:25.000000000 -0600
+++++ comm-esr31/mozilla/js/src/gdb/mozilla/jsval.py	2014-10-24 11:41:35.460880223 -0600
++@@ -171,7 +171,11 @@ class jsvalTypeCache(object):
++         for (k,v) in d.items(): self.magic_names[v] = k
++ 
++         # Choose an unboxing scheme for this architecture.
++-        self.boxer = Punbox if cache.void_ptr_t.sizeof == 8 else Nunbox
+++        self.boxer = None
+++        if cache.void_ptr_t.sizeof == 8:
+++          self.boxer = Punbox
+++        else:
+++          self.boxer = Nunbox
++ 
++ @pretty_printer('jsval_layout')
++ class jsval_layout(object):
++@@ -194,7 +198,7 @@ class jsval_layout(object):
++         elif tag == self.jtc.UNDEFINED:
++             return 'JSVAL_VOID'
++         elif tag == self.jtc.BOOLEAN:
++-            return 'JSVAL_TRUE' if self.box.as_uint32() else 'JSVAL_FALSE'
+++            return ('JSVAL_FALSE', 'JSVAL_TRUE')[self.box.as_uint32()]
++         elif tag == self.jtc.MAGIC:
++             value = self.box.as_uint32()
++             if 0 <= value and value < len(self.jtc.magic_names):
++diff -up comm-esr31/mozilla/js/src/gdb/mozilla/prettyprinters.py.python3 comm-esr31/mozilla/js/src/gdb/mozilla/prettyprinters.py
++--- comm-esr31/mozilla/js/src/gdb/mozilla/prettyprinters.py.python3	2014-07-17 18:05:25.000000000 -0600
+++++ comm-esr31/mozilla/js/src/gdb/mozilla/prettyprinters.py	2014-10-24 11:41:35.460880223 -0600
++@@ -335,7 +335,7 @@ class Pointer(object):
++             assert not "mozilla.prettyprinters.Pointer applied to bad value type"
++         try:
++             summary = self.summary()
++-        except gdb.MemoryError as r:
+++        except gdb.MemoryError, r:
++             summary = str(r)
++         v = '(%s) %s %s' % (self.value.type, address, summary)
++         return v
++diff -up comm-esr31/mozilla/js/src/gdb/run-tests.py.python3 comm-esr31/mozilla/js/src/gdb/run-tests.py
++--- comm-esr31/mozilla/js/src/gdb/run-tests.py.python3	2014-07-17 18:05:25.000000000 -0600
+++++ comm-esr31/mozilla/js/src/gdb/run-tests.py	2014-10-24 11:41:35.461880219 -0600
++@@ -110,20 +110,24 @@ class Summary(object):
++ 
++             if OPTIONS.worklist:
++                 try:
++-                    with open(OPTIONS.worklist) as out:
+++                    out = open(OPTIONS.worklist)
+++                    if 1:
++                         for test in self.failures:
++                             out.write(test.name + '\n')
++-                except IOError as err:
+++                    out.__exit__(0, 0, 0)
+++                except IOError, err:
++                     sys.stderr.write("Error writing worklist file '%s': %s"
++                                      % (OPTIONS.worklist, err))
++                     sys.exit(1)
++ 
++             if OPTIONS.write_failures:
++                 try:
++-                    with open(OPTIONS.write_failures) as out:
+++                    out = open(OPTIONS.write_failures).__enter__()
+++                    if 1:
++                         for test in self.failures:
++                             test.show(out)
++-                except IOError as err:
+++                    out.close()
+++                except IOError, err:
++                     sys.stderr.write("Error writing worklist file '%s': %s"
++                                      % (OPTIONS.write_failures, err))
++                     sys.exit(1)
++@@ -288,9 +292,11 @@ def main(argv):
++             test_set.update(find_tests(OPTIONS.testdir, arg))
++     if OPTIONS.worklist:
++         try:
++-            with open(OPTIONS.worklist) as f:
+++            f = open(OPTIONS.worklist)
+++            if 1:
++                 for line in f:
++                     test_set.update(os.path.join(test_dir, line.strip('\n')))
+++            f.__exit__(0, 0, 0)
++         except IOError:
++             # With worklist, a missing file means to start the process with
++             # the complete list of tests.
++@@ -299,10 +305,12 @@ def main(argv):
++             test_set = set(find_tests(OPTIONS.testdir))
++     if OPTIONS.read_tests:
++         try:
++-            with open(OPTIONS.read_tests) as f:
+++            f = open(OPTIONS.read_tests).__enter__()
+++            if 1:
++                 for line in f:
++                     test_set.update(os.path.join(test_dir, line.strip('\n')))
++-        except IOError as err:
+++            f.close()
+++        except IOError, err:
++             sys.stderr.write("Error trying to read test file '%s': %s\n"
++                              % (OPTIONS.read_tests, err))
++             sys.exit(1)
++@@ -329,7 +337,7 @@ def main(argv):
++     # directory tree.
++     try:
++         build_test_exec(OPTIONS.builddir)
++-    except subprocess.CalledProcessError as err:
+++    except subprocess.CalledProcessError, err:
++         sys.stderr.write("Error building test executable: %s\n" % (err,))
++         sys.exit(1)
++ 
++@@ -338,7 +346,7 @@ def main(argv):
++         summary.start()
++         run_tests(test_list, summary)
++         summary.finish()
++-    except OSError as err:
+++    except OSError, err:
++         sys.stderr.write("Error running tests: %s\n" % (err,))
++         sys.exit(1)
++ 
++diff -up comm-esr31/mozilla/js/src/gdb/taskpool.py.python3 comm-esr31/mozilla/js/src/gdb/taskpool.py
++--- comm-esr31/mozilla/js/src/gdb/taskpool.py.python3	2014-07-17 18:05:25.000000000 -0600
+++++ comm-esr31/mozilla/js/src/gdb/taskpool.py	2014-10-24 11:41:35.461880219 -0600
++@@ -75,7 +75,8 @@ class TaskPool(object):
++     def run_all(self):
++         # The currently running tasks: a set of Task instances.
++         running = set()
++-        with open(os.devnull, 'r') as devnull:
+++        devnull = open(os.devnull, 'r')
+++        if 1:
++             while True:
++                 while len(running) < self.job_limit and self.next_pending:
++                     t = self.next_pending
++@@ -158,6 +159,7 @@ class TaskPool(object):
++                 # Remove the finished tasks from the running set. (Do this here
++                 # to avoid mutating the set while iterating over it.)
++                 running -= finished
+++        devnull.close()
++         return None
++ 
++ def get_cpu_count():
++diff -up comm-esr31/mozilla/js/src/jit-test/jit_test.py.python3 comm-esr31/mozilla/js/src/jit-test/jit_test.py
++--- comm-esr31/mozilla/js/src/jit-test/jit_test.py.python3	2014-07-17 18:05:25.000000000 -0600
+++++ comm-esr31/mozilla/js/src/jit-test/jit_test.py	2014-10-24 11:41:35.461880219 -0600
++@@ -109,8 +109,7 @@ def main(argv):
++     test_args = args[1:]
++ 
++     if jittests.stdio_might_be_broken():
++-        # Prefer erring on the side of caution and not using stdio if
++-        # it might be broken on this platform.  The file-redirect
+++        # Prefer erring on the side of caution and not using stdio if # it might be broken on this platform.  The file-redirect
++         # fallback should work on any platform, so at worst by
++         # guessing wrong we might have slowed down the tests a bit.
++         #
++diff -up comm-esr31/mozilla/js/src/tests/jstests.py.python3 comm-esr31/mozilla/js/src/tests/jstests.py
++--- comm-esr31/mozilla/js/src/tests/jstests.py.python3	2014-07-17 18:05:28.000000000 -0600
+++++ comm-esr31/mozilla/js/src/tests/jstests.py	2014-10-24 11:41:35.461880219 -0600
++@@ -151,7 +151,11 @@ def parse_args():
++         op.error("--valgrind and --debug are mutually exclusive.")
++ 
++     # Fill the debugger field, as needed.
++-    prefix = options.debugger.split() if options.debug else []
+++    prefix = None
+++    if options.debug:
+++      prefix = options.debugger.split()
+++    else:
+++      prefix = []
++     if options.valgrind:
++         prefix = ['valgrind'] + options.valgrind_args.split()
++         if os.uname()[0] == 'Darwin':
++diff -up comm-esr31/mozilla/js/src/tests/lib/manifest.py.python3 comm-esr31/mozilla/js/src/tests/lib/manifest.py
++--- comm-esr31/mozilla/js/src/tests/lib/manifest.py.python3	2014-07-17 18:05:28.000000000 -0600
+++++ comm-esr31/mozilla/js/src/tests/lib/manifest.py	2014-10-24 11:41:35.462880214 -0600
++@@ -286,7 +286,8 @@ def _parse_external_manifest(filename, r
++     """
++     entries = []
++ 
++-    with open(filename, 'r') as fp:
+++    fp = open(filename, 'r')
+++    if 1:
++         manifest_re = re.compile(r'^\s*(.*)\s+(include|script)\s+(\S+)$')
++         for line in fp:
++             line, _, comment = line.partition('#')
++@@ -309,6 +310,7 @@ def _parse_external_manifest(filename, r
++ 
++             entries.append({'path': path, 'terms': matches.group(1), 'comment': comment.strip()})
++ 
+++    fp.close()
++     # if one directory name is a prefix of another, we want the shorter one first
++     entries.sort(key=lambda x: x["path"])
++     return entries
++diff -up comm-esr31/mozilla/js/src/tests/lib/progressbar.py.python3 comm-esr31/mozilla/js/src/tests/lib/progressbar.py
++--- comm-esr31/mozilla/js/src/tests/lib/progressbar.py.python3	2014-07-17 18:05:28.000000000 -0600
+++++ comm-esr31/mozilla/js/src/tests/lib/progressbar.py	2014-10-24 11:41:35.462880214 -0600
++@@ -79,7 +79,11 @@ class ProgressBar(object):
++         self.update(*self.prior)
++ 
++     def finish(self, complete=True):
++-        final_count = self.limit if complete else self.prior[0]
+++        final_count = None
+++        if complete:
+++          final_count = self.limit
+++        else:
+++          final_count = self.prior[0]
++         self.update(final_count, self.prior[1])
++         sys.stdout.write('\n')
++ 
++@@ -96,8 +100,7 @@ class ProgressBar(object):
++     @staticmethod
++     def conservative_isatty():
++         """
++-        Prefer erring on the side of caution and not using terminal commands if
++-        the current output stream may be a file.  We explicitly check for the
+++        Prefer erring on the side of caution and not using terminal commands if the current output stream may be a file.  We explicitly check for the
++         Android platform because terminal commands work poorly over ADB's
++         redirection.
++         """
++diff -up comm-esr31/mozilla/js/src/tests/lib/results.py.python3 comm-esr31/mozilla/js/src/tests/lib/results.py
++--- comm-esr31/mozilla/js/src/tests/lib/results.py.python3	2014-07-17 18:05:28.000000000 -0600
+++++ comm-esr31/mozilla/js/src/tests/lib/results.py	2014-10-24 11:41:35.462880214 -0600
++@@ -167,7 +167,10 @@ class ResultsSink:
++ 
++             if dev_label:
++                 def singular(label):
++-                    return "FIXED" if label == "FIXES" else label[:-1]
+++                    if label == "FIXES":
+++                      return "FIXED"
+++                    else:
+++                      return label[:-1]
++                 self.pb.message("%s - %s" % (singular(dev_label), output.test.path))
++ 
++         self.pb.update(self.n, self.counts)
++@@ -216,7 +219,7 @@ class ResultsSink:
++                           print >> failure_file, path
++               failure_file.close()
++ 
++-        suffix = '' if completed else ' (partial run -- interrupted by user)'
+++        suffix = (' (partial run -- interrupted by user)', '')[completed]
++         if self.all_passed():
++             print 'PASS' + suffix
++         else:
++diff -up comm-esr31/mozilla/js/xpconnect/src/event_impl_gen.py.python3 comm-esr31/mozilla/js/xpconnect/src/event_impl_gen.py
++--- comm-esr31/mozilla/js/xpconnect/src/event_impl_gen.py.python3	2014-07-17 18:05:30.000000000 -0600
+++++ comm-esr31/mozilla/js/xpconnect/src/event_impl_gen.py	2014-10-24 11:41:35.462880214 -0600
++@@ -499,13 +499,13 @@ def toWebIDLType(attribute, inType=False
++     if attribute.type == "nsIVariant":
++         return "any";
++     if attribute.type == "nsISupports":
++-        return "%s%s" % (attribute.type, "" if onlyInterface else "?")
+++        return "%s%s" % (attribute.type, ("?", "")[onlyInterface])
++     if attribute.type.count("nsIDOM"):
++-        return "%s%s" % (attribute.type[6:], "" if onlyInterface else "?")
+++        return "%s%s" % (attribute.type[6:], ("?", "")[onlyInterface])
++     if attribute.type.count("nsI"):
++-        return "%s%s" % (attribute.type[3:], "" if onlyInterface else "?")
+++        return "%s%s" % (attribute.type[3:], ("?", "")[onlyInterface])
++     if attribute.realtype.nativeType('in').endswith('*') or attribute.realtype.nativeType('in').count("nsAString"):
++-        return "%s%s" % (attribute.type, "" if onlyInterface else "?")
+++        return "%s%s" % (attribute.type, ("?", "")[onlyInterface])
++     return attribute.type
++ 
++ def write_webidl(eventname, iface, fd, conf, idl):
++diff -up comm-esr31/mozilla/js/xpconnect/src/qsgen.py.python3 comm-esr31/mozilla/js/xpconnect/src/qsgen.py
++--- comm-esr31/mozilla/js/xpconnect/src/qsgen.py.python3	2014-07-17 18:05:30.000000000 -0600
+++++ comm-esr31/mozilla/js/xpconnect/src/qsgen.py	2014-10-24 11:41:35.463880210 -0600
++@@ -22,8 +22,8 @@
++ # case, everything that involves interpreting xptcall data (for example, the
++ # big methodInfo loops in XPCWrappedNative::CallMethod and the switch statement
++ # in XPCConert::JSData2Native) might as well happen at build time, since all
++-# the type information for any given member is already known.  That's what this
++-# script does.  It gets the information from IDL instead of XPT files.  Apart
+++# the type i % ion for any given member is already known.  That's what this
+++# script does.  It gets the i % ion from IDL instead of XPT files.  Apart
++ # from that, the code in this script is very similar to what you'll find in
++ # XPConnect itself.  The advantage is that it runs once, at build time, not in
++ # tight loops at run time.
++@@ -233,7 +233,7 @@ def readConfigFile(filename, includePath
++     # Read the config file.
++     conf = Configuration(filename, includePath)
++ 
++-    # Now read IDL files to connect the information in the config file to
+++    # Now read IDL files to connect the i % ion in the config file to
++     # actual XPCOM interfaces, methods, and attributes.
++     interfaces = []
++     interfacesByName = {}
++@@ -512,12 +512,12 @@ def writeArgumentUnboxing(f, i, name, ty
++             # passed in at all. In that case, point the MutableHandleValue at a
++             # dummy variable, and pass in a boolean saying that the argument
++             # wasn't passed (previously, this used a NULL ptr sentinel value.)
++-            f.write("    JS::RootedValue {name}_dummy(cx);\n".format(name=name))
++-            f.write("    JS::MutableHandleValue {name}_mhv({i} < argc ? args[{i}] : &{name}_dummy);\n".format(name=name, i=i))
++-            f.write("    (void) {name}_mhv;\n".format(name=name, i=i))
+++            f.write("    JS::RootedValue %s_dummy(cx);\n" % name)
+++            f.write("    JS::MutableHandleValue %s_mhv(%d < argc ? args[%d] : &%s_dummy);\n" % (name, i, i, name))
+++            f.write("    (void) %s_mhv;\n" % (name))
++ 
++-            argPtr = "{name}_mhv".format(name=name)
++-            notPassed = "argc < {i}".format(i=i)
+++            argPtr = "%s_mhv" % name
+++            notPassed = "argc < %d" % i
++     else:
++         argVal = "args[%d]" % i
++         argPtr = "args[%d]" % i
++diff -up comm-esr31/mozilla/layout/tools/reftest/b2g_desktop.py.python3 comm-esr31/mozilla/layout/tools/reftest/b2g_desktop.py
++--- comm-esr31/mozilla/layout/tools/reftest/b2g_desktop.py.python3	2014-07-17 18:05:38.000000000 -0600
+++++ comm-esr31/mozilla/layout/tools/reftest/b2g_desktop.py	2014-10-24 11:41:35.463880210 -0600
++@@ -1,7 +1,11 @@
++ # This Source Code Form is subject to the terms of the Mozilla Public
++ # License, v. 2.0. If a copy of the MPL was not distributed with this file,
++ # You can obtain one at http://mozilla.org/MPL/2.0/.
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ import json
++ import os
++diff -up comm-esr31/mozilla/layout/tools/reftest/mach_commands.py.python3 comm-esr31/mozilla/layout/tools/reftest/mach_commands.py
++--- comm-esr31/mozilla/layout/tools/reftest/mach_commands.py.python3	2014-07-17 18:05:38.000000000 -0600
+++++ comm-esr31/mozilla/layout/tools/reftest/mach_commands.py	2014-10-24 11:41:35.463880210 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import mozpack.path
++ import os
++@@ -142,15 +142,19 @@ class ReftestRunner(MozbuildObject):
++ 
++         # The imp module can spew warnings if the modules below have
++         # already been imported, ignore them.
++-        with warnings.catch_warnings():
+++        warnings.catch_warnings().__enter__()
+++        if 1:
++             warnings.simplefilter('ignore')
++ 
++             import imp
++             path = os.path.join(self.reftest_dir, 'runreftestb2g.py')
++-            with open(path, 'r') as fh:
+++            fh = open(path, 'r')
+++            if 1:
++                 imp.load_module('reftest', fh, path, ('.py', 'r', imp.PY_SOURCE))
+++            fh.close()
++             import reftest
++ 
+++        warnings.catch_warnings().__exit__(0, 0, 0)
++         # Set up the reftest options.
++         parser = reftest.B2GOptions()
++         options, args = parser.parse_args([])
++diff -up comm-esr31/mozilla/layout/tools/reftest/runreftestb2g.py.python3 comm-esr31/mozilla/layout/tools/reftest/runreftestb2g.py
++--- comm-esr31/mozilla/layout/tools/reftest/runreftestb2g.py.python3	2014-07-17 18:05:38.000000000 -0600
+++++ comm-esr31/mozilla/layout/tools/reftest/runreftestb2g.py	2014-10-24 11:41:35.463880210 -0600
++@@ -400,9 +400,11 @@ class B2GRemoteReftest(RefTest):
++                 config.set(section, 'Path', profilePath)
++ 
++         newProfilesIni = tempfile.mktemp()
++-        with open(newProfilesIni, 'wb') as configfile:
+++        configfile = open(newProfilesIni, 'wb')
+++        if 1:
++             config.write(configfile)
++ 
+++        configfile.close()
++         self._devicemanager.pushFile(newProfilesIni, self.remoteProfilesIniPath)
++         try:
++             os.remove(newProfilesIni)
++diff -up comm-esr31/mozilla/layout/tools/reftest/runreftest.py.python3 comm-esr31/mozilla/layout/tools/reftest/runreftest.py
++--- comm-esr31/mozilla/layout/tools/reftest/runreftest.py.python3	2014-07-17 18:05:38.000000000 -0600
+++++ comm-esr31/mozilla/layout/tools/reftest/runreftest.py	2014-10-24 11:41:35.464880206 -0600
++@@ -57,14 +57,18 @@ class ReftestThread(threading.Thread):
++       self.summaryMatches[text] = None
++ 
++   def run(self):
++-    with printLock:
+++    printLock.__enter__()
+++    if 1:
++       print "Starting thread with", self.cmdlineArgs
++       sys.stdout.flush()
+++    printLock.__exit__(0, 0, 0)
++     process = subprocess.Popen(self.cmdlineArgs, stdout=subprocess.PIPE)
++     for chunk in self.chunkForMergedOutput(process.stdout):
++-      with printLock:
+++      printLock.__enter__()
+++      if 1:
++         print chunk,
++         sys.stdout.flush()
+++      printLock.__exit__(0, 0, 0)
++     self.retcode = process.wait()
++ 
++   def chunkForMergedOutput(self, logsource):
++@@ -301,9 +305,17 @@ class RefTest(object):
++       for (summaryObj, (text, categories)) in zip(summaryObjects, summaryLines):
++         threadMatches = t.summaryMatches[text]
++         for (attribute, description) in categories:
++-          amount = int(threadMatches.group(attribute) if threadMatches else 0)
+++          amount = None
+++          if threadMatches:
+++            amount = int(threadMatches.group(attribute)
+++          else:
+++            amount = 0)
++           summaryObj[attribute] += amount
++-        amount = int(threadMatches.group('total') if threadMatches else 0)
+++        amount = None
+++        if threadMatches:
+++          amount = int(threadMatches.group('total')
+++        else:
+++          amount = 0)
++         summaryObj['total'] += amount
++ 
++     print 'REFTEST INFO | Result summary:'
++diff -up comm-esr31/mozilla/media/libopus/gen-sources.py.python3 comm-esr31/mozilla/media/libopus/gen-sources.py
++--- comm-esr31/mozilla/media/libopus/gen-sources.py.python3	2014-07-17 18:05:38.000000000 -0600
+++++ comm-esr31/mozilla/media/libopus/gen-sources.py	2014-10-24 11:41:35.464880206 -0600
++@@ -27,14 +27,16 @@ def generate_sources_mozbuild(path):
++     ]
++ 
++     var_definition = re.compile('([A-Z_]*) = (.*)')
++-    with open('sources.mozbuild', 'w') as output:
+++    output = open('sources.mozbuild', 'w')
+++    if 1:
++ 
++         output.write('# THIS FILE WAS AUTOMATICALLY GENERATED BY %s. DO NOT EDIT.\n' % sys.argv[0])
++         for makefile in makefiles:
++             values = []
++             definition_started = False
++ 
++-            with open('%s/%s' % (path, makefile), 'r') as mk:
+++            mk = open('%s/%s' % (path, makefile), 'r')
+++            if 1:
++                 for line in mk:
++                     line = line.rstrip()
++                     result = var_definition.match(line)
++@@ -60,8 +62,10 @@ def generate_sources_mozbuild(path):
++                         add_value(values, result.group(2))
++                     else:
++                         add_value(values, line)
+++            mk.close()
++             write_values(output, values)
++ 
+++    output.close()
++ if __name__ == '__main__':
++     if len(sys.argv) != 2:
++         print "Usage: %s /path/to/opus" % (sys.argv[0])
++diff -up comm-esr31/mozilla/media/libvpx/update.py.python3 comm-esr31/mozilla/media/libvpx/update.py
++--- comm-esr31/mozilla/media/libvpx/update.py.python3	2014-07-17 18:05:38.000000000 -0600
+++++ comm-esr31/mozilla/media/libvpx/update.py	2014-10-24 11:41:35.464880206 -0600
++@@ -330,7 +330,8 @@ def get_sources(prefix):
++     disabled = {}
++ 
++     for mk in mk_files:
++-        with open(os.path.join(prefix, mk)) as f:
+++        f = open(os.path.join(prefix, mk))
+++        if 1:
++             base = os.path.dirname(mk)
++             for l in f:
++                 if '+=' in l:
++@@ -343,6 +344,7 @@ def get_sources(prefix):
++                             source[key] = []
++                         source[key].append(value)
++ 
+++        f.__exit__(0, 0, 0)
++     for key in source:
++         for f in source[key]:
++             if key.endswith('EXPORTS') and f.endswith('.h'):
++@@ -376,9 +378,11 @@ def update_sources_mozbuild(files, sourc
++     sources_mozbuild_new = "files = {\n %s\n}\n" % f.getvalue().strip()[1:-1]
++     if sources_mozbuild != sources_mozbuild_new:
++         print 'updating sources.mozbuild'
++-        with open('sources.mozbuild', 'w') as f:
+++        f = open('sources.mozbuild', 'w')
+++        if 1:
++             f.write(sources_mozbuild_new)
++ 
+++        f.close()
++ def get_current_files():
++     current_files = []
++     for root, folders, files in os.walk('.'):
++@@ -396,8 +400,10 @@ def is_new(a, b):
++         or open(a).read() != open(b).read()
++ 
++ def get_sources_mozbuild():
++-    with open('sources.mozbuild') as f:
+++    f = open('sources.mozbuild')
+++    if 1:
++         sources_mozbuild = f.read()
+++    f.__exit__(0, 0, 0)
++     exec(sources_mozbuild)
++     return sources_mozbuild, files
++ 
++@@ -455,9 +461,11 @@ def apply_patches():
++     os.system("patch -p3 < mingw.patch")
++ 
++ def update_readme(commit):
++-    with open('README_MOZILLA') as f:
+++    f = open('README_MOZILLA').__enter__()
+++    if 1:
++         readme = f.read()
++ 
+++    f.close()
++     if 'The git commit ID used was' in readme:
++         new_readme = re.sub('The git commit ID used was [a-f0-9]+',
++             'The git commit ID used was %s' % commit, readme)
++@@ -465,9 +473,11 @@ def update_readme(commit):
++         new_readme = "%s\n\nThe git commit ID used was %s\n" % (readme, commit)
++ 
++     if readme != new_readme:
++-        with open('README_MOZILLA', 'w') as f:
+++        f = open('README_MOZILLA', 'w').__enter__()
+++        if 1:
++             f.write(new_readme)
++ 
+++        f.close()
++ def print_info(source, files, disabled, unknown, moz_build_files):
++     for key in moz_build_files:
++         if key not in files:
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/android/adb_logcat_monitor.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/android/adb_logcat_monitor.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/android/adb_logcat_monitor.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/android/adb_logcat_monitor.py	2014-10-24 11:41:35.464880206 -0600
++@@ -121,8 +121,10 @@ def main(base_dir, adb_cmd='adb'):
++   pid_file_path = os.path.join(base_dir, 'LOGCAT_MONITOR_PID')
++ 
++   try:
++-    with open(pid_file_path, 'w') as f:
+++    f = open(pid_file_path, 'w')
+++    if 1:
++       f.write(str(os.getpid()))
+++    f.close()
++     while True:
++       for device_id in GetAttachedDevices(adb_cmd):
++         if not device_id in devices:
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/android/adb_logcat_printer.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/android/adb_logcat_printer.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/android/adb_logcat_printer.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/android/adb_logcat_printer.py	2014-10-24 11:41:35.465880201 -0600
++@@ -110,8 +110,10 @@ def GetDeviceLogs(log_filenames, logger)
++     logger.debug('%s: %s', device, str(device_files))
++     device_file_lines = []
++     for cur_file in device_files:
++-      with open(cur_file) as f:
+++      f = open(cur_file)
+++      if 1:
++         device_file_lines += [(cur_file, f.read().splitlines())]
+++      f.close()
++     combined_lines = CombineLogFiles(device_file_lines, logger)
++     # Prepend each line with a short unique ID so it's easy to see
++     # when the device changes.  We don't use the start of the device
++@@ -126,9 +128,11 @@ def ShutdownLogcatMonitor(base_dir, logg
++   """Attempts to shutdown adb_logcat_monitor and blocks while waiting."""
++   try:
++     monitor_pid_path = os.path.join(base_dir, 'LOGCAT_MONITOR_PID')
++-    with open(monitor_pid_path) as f:
+++    f = open(monitor_pid_path)
+++    if 1:
++       monitor_pid = int(f.readline())
++ 
+++    f.__exit__(0, 0, 0)
++     logger.info('Sending SIGTERM to %d', monitor_pid)
++     os.kill(monitor_pid, signal.SIGTERM)
++     i = 0
++@@ -184,9 +188,11 @@ def main(base_dir, output_file):
++     for log in GetDeviceLogs(FindLogFiles(base_dir), logger):
++       output_file.write(log)
++       output_file.write(separator)
++-    with open(os.path.join(base_dir, 'eventlog')) as f:
+++    f = open(os.path.join(base_dir, 'eventlog')).__enter__()
+++    if 1:
++       output_file.write('\nLogcat Monitor Event Log\n')
++       output_file.write(f.read())
+++    f.close()
++   except:
++     logger.exception('Unexpected exception')
++ 
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/android/device_status_check.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/android/device_status_check.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/android/device_status_check.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/android/device_status_check.py	2014-10-24 11:41:35.465880201 -0600
++@@ -70,8 +70,10 @@ def CheckForMissingDevices(options, adb_
++     devices_path = os.path.join(out_dir, file_name)
++     devices = []
++     try:
++-      with open(devices_path) as f:
+++      f = open(devices_path)
+++      if 1:
++         devices = f.read().splitlines()
+++      f.close()
++     except IOError:
++       # Ignore error, file might not exist
++       pass
++@@ -81,10 +83,12 @@ def CheckForMissingDevices(options, adb_
++     path = os.path.join(out_dir, file_name)
++     if not os.path.exists(out_dir):
++       os.makedirs(out_dir)
++-    with open(path, 'w') as f:
+++    f = open(path, 'w')
+++    if 1:
++       # Write devices currently visible plus devices previously seen.
++       f.write('\n'.join(set(device_list)))
++ 
+++    f.close()
++   last_devices_path = os.path.join(out_dir, '.last_devices')
++   last_devices = ReadDeviceList('.last_devices')
++ 
++@@ -128,7 +132,7 @@ def CheckForMissingDevices(options, adb_
++         server = smtplib.SMTP('localhost')
++         server.sendmail(from_address, [to_address], msg_body)
++         server.quit()
++-      except Exception as e:
+++      except Exception, e:
++         print 'Failed to send alert email. Error: %s' % e
++   else:
++     new_devs = set(adb_online_devs) - set(last_devices)
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/android/emulator.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/android/emulator.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/android/emulator.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/android/emulator.py	2014-10-24 11:41:35.465880201 -0600
++@@ -275,7 +275,7 @@ class Emulator(object):
++         number_of_waits -= 1
++         if not number_of_waits:
++           break
++-      except errors.WaitForResponseTimedOutError as e:
+++      except errors.WaitForResponseTimedOutError, e:
++         seconds_waited += self._WAITFORDEVICE_TIMEOUT
++         adb_cmd = "adb -s %s %s" % (self.device, 'kill-server')
++         run_command.RunCommand(adb_cmd)
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/android/lighttpd_server.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/android/lighttpd_server.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/android/lighttpd_server.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/android/lighttpd_server.py	2014-10-24 11:41:35.465880201 -0600
++@@ -77,15 +77,19 @@ class LighttpdServer(object):
++     while True:
++       if self.base_config_path:
++         # Read the config
++-        with codecs.open(self.base_config_path, 'r', 'utf-8') as f:
+++        f = codecs.open(self.base_config_path, 'r', 'utf-8').__enter__()
+++        if 1:
++           config_contents = f.read()
+++        f.__exit__(0, 0, 0)
++       else:
++         config_contents = self._GetDefaultBaseConfig()
++       if self.extra_config_contents:
++         config_contents += self.extra_config_contents
++       # Write out the config, filling in placeholders from the members of |self|
++-      with codecs.open(self.config_path, 'w', 'utf-8') as f:
+++      f = codecs.open(self.config_path, 'w', 'utf-8').__enter__()
+++      if 1:
++         f.write(config_contents % self.__dict__)
+++      f.__exit__(0, 0, 0)
++       if (not os.path.exists(self.lighttpd_path) or
++           not os.access(self.lighttpd_path, os.X_OK)):
++         raise EnvironmentError(
++@@ -133,7 +137,7 @@ class LighttpdServer(object):
++           client_error = ('Bad response: %s %s version %s\n  ' %
++                           (r.status, r.reason, r.version) +
++                           '\n  '.join([': '.join(h) for h in r.getheaders()]))
++-      except (httplib.HTTPException, socket.error) as client_error:
+++      except (httplib.HTTPException, socket.error), client_error:
++         pass  # Probably too quick connecting: try again
++       # Check for server startup error messages
++       ix = self.process.expect([pexpect.TIMEOUT, pexpect.EOF, '.+'],
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/android_commands.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/android_commands.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/android_commands.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/android_commands.py	2014-10-24 11:41:35.466880197 -0600
++@@ -251,7 +251,7 @@ class AndroidCommands(object):
++       try:
++         self._adb.WaitForDevicePm()
++         return  # Success
++-      except errors.WaitForResponseTimedOutError as e:
+++      except errors.WaitForResponseTimedOutError, e:
++         last_err = e
++         logging.warning('Restarting and retrying after timeout: %s', e)
++         retries -= 1
++@@ -624,11 +624,13 @@ class AndroidCommands(object):
++ 
++   def SetFileContents(self, filename, contents):
++     """Writes |contents| to the file specified by |filename|."""
++-    with tempfile.NamedTemporaryFile() as f:
+++    f = tempfile.NamedTemporaryFile().__enter__()
+++    if 1:
++       f.write(contents)
++       f.flush()
++       self._adb.Push(f.name, filename)
++ 
+++    f.__exit__(0, 0, 0)
++   def RemovePushedFiles(self):
++     """Removes all files pushed with PushIfNeeded() from the device."""
++     for p in self._pushed_files:
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/device_stats_monitor.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/device_stats_monitor.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/device_stats_monitor.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/device_stats_monitor.py	2014-10-24 11:41:35.466880197 -0600
++@@ -92,8 +92,10 @@ class DeviceStatsMonitor(object):
++       'irq': 'jiffies',
++       'softirq': 'jiffies',
++     }
++-    with open(output_path, 'w') as f:
+++    f = open(output_path, 'w')
+++    if 1:
++       f.write('display(%d, %s, %s);' % (self._hz, json.dumps(results), units))
+++    f.close()
++     return 'file://%s?results=file://%s' % (
++         DeviceStatsMonitor.RESULT_VIEWER_PATH, urllib.quote(output_path))
++ 
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/forwarder.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/forwarder.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/forwarder.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/forwarder.py	2014-10-24 11:41:35.466880197 -0600
++@@ -117,8 +117,7 @@ class Forwarder(object):
++                                        forward_string)
++ 
++     # Read the output of the command to determine which device ports where
++-    # forwarded to which host ports (necessary if
++-    host_success_re = re.compile('Forwarding device port (\d+) to host (\d+):')
+++    # forwarded to which host ports (necessary if host_success_re = re.compile('Forwarding device port (\d+) to host (\d+):')
++     host_failure_re = re.compile('Couldn\'t start forwarder server for port '
++                                  'spec: (\d+):(\d+)')
++     for pair in port_pairs:
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/json_perf_parser.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/json_perf_parser.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/json_perf_parser.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/json_perf_parser.py	2014-10-24 11:41:35.466880197 -0600
++@@ -153,8 +153,10 @@ def GetAverageRunInfoFromFile(json_file,
++   Returns:
++     See GetAverageRunInfo Returns section.
++   """
++-  with open(json_file, 'r') as f:
+++  f = open(json_file, 'r')
+++  if 1:
++     data = f.read()
++     perf = json.loads(data)
++ 
+++  f.close()
++   return GetAverageRunInfo(perf, name)
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/perf_tests_helper.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/perf_tests_helper.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/perf_tests_helper.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/perf_tests_helper.py	2014-10-24 11:41:35.466880197 -0600
++@@ -67,7 +67,7 @@ def PrintPerfResult(measurement, trace,
++     trace_name,
++     # Do not show equal sign if the trace is empty. Usually it happens when
++     # measurement is enough clear to describe the result.
++-    '= ' if trace_name else '',
+++    ('', '= ')[trace_name],
++     value,
++     units)
++   if avg:
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/ports.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/ports.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/ports.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/ports.py	2014-10-24 11:41:35.467880193 -0600
++@@ -28,12 +28,14 @@ def ResetTestServerPortAllocation():
++     Returns True if reset successes. Otherwise returns False.
++   """
++   try:
++-    with open(constants.TEST_SERVER_PORT_FILE, 'w') as fp:
+++    fp = open(constants.TEST_SERVER_PORT_FILE, 'w')
+++    if 1:
++       fp.write('%d' % constants.TEST_SERVER_PORT_FIRST)
+++    fp.__exit__(0, 0, 0)
++     if os.path.exists(constants.TEST_SERVER_PORT_LOCKFILE):
++       os.unlink(constants.TEST_SERVER_PORT_LOCKFILE)
++     return True
++-  except Exception as e:
+++  except Exception, e:
++     logging.error(e)
++   return False
++ 
++@@ -52,7 +54,8 @@ def AllocateTestServerPort():
++     fcntl.flock(fp_lock, fcntl.LOCK_EX)
++     # Get current valid port and calculate next valid port.
++     assert os.path.exists(constants.TEST_SERVER_PORT_FILE)
++-    with open(constants.TEST_SERVER_PORT_FILE, 'r+') as fp:
+++    fp = open(constants.TEST_SERVER_PORT_FILE, 'r+').__enter__()
+++    if 1:
++       port = int(fp.read())
++       ports_tried.append(port)
++       while IsHostPortUsed(port):
++@@ -62,9 +65,10 @@ def AllocateTestServerPort():
++           port < constants.TEST_SERVER_PORT_FIRST):
++         port = 0
++       else:
++-        fp.seek(0, os.SEEK_SET)
+++        fp.seek(0, 0)
++         fp.write('%d' % (port + 1))
++-  except Exception as e:
+++    fp.close()
+++  except Exception, e:
++     logging.info(e)
++   finally:
++     if fp_lock:
++@@ -114,7 +118,11 @@ def IsDevicePortUsed(adb, device_port, s
++   for single_connect in netstat_results:
++     # Column 3 is the local address which we want to check with.
++     connect_results = single_connect.split()
++-    is_state_match = connect_results[5] == state if state else True
+++    is_state_match = None
+++    if state:
+++      is_state_match = connect_results[5] == state
+++    else:
+++      is_state_match = True
++     if connect_results[3] == base_url and is_state_match:
++       return True
++   return False
++@@ -158,7 +166,7 @@ def IsHttpServerConnectable(host, port,
++         client_error = ('Bad response: %s %s version %s\n  ' %
++                         (r.status, r.reason, r.version) +
++                         '\n  '.join([': '.join(h) for h in r.getheaders()]))
++-    except (httplib.HTTPException, socket.error) as e:
+++    except (httplib.HTTPException, socket.error), e:
++       # Probably too quick connecting: try again.
++       exception_error_msgs = traceback.format_exception_only(type(e), e)
++       if exception_error_msgs:
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/run_java_tests.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/run_java_tests.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/run_java_tests.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/run_java_tests.py	2014-10-24 11:41:35.467880193 -0600
++@@ -382,8 +382,10 @@ class TestRunner(BaseTestRunner):
++ 
++       if self.save_perf_json:
++         json_local_file = '/tmp/chromium-android-perf-json-' + raw_test_name
++-        with open(json_local_file, 'w') as f:
+++        f = open(json_local_file, 'w')
+++        if 1:
++           f.write(json_string)
+++        f.close()
++         logging.info('Saving Perf UI JSON from test ' +
++                      test + ' to ' + json_local_file)
++ 
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/test_info_collection.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/test_info_collection.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/test_info_collection.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/test_info_collection.py	2014-10-24 11:41:35.467880193 -0600
++@@ -78,20 +78,17 @@ class TestInfoCollection(object):
++ 
++     # Filter out tests which match neither the requested annotation, nor the
++     # requested name filter, if any.
++-    available_tests = [t for t in available_tests if
++-                       self._AnnotationIncludesTest(t, annotation)]
+++    available_tests = [t for t in available_tests if self._AnnotationIncludesTest(t, annotation)]
++     if annotation and len(annotation) == 1 and annotation[0] == 'SmallTest':
++       tests_without_annotation = [
++-          t for t in self.all_tests if
++-          not tests_annotations.AnnotatedFunctions.GetTestAnnotations(
+++          t for t in self.all_tests if not tests_annotations.AnnotatedFunctions.GetTestAnnotations(
++               t.qualified_name)]
++       test_names = [t.qualified_name for t in tests_without_annotation]
++       logging.warning('The following tests do not contain any annotation. '
++                       'Assuming "SmallTest":\n%s',
++                       '\n'.join(test_names))
++       available_tests += tests_without_annotation
++-    available_tests = [t for t in available_tests if
++-                       self._NameFilterIncludesTest(t, name_filter)]
+++    available_tests = [t for t in available_tests if self._NameFilterIncludesTest(t, name_filter)]
++ 
++     return available_tests
++ 
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/test_result.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/test_result.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/test_result.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/android/pylib/test_result.py	2014-10-24 11:41:35.467880193 -0600
++@@ -145,10 +145,12 @@ class TestResults(object):
++         os.mkdir(log_file_path)
++       full_file_name = os.path.join(log_file_path, test_group)
++       if not os.path.exists(full_file_name):
++-        with open(full_file_name, 'w') as log_file:
+++        log_file = open(full_file_name, 'w')
+++        if 1:
++           print >> log_file, '\n%s results for %s build %s:' % (
++               test_group, os.environ.get('BUILDBOT_BUILDERNAME'),
++               os.environ.get('BUILDBOT_BUILDNUMBER'))
+++        log_file.close()
++       log_contents = ['  %s result : %d tests ran' % (test_suite,
++                                                       len(self.ok) +
++                                                       len(self.failed) +
++@@ -159,16 +161,20 @@ class TestResults(object):
++       for (result, count) in content_pairs:
++         if count:
++           log_contents.append(', %d tests %s' % (count, result))
++-      with open(full_file_name, 'a') as log_file:
+++      log_file = open(full_file_name, 'a')
+++      if 1:
++         print >> log_file, ''.join(log_contents)
+++      log_file.close()
++       content = {'test_group': test_group,
++                  'ok': [t.name for t in self.ok],
++                  'failed': [t.name for t in self.failed],
++                  'crashed': [t.name for t in self.failed],
++                  'unknown': [t.name for t in self.unknown],}
++-      with open(os.path.join(log_file_path, 'results.json'), 'a') as json_file:
+++      json_file = open(os.path.join(log_file_path, 'results.json'), 'a')
+++      if 1:
++         print >> json_file, json.dumps(content)
++ 
+++      json_file.close()
++     # Summarize in the test output.
++     summary_string = 'Summary:\n'
++     summary_string += 'RAN=%d\n' % (len(self.ok) + len(self.failed) +
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/android/run_tests.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/android/run_tests.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/android/run_tests.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/android/run_tests.py	2014-10-24 11:41:35.468880189 -0600
++@@ -147,7 +147,7 @@ class Xvfb(object):
++     self._pid = 0
++ 
++   def _IsLinux(self):
++-    """Return True if on Linux; else False."""
+++    """Return Trueon Linux; = (False.""", )[]
++     return sys.platform.startswith('linux')
++ 
++   def Start(self):
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/escape_unicode.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/escape_unicode.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/escape_unicode.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/escape_unicode.py	2014-10-24 11:41:35.468880189 -0600
++@@ -42,7 +42,8 @@ def main(argv):
++ 
++ def WriteEscapedFile(in_filename, out_filename):
++   input_data = codecs.open(in_filename, 'r', 'utf8').read()
++-  with codecs.open(out_filename, 'w', 'ascii') as out_file:
+++  out_file = codecs.open(out_filename, 'w', 'ascii').__enter__()
+++  if 1:
++     for i, char in enumerate(input_data):
++       if ord(char) > 127:
++         out_file.write(repr(char.encode('utf8'))[1:-1])
++@@ -52,5 +53,6 @@ def WriteEscapedFile(in_filename, out_fi
++         out_file.write(char.encode('ascii'))
++ 
++ 
+++  out_file.__exit__(0, 0, 0)
++ if __name__ == '__main__':
++   sys.exit(main(sys.argv))
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/mac/change_mach_o_flags.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/mac/change_mach_o_flags.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/mac/change_mach_o_flags.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/mac/change_mach_o_flags.py	2014-10-24 11:41:35.468880189 -0600
++@@ -103,7 +103,7 @@ def CheckedSeek(file, offset):
++   """Seeks the file-like object at |file| to offset |offset| and raises a
++   MachOError if anything funny happens."""
++ 
++-  file.seek(offset, os.SEEK_SET)
+++  file.seek(offset, 0)
++   new_offset = file.tell()
++   if new_offset != offset:
++     raise MachOError, \
++diff -up comm-esr31/mozilla/media/webrtc/trunk/build/mac/tweak_info_plist.py.python3 comm-esr31/mozilla/media/webrtc/trunk/build/mac/tweak_info_plist.py
++--- comm-esr31/mozilla/media/webrtc/trunk/build/mac/tweak_info_plist.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/build/mac/tweak_info_plist.py	2014-10-24 11:41:35.468880189 -0600
++@@ -125,8 +125,7 @@ def _DoSCMKeys(plist, add_keys):
++ 
++ def _DoPDFKeys(plist, add_keys):
++   """Adds PDF support to the document types list. If add_keys is True, it will
++-  add the type information dictionary. If it is False, it will remove it if
++-  present."""
+++  add the type information dictionary. If it is False, it will remove it if present."""
++ 
++   PDF_FILE_EXTENSION = 'pdf'
++ 
++diff -up comm-esr31/mozilla/media/webrtc/trunk/testing/gtest/test/gtest_xml_output_unittest.py.python3 comm-esr31/mozilla/media/webrtc/trunk/testing/gtest/test/gtest_xml_output_unittest.py
++--- comm-esr31/mozilla/media/webrtc/trunk/testing/gtest/test/gtest_xml_output_unittest.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/testing/gtest/test/gtest_xml_output_unittest.py	2014-10-24 11:41:35.468880189 -0600
++@@ -166,8 +166,7 @@ class GTestXMLOutputUnitTest(gtest_xml_t
++   def testTimestampValue(self):
++     """Checks whether the timestamp attribute in the XML output is valid.
++ 
++-    Runs a test program that generates an empty XML output, and checks if
++-    the timestamp attribute in the testsuites tag is valid.
+++    Runs a test program that generates an empty XML output, and checks if the timestamp attribute in the testsuites tag is valid.
++     """
++     actual = self._GetXmlOutput('gtest_no_test_unittest', 0)
++     date_time_str = actual.documentElement.getAttributeNode('timestamp').value
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/common.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/common.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/common.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/common.py	2014-10-24 11:41:35.469880185 -0600
++@@ -2,7 +2,7 @@
++ # Use of this source code is governed by a BSD-style license that can be
++ # found in the LICENSE file.
++ 
++-from __future__ import with_statement
+++
++ 
++ import errno
++ import filecmp
++@@ -392,15 +392,19 @@ def CopyTool(flavor, out_path):
++   # Slurp input file.
++   source_path = os.path.join(
++       os.path.dirname(os.path.abspath(__file__)), '%s_tool.py' % prefix)
++-  with open(source_path) as source_file:
+++  source_file = open(source_path)
+++  if 1:
++     source = source_file.readlines()
++ 
+++  source_file.close()
++   # Add header and write it out.
++   tool_path = os.path.join(out_path, 'gyp-%s-tool' % prefix)
++-  with open(tool_path, 'w') as tool_file:
+++  tool_file = open(tool_path, 'w')
+++  if 1:
++     tool_file.write(
++         ''.join([source[0], '# Generated by gyp. Do not edit.\n'] + source[1:]))
++ 
+++  tool_file.close()
++   # Make file executable.
++   os.chmod(tool_path, 0755)
++ 
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/msvs.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/msvs.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/msvs.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/msvs.py	2014-10-24 11:41:35.469880185 -0600
++@@ -305,7 +305,11 @@ def _BuildCommandLineForRuleRaw(spec, cm
++     #              for arguments like "--arg=path" or "/opt:path".
++     # If the argument starts with a slash or dash, it's probably a command line
++     # switch
++-    arguments = [i if (i[:1] in "/-") else _FixPath(i) for i in cmd[1:]]
+++    arguments = None
+++    if (i[:1] in "/-"):
+++      arguments = [i
+++    else:
+++      arguments = _FixPath(i) for i in cmd[1:]]
++     arguments = [i.replace('$(InputDir)','%INPUTDIR%') for i in arguments]
++     arguments = [MSVSSettings.FixVCMacroSlashes(i) for i in arguments]
++     if quote_cmd:
++@@ -695,8 +699,7 @@ def _EscapeVCProjCommandLineArgListItem(
++     # .vcproj file will be misinterpreted as part of this item. There is nothing
++     # we can do about this. Adding an extra quote would correct the problem in
++     # the VCProj but cause the same problem on the final command-line. Moving
++-    # the item to the end of the list does works, but that's only possible if
++-    # there's only one such item. Let's just warn the user.
+++    # the item to the end of the list does works, but that's only possible if # there's only one such item. Let's just warn the user.
++     print >> sys.stderr, ('Warning: MSVS may misinterpret the odd number of ' +
++                           'quotes in ' + s)
++   return s
++@@ -1484,7 +1487,7 @@ def _AddActions(actions_to_add, spec, re
++   # and does not need to be set up again.
++   have_setup_env = set()
++   for a in actions:
++-    # Attach actions to the gyp file if nothing else is there.
+++    # Attach actions to the gyp filenothing = (is there., )[]
++     inputs = a.get('inputs') or [relative_path_of_gyp_file]
++     attached_to = inputs[0]
++     need_setup_env = attached_to not in have_setup_env
++@@ -2632,8 +2635,7 @@ def _GetMSBuildAttributes(spec, config,
++ 
++ 
++ def _GetMSBuildConfigurationGlobalProperties(spec, configurations, build_file):
++-  # TODO(jeanluc) We could optimize out the following and do it only if
++-  # there are actions.
+++  # TODO(jeanluc) We could optimize out the following and do it only if # there are actions.
++   # TODO(jeanluc) Handle the equivalent of setting 'CYGWIN=nontsec'.
++   new_paths = []
++   cygwin_dirs = spec.get('msvs_cygwin_dirs', ['.'])[0]
++@@ -2802,8 +2804,7 @@ def _FinalizeMSBuildSettings(spec, confi
++   precompiled_header = configuration.get('msvs_precompiled_header')
++ 
++   # Add the information to the appropriate tool
++-  # TODO(jeanluc) We could optimize and generate these settings only if
++-  # the corresponding files are found, e.g. don't generate ResourceCompile
+++  # TODO(jeanluc) We could optimize and generate these settings only if # the corresponding files are found, e.g. don't generate ResourceCompile
++   # if you don't have any resources.
++   _ToolAppend(msbuild_settings, 'ClCompile',
++               'AdditionalIncludeDirectories', include_dirs)
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/ninja.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/ninja.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/ninja.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/ninja.py	2014-10-24 11:41:35.470880180 -0600
++@@ -233,7 +233,7 @@ class NinjaWriter:
++     self.ninja = ninja_syntax.Writer(output_file)
++     self.flavor = flavor
++     self.abs_build_dir = abs_build_dir
++-    self.obj_ext = '.obj' if flavor == 'win' else '.o'
+++    self.obj_ext = ('.o', '.obj')[flavor == 'win']
++     if flavor == 'win':
++       # See docstring of msvs_emulation.GenerateEnvironmentFiles().
++       self.win_env = {}
++@@ -551,8 +551,11 @@ class NinjaWriter:
++       description = self.GenerateDescription('ACTION',
++                                              action.get('message', None),
++                                              name)
++-      is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(action)
++-                   if self.flavor == 'win' else False)
+++      is_cygwin = None
+++      if self.flavor == 'win':
+++        is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(action))
+++      else:
+++        is_cygwin = (False)
++       args = action['action']
++       rule_name, _ = self.WriteNewNinjaRule(name, args, description,
++                                             is_cygwin, env=env)
++@@ -589,8 +592,11 @@ class NinjaWriter:
++           'RULE',
++           rule.get('message', None),
++           ('%s ' + generator_default_variables['RULE_INPUT_PATH']) % name)
++-      is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(rule)
++-                   if self.flavor == 'win' else False)
+++      is_cygwin = None
+++      if self.flavor == 'win':
+++        is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(rule))
+++      else:
+++        is_cygwin = (False)
++       rule_name, args = self.WriteNewNinjaRule(
++           name, args, description, is_cygwin, env=env)
++ 
++@@ -1204,7 +1210,7 @@ class NinjaWriter:
++     if self.flavor == 'win':
++       rspfile = rule_name + '.$unique_name.rsp'
++       # The cygwin case handles this inside the bash sub-shell.
++-      run_in = '' if is_cygwin else ' ' + self.build_to_base
+++      run_in = (' ' + self.build_to_base, '' )[is_cygwin] 
++       if is_cygwin:
++         rspfile_content = self.msvs_settings.BuildCygwinBashCommandLine(
++             args, self.build_to_base)
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/xcode.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/xcode.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/xcode.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/generator/xcode.py	2014-10-24 11:41:35.470880180 -0600
++@@ -1090,8 +1090,7 @@ exit 1
++       else:
++         pbxp.AddOrGetFileInRootGroup(source)
++ 
++-    # Add "mac_bundle_resources" and "mac_framework_private_headers" if
++-    # it's a bundle of any type.
+++    # Add "mac_bundle_resources" and "mac_framework_private_headers" if # it's a bundle of any type.
++     if is_bundle:
++       for resource in tgt_mac_bundle_resources:
++         (resource_root, resource_extension) = posixpath.splitext(resource)
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/input.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/input.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/input.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/input.py	2014-10-24 11:41:35.471880176 -0600
++@@ -12,7 +12,7 @@ from compiler.ast import Stmt
++ import compiler
++ import copy
++ import gyp.common
++-import multiprocessing
+++#import multiprocessing
++ import optparse
++ import os.path
++ import re
++@@ -997,8 +997,7 @@ def ProcessConditionsInDict(the_dict, ph
++   # Each item in a conditions list consists of cond_expr, a string expression
++   # evaluated as the condition, and true_dict, a dict that will be merged into
++   # the_dict if cond_expr evaluates to true.  Optionally, a third item,
++-  # false_dict, may be present.  false_dict is merged into the_dict if
++-  # cond_expr evaluates to false.
+++  # false_dict, may be present.  false_dict is merged into the_dict if # cond_expr evaluates to false.
++   #
++   # Any dict merged into the_dict will be recursively processed for nested
++   # conditionals and other expansions, also according to phase, immediately
++@@ -1202,8 +1201,7 @@ def ProcessVariablesAndConditionsInDict(
++   # Recurse into child dicts, or process child lists which may result in
++   # further recursion into descendant dicts.
++   for key, value in the_dict.iteritems():
++-    # Skip "variables" and string values, which were already processed if
++-    # present.
+++    # Skip "variables" and string values, which were already processed if # present.
++     if key == 'variables' or isinstance(value, str):
++       continue
++     if isinstance(value, dict):
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/msvs_emulation.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/msvs_emulation.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/msvs_emulation.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/msvs_emulation.py	2014-10-24 11:41:35.471880176 -0600
++@@ -170,7 +170,7 @@ class MsvsSettings(object):
++     replacements = {
++         '$(VSInstallDir)': self.vs_version.Path(),
++         '$(VCInstallDir)': os.path.join(self.vs_version.Path(), 'VC') + '\\',
++-        '$(OutDir)\\': base_to_build + '\\' if base_to_build else '',
+++        '$(OutDir)\\': base_to_build + ('', '\\')[base_to_build],
++         '$(IntDir)': '$!INTERMEDIATE_DIR',
++         '$(InputPath)': '${source}',
++         '$(InputName)': '${root}',
++@@ -182,8 +182,7 @@ class MsvsSettings(object):
++     # set. This happens when the SDK is sync'd via src-internal, rather than
++     # by typical end-user installation of the SDK. If it's not set, we don't
++     # want to leave the unexpanded variable in the path, so simply strip it.
++-    replacements['$(DXSDK_DIR)'] = self.dxsdk_dir if self.dxsdk_dir else ''
++-    replacements['$(WDK_DIR)'] = self.wdk_dir if self.wdk_dir else ''
+++    replacements['$(DXSDK_DIR)'] = ('', self.wdk_dir)[self.wdk_dir]
++     return replacements
++ 
++   def ConvertVSMacros(self, s, base_to_build=None, config=None):
++@@ -192,8 +191,10 @@ class MsvsSettings(object):
++     return ExpandMacros(s, env)
++ 
++   def AdjustLibraries(self, libraries):
++-    """Strip -l from library if it's specified with that."""
++-    return [lib[2:] if lib.startswith('-l') else lib for lib in libraries]
+++    """Strip -l from library if it's specified with that.""" if lib.startswith('-l'):
+++   return [lib[2:]
+++ else:
+++   return lib for lib in libraries]
++ 
++   def _GetAndMunge(self, field, path, default, prefix, append, map):
++     """Retrieve a value from |field| at |path| or return |default|. If
++@@ -269,7 +270,7 @@ class MsvsSettings(object):
++     if it's not overridden."""
++     config = self._RealConfig(config)
++     type = self.spec['type']
++-    root = 'VCLibrarianTool' if type == 'static_library' else 'VCLinkerTool'
+++    root = ('VCLinkerTool', 'VCLibrarianTool')[type == 'static_library']
++     # TODO(scottmg): Handle OutputDirectory without OutputFile.
++     output_file = self._Setting((root, 'OutputFile'), config)
++     if output_file:
++@@ -597,7 +598,7 @@ class PrecompiledHeader(object):
++     if not source or not header:
++       return []
++     ext = os.path.splitext(source)[1]
++-    lang = 'c' if ext == '.c' else 'cc'
+++    lang = ('cc', 'c')[ext == '.c']
++     return [(self._PchOutput(), '/Yc' + header, lang, source)]
++ 
++ 
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSUserFile.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSUserFile.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSUserFile.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/MSVSUserFile.py	2014-10-24 11:41:35.471880176 -0600
++@@ -81,8 +81,7 @@ class Writer(object):
++ 
++     Args:
++       command: command line to run.  First element in the list is the
++-        executable.  All elements of the command will be quoted if
++-        necessary.
+++        executable.  All elements of the command will be quoted if necessary.
++       working_directory: other files which may trigger the rule. (optional)
++     """
++     command = _QuoteWin32CommandLineArgs(command)
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/SCons.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/SCons.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/SCons.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/SCons.py	2014-10-24 11:41:35.472880172 -0600
++@@ -34,7 +34,7 @@ class TargetBase(object):
++     """
++     Returns the full name of the product being built:
++ 
++-      * Uses 'product_name' if it's set, else prefix + 'target_name'.
+++      * Uses 'product_name'it's set, = (prefix + 'target_name'., )[]
++       * Prepends 'product_dir' if set.
++       * Appends SCons suffix variables for the target type (or
++         product_extension).
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/win_tool.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/win_tool.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/win_tool.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/win_tool.py	2014-10-24 11:41:35.472880172 -0600
++@@ -96,7 +96,8 @@ class WinTool(object):
++     '   Creating library ui.dll.lib and object ui.dll.exp'
++     This happens when there are exports from the dll or exe.
++     """
++-    with LinkLock():
+++    LinkLock().__enter__()
+++    if 1:
++       env = self._GetEnv(arch)
++       popen = subprocess.Popen(args, shell=True, env=env,
++                                stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
++@@ -106,6 +107,7 @@ class WinTool(object):
++           print line
++       return popen.returncode
++ 
+++    LinkLock().__exit__(0, 0, 0)
++   def ExecManifestWrapper(self, arch, *args):
++     """Run manifest tool with environment set. Strip out undesirable warning
++     (some XML blocks are recognized by the OS loader, but not the manifest
++@@ -184,7 +186,11 @@ class WinTool(object):
++     for |arch|. If |dir| is supplied, use that as the working directory."""
++     env = self._GetEnv(arch)
++     args = open(rspfile).read()
++-    dir = dir[0] if dir else None
+++    dir = None
+++    if dir:
+++      dir = dir[0]
+++    else:
+++      dir = None
++     popen = subprocess.Popen(args, shell=True, env=env, cwd=dir)
++     popen.wait()
++     return popen.returncode
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/xcode_emulation.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/xcode_emulation.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/xcode_emulation.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/xcode_emulation.py	2014-10-24 11:41:35.472880172 -0600
++@@ -415,7 +415,7 @@ class XcodeSettings(object):
++       return None
++     install_base = self.GetPerTargetSetting(
++         'DYLIB_INSTALL_NAME_BASE',
++-        default='/Library/Frameworks' if self._IsBundle() else '/usr/local/lib')
+++        default=('/usr/local/lib', '/Library/Frameworks')[self._IsBundle()])
++     return install_base
++ 
++   def _StandardizePath(self, path):
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/xcodeproj_file.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/xcodeproj_file.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/xcodeproj_file.py.python3	2014-07-17 18:05:40.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/pylib/gyp/xcodeproj_file.py	2014-10-24 11:41:35.473880168 -0600
++@@ -216,8 +216,7 @@ class XCObject(object):
++              is_strong: If property_type is an XCObject subclass, is_strong
++                         is True to assert that this class "owns," or serves
++                         as parent, to the property value (or, if is_list is
++-                        True, values).  is_strong must be False if
++-                        property_type is not an XCObject subclass.
+++                        True, values).  is_strong must be False if property_type is not an XCObject subclass.
++              is_required: True if the property is required for the class.
++                           Note that is_required being True does not preclude
++                           an empty string ("", in the case of property_type
++@@ -954,8 +953,7 @@ class XCHierarchicalElement(XCObject):
++ 
++     XCHierarchicalElements are special.  Generally, their hashes shouldn't
++     change if the paths don't change.  The normal XCObject implementation of
++-    Hashables adds a hashable for each object, which means that if
++-    the hierarchical structure changes (possibly due to changes caused when
+++    Hashables adds a hashable for each object, which means that if the hierarchical structure changes (possibly due to changes caused when
++     TakeOverOnlyChild runs and encounters slight changes in the hierarchy),
++     the hashes will change.  For example, if a project file initially contains
++     a/b/f1 and a/b becomes collapsed into a/b, f1 will have a single parent
++@@ -2132,8 +2130,7 @@ class XCTarget(XCRemoteObject):
++ 
++     # Set up additional defaults not expressed in the schema.  If a "name"
++     # property was supplied, set "productName" if it is not present.  Also set
++-    # the "PRODUCT_NAME" build setting in each configuration, but only if
++-    # the setting is not present in any build configuration.
+++    # the "PRODUCT_NAME" build setting in each configuration, but only if # the setting is not present in any build configuration.
++     if 'name' in self._properties:
++       if not 'productName' in self._properties:
++         self.SetProperty('productName', self._properties['name'])
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/library/gyptest-shared-obj-install-path.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/library/gyptest-shared-obj-install-path.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/library/gyptest-shared-obj-install-path.py.python3	2014-07-17 18:05:41.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/library/gyptest-shared-obj-install-path.py	2014-10-24 11:41:35.473880168 -0600
++@@ -10,7 +10,7 @@ their install location rather than by th
++ """
++ 
++ # Python 2.5 needs this for the with statement.
++-from __future__ import with_statement
+++
++ 
++ import os
++ import TestGyp
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/lib/TestCmd.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/lib/TestCmd.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/lib/TestCmd.py.python3	2014-07-17 18:05:41.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/lib/TestCmd.py	2014-10-24 11:41:35.473880168 -0600
++@@ -1127,8 +1127,10 @@ class TestCmd(object):
++         file = self.canonicalize(file)
++         if mode[0] != 'r':
++             raise ValueError, "mode must begin with 'r'"
++-        with open(file, mode) as f:
+++        f = open(file, mode)
+++        if 1:
++             result = f.read()
+++        f.__exit__(0, 0, 0)
++         return result
++ 
++     def rmdir(self, dir):
++@@ -1587,9 +1589,11 @@ class TestCmd(object):
++         file = self.canonicalize(file)
++         if mode[0] != 'w':
++             raise ValueError, "mode must begin with 'w'"
++-        with open(file, mode) as f:
+++        f = open(file, mode).__enter__()
+++        if 1:
++             f.write(content)
++ 
+++        f.close()
++ # Local Variables:
++ # tab-width:4
++ # indent-tabs-mode:nil
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/lib/TestCommon.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/lib/TestCommon.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/lib/TestCommon.py.python3	2014-07-17 18:05:41.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/lib/TestCommon.py	2014-10-24 11:41:35.474880163 -0600
++@@ -499,7 +499,8 @@ class TestCommon(TestCmd):
++         """Runs the program under test, checking that the test succeeded.
++ 
++         The arguments are the same as the base TestCmd.run() method,
++-        with the addition of:
+++        the addition of.__enter__()
+++        if 1:
++ 
++                 options Extra options that get appended to the beginning
++                         of the arguments.
++@@ -516,6 +517,7 @@ class TestCommon(TestCmd):
++                         command.  A value of None means don't
++                         test exit status.
++ 
+++        the addition of.__exit__(0, 0, 0)
++         By default, this expects a successful exit (status = 0), does
++         not test standard output (stdout = None), and expects that error
++         output is empty (stderr = "").
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/make/gyptest-noload.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/make/gyptest-noload.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/make/gyptest-noload.py.python3	2014-07-17 18:05:41.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/make/gyptest-noload.py	2014-10-24 11:41:35.474880163 -0600
++@@ -10,7 +10,7 @@ optional.
++ """
++ 
++ # Python 2.5 needs this for the with statement.
++-from __future__ import with_statement
+++
++ 
++ import os
++ import TestGyp
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/ninja/action_dependencies/gyptest-action-dependencies.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/ninja/action_dependencies/gyptest-action-dependencies.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/ninja/action_dependencies/gyptest-action-dependencies.py.python3	2014-07-17 18:05:41.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/ninja/action_dependencies/gyptest-action-dependencies.py	2014-10-24 11:41:35.474880163 -0600
++@@ -27,7 +27,7 @@ test.run_gyp('action_dependencies.gyp',
++ chdir = 'relocate/src'
++ test.relocate('src', chdir)
++ 
++-objext = '.obj' if sys.platform == 'win32' else '.o'
+++objext = ('.o', '.obj')[sys.platform == 'win32']
++ 
++ test.build('action_dependencies.gyp',
++            os.path.join('obj', 'b.b' + objext),
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/ninja/chained-dependency/gyptest-chained-dependency.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/ninja/chained-dependency/gyptest-chained-dependency.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/ninja/chained-dependency/gyptest-chained-dependency.py.python3	2014-07-17 18:05:41.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/ninja/chained-dependency/gyptest-chained-dependency.py	2014-10-24 11:41:35.474880163 -0600
++@@ -19,7 +19,7 @@ import TestGyp
++ 
++ test = TestGyp.TestGyp(formats=['ninja'])
++ test.run_gyp('chained-dependency.gyp')
++-objext = '.obj' if sys.platform == 'win32' else '.o'
+++objext = ('.o', '.obj')[sys.platform == 'win32']
++ test.build('chained-dependency.gyp',
++            os.path.join('obj', 'chained.chained' + objext))
++ # The test passes if the .o file builds successfully.
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/win/gyptest-cl-function-level-linking.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/win/gyptest-cl-function-level-linking.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/win/gyptest-cl-function-level-linking.py.python3	2014-07-17 18:05:42.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/win/gyptest-cl-function-level-linking.py	2014-10-24 11:41:35.474880163 -0600
++@@ -29,7 +29,7 @@ if sys.platform == 'win32':
++       test.fail_test()
++ 
++   def Object(proj, obj):
++-    sep = '.' if test.format == 'ninja' else '\\'
+++    sep = ('\\', '.')[test.format == 'ninja']
++     return 'obj\\%s%s%s' % (proj, sep, obj)
++ 
++   look_for = '''COMDAT; sym= "int __cdecl comdat_function'''
++diff -up comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-debug-info.py.python3 comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-debug-info.py
++--- comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-debug-info.py.python3	2014-07-17 18:05:42.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/tools/gyp/test/win/gyptest-link-debug-info.py	2014-10-24 11:41:35.474880163 -0600
++@@ -19,7 +19,7 @@ if sys.platform == 'win32':
++   test.run_gyp('debug-info.gyp', chdir=CHDIR)
++   test.build('debug-info.gyp', test.ALL, chdir=CHDIR)
++ 
++-  suffix = '.exe.pdb' if test.format == 'ninja' else '.pdb'
+++  suffix = ('.pdb', '.exe.pdb')[test.format == 'ninja']
++   test.built_file_must_not_exist('test_debug_off%s' % suffix, chdir=CHDIR)
++   test.built_file_must_exist('test_debug_on%s' % suffix, chdir=CHDIR)
++ 
++diff -up comm-esr31/mozilla/media/webrtc/trunk/webrtc/test/buildbot_tests.py.python3 comm-esr31/mozilla/media/webrtc/trunk/webrtc/test/buildbot_tests.py
++--- comm-esr31/mozilla/media/webrtc/trunk/webrtc/test/buildbot_tests.py.python3	2014-07-17 18:05:43.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/webrtc/test/buildbot_tests.py	2014-10-24 11:41:35.475880159 -0600
++@@ -128,7 +128,7 @@ def main():
++     print 'Running: %s' % ' '.join(cmd_line)
++     try:
++       subprocess.check_call(cmd_line, env=env)
++-    except subprocess.CalledProcessError as e:
+++    except subprocess.CalledProcessError, e:
++       print >> sys.stderr, ('An error occurred during test execution: return '
++                             'code: %d' % e.returncode)
++       return -1
++diff -up comm-esr31/mozilla/media/webrtc/trunk/webrtc/tools/barcode_tools/barcode_decoder.py.python3 comm-esr31/mozilla/media/webrtc/trunk/webrtc/tools/barcode_tools/barcode_decoder.py
++--- comm-esr31/mozilla/media/webrtc/trunk/webrtc/tools/barcode_tools/barcode_decoder.py.python3	2014-07-17 18:05:43.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/webrtc/tools/barcode_tools/barcode_decoder.py	2014-10-24 11:41:35.475880159 -0600
++@@ -39,7 +39,7 @@ def convert_yuv_to_png_files(yuv_file_na
++   """
++   size_string = str(yuv_frame_width) + 'x' + str(yuv_frame_height)
++   output_files_pattern = os.path.join(output_directory, 'frame_%04d.png')
++-  ffmpeg_executable = 'ffmpeg.exe' if sys.platform == 'win32' else 'ffmpeg'
+++  ffmpeg_executable = ('ffmpeg', 'ffmpeg.exe')[sys.platform == 'win32']
++   if ffmpeg_dir:
++     ffmpeg_executable = os.path.join(ffmpeg_dir, ffmpeg_executable)
++   command = [ffmpeg_executable, '-s', '%s' % size_string, '-i', '%s'
++@@ -78,7 +78,7 @@ def decode_frames(input_directory, zxing
++   Return:
++     (bool): True if the decoding went without errors.
++   """
++-  zxing_executable = 'zxing.exe' if sys.platform == 'win32' else 'zxing'
+++  zxing_executable = ('zxing', 'zxing.exe')[sys.platform == 'win32']
++   if zxing_dir:
++     zxing_executable = os.path.join(zxing_dir, zxing_executable)
++   print 'Decoding barcodes from PNG files with %s...' % zxing_executable
++diff -up comm-esr31/mozilla/media/webrtc/trunk/webrtc/tools/barcode_tools/barcode_encoder.py.python3 comm-esr31/mozilla/media/webrtc/trunk/webrtc/tools/barcode_tools/barcode_encoder.py
++--- comm-esr31/mozilla/media/webrtc/trunk/webrtc/tools/barcode_tools/barcode_encoder.py.python3	2014-07-17 18:05:43.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/webrtc/tools/barcode_tools/barcode_encoder.py	2014-10-24 11:41:35.475880159 -0600
++@@ -58,7 +58,7 @@ def generate_upca_barcodes(number_of_bar
++     try:
++       helper_functions.run_shell_command(
++           command, fail_msg=('Error during barcode %s generation' % content))
++-    except helper_functions.HelperError as err:
+++    except helper_functions.HelperError, err:
++       print >> sys.stderr, err
++       errors = True
++   return not errors
++@@ -110,7 +110,7 @@ def _convert_to_yuv_and_delete(output_di
++         command, fail_msg=('Error during PNG to YUV conversion of %s' %
++                            file_name))
++     os.remove(file_name)
++-  except helper_functions.HelperError as err:
+++  except helper_functions.HelperError, err:
++     print >> sys.stderr, err
++     return False
++   return True
++@@ -153,7 +153,7 @@ def _add_to_file_and_delete(output_file,
++   input_file.close()
++   try:
++     os.remove(file_name)
++-  except OSError as e:
+++  except OSError, e:
++     print >> sys.stderr, 'Error deleting file %s.\nError: %s' % (file_name, e)
++     return False
++   return True
++@@ -330,8 +330,7 @@ def _main():
++   --output_yuv=<path and name_of_output_file>
++   """
++   options = _parse_args()
++-  # The barcodes with will be different than the base frame width only if
++-  # explicitly specified at the command line.
+++  # The barcodes with will be different than the base frame width only if # explicitly specified at the command line.
++   if options.barcode_width == _DEFAULT_BARCODE_WIDTH:
++     options.barcode_width = options.base_frame_width
++   # If the user provides a value for the barcodes YUV video file, we will keep
++diff -up comm-esr31/mozilla/media/webrtc/trunk/webrtc/tools/barcode_tools/build_zxing.py.python3 comm-esr31/mozilla/media/webrtc/trunk/webrtc/tools/barcode_tools/build_zxing.py
++--- comm-esr31/mozilla/media/webrtc/trunk/webrtc/tools/barcode_tools/build_zxing.py.python3	2014-07-17 18:05:43.000000000 -0600
+++++ comm-esr31/mozilla/media/webrtc/trunk/webrtc/tools/barcode_tools/build_zxing.py	2014-10-24 11:41:35.475880159 -0600
++@@ -27,7 +27,7 @@ def run_ant_build_command(path_to_ant_bu
++     if process.returncode != 0:
++       print >> sys.stderr, 'Failed to execute: %s' % ' '.join(cmd)
++     return process.returncode
++-  except subprocess.CalledProcessError as e:
+++  except subprocess.CalledProcessError, e:
++     print >> sys.stderr, 'Failed to execute: %s.\nCause: %s' % (' '.join(cmd),
++                                                                 e)
++     return -1
++diff -up comm-esr31/mozilla/mobile/android/debug_sign_tool.py.python3 comm-esr31/mozilla/mobile/android/debug_sign_tool.py
++--- comm-esr31/mozilla/mobile/android/debug_sign_tool.py.python3	2014-07-17 18:05:44.000000000 -0600
+++++ comm-esr31/mozilla/mobile/android/debug_sign_tool.py	2014-10-24 11:41:35.476880155 -0600
++@@ -55,7 +55,7 @@ class DebugKeystore:
++                 subprocess.check_call(args)
++             else:
++                 subprocess.check_output(args)
++-        except OSError as ex:
+++        except OSError, ex:
++             if ex.errno != errno.ENOENT:
++                 raise
++             raise Exception("Could not find executable '%s'" % args[0])
++@@ -72,12 +72,12 @@ class DebugKeystore:
++         contains = True
++         try:
++             self._check(args)
++-        except subprocess.CalledProcessError as e:
+++        except subprocess.CalledProcessError, e:
++             contains = False
++         if self.verbose:
++             log.info('Keystore %s %s alias %s' %
++                      (self.keystore,
++-                      'contains' if contains else 'does not contain',
+++                      ('does not contain', 'contains')[contains],
++                       self.alias))
++         return contains
++ 
++@@ -85,7 +85,7 @@ class DebugKeystore:
++         try:
++             path = os.path.dirname(self.keystore)
++             os.makedirs(path)
++-        except OSError as exception:
+++        except OSError, exception:
++             if exception.errno != errno.EEXIST:
++                 raise
++ 
++@@ -167,7 +167,7 @@ def main():
++     if args.force:
++         try:
++             keystore.create_alias_in_keystore()
++-        except subprocess.CalledProcessError as e:
+++        except subprocess.CalledProcessError, e:
++             log.error('Failed to force-create alias %s in keystore %s' %
++                       (keystore.alias, keystore.keystore))
++             log.error(e)
++@@ -176,7 +176,7 @@ def main():
++     for apk in args.apks:
++         try:
++             keystore.sign(apk)
++-        except subprocess.CalledProcessError as e:
+++        except subprocess.CalledProcessError, e:
++             log.error('Failed to sign %s', apk)
++             log.error(e)
++             return 1
++diff -up comm-esr31/mozilla/mozglue/build/fixcrt.py.python3 comm-esr31/mozilla/mozglue/build/fixcrt.py
++--- comm-esr31/mozilla/mozglue/build/fixcrt.py.python3	2014-07-17 18:05:45.000000000 -0600
+++++ comm-esr31/mozilla/mozglue/build/fixcrt.py	2014-10-24 11:41:35.476880155 -0600
++@@ -2,13 +2,16 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import with_statement
+++
++ 
++ with open('crtdll.obj', 'rb') as infile:
++   data = infile.read()
++-  with open('crtdll_fixed.obj', 'wb') as outfile:
+++  outfile = open('crtdll_fixed.obj', 'wb')
+++  if 1:
++     # for Win32
++     data = data.replace('__imp__free', '__imp__frex')
++     # for Win64
++     data = data.replace('__imp_free', '__imp_frex')
++     outfile.write(data)
+++  outfile.close()
+++
++diff -up comm-esr31/mozilla/netwerk/protocol/http/make_incoming_tables.py.python3 comm-esr31/mozilla/netwerk/protocol/http/make_incoming_tables.py
++--- comm-esr31/mozilla/netwerk/protocol/http/make_incoming_tables.py.python3	2014-07-17 18:05:46.000000000 -0600
+++++ comm-esr31/mozilla/netwerk/protocol/http/make_incoming_tables.py	2014-10-24 11:41:35.476880155 -0600
++@@ -84,7 +84,7 @@ def output_table(table, name_suffix=''):
++         elif t is not None:
++             output_table(t, '%s_%s' % (name_suffix, i))
++ 
++-    tablename = 'HuffmanIncoming%s' % (name_suffix if name_suffix else 'Root',)
+++    tablename = 'HuffmanIncoming%s' % (('Root', name_suffix)[name_suffix],)
++     entriestable = tablename.replace('HuffmanIncoming', 'HuffmanIncomingEntries')
++     sys.stdout.write('static HuffmanIncomingEntry %s[] = {\n' % (entriestable,))
++     prefix_len = 0
++diff -up comm-esr31/mozilla/other-licenses/ply/ply/yacc.py.python3 comm-esr31/mozilla/other-licenses/ply/ply/yacc.py
++--- comm-esr31/mozilla/other-licenses/ply/ply/yacc.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/other-licenses/ply/ply/yacc.py	2014-10-24 11:41:35.477880151 -0600
++@@ -98,7 +98,7 @@ else:
++ try:
++     MAXINT = sys.maxint
++ except AttributeError:
++-    MAXINT = sys.maxsize
+++    MAXINT = sys.maxint
++ 
++ # Python 2.x/3.0 compatibility.
++ def load_ply_lex():
++@@ -501,8 +501,7 @@ class LRParser:
++                 #
++                 # In addition to pushing the error token, we call call
++                 # the user defined p_error() function if this is the
++-                # first syntax error.  This function is only called if
++-                # errorcount == 0.
+++                # first syntax error.  This function is only called if # errorcount == 0.
++                 if errorcount == 0 or self.errorok:
++                     errorcount = error_count
++                     self.errorok = 0
++@@ -774,8 +773,7 @@ class LRParser:
++                 #
++                 # In addition to pushing the error token, we call call
++                 # the user defined p_error() function if this is the
++-                # first syntax error.  This function is only called if
++-                # errorcount == 0.
+++                # first syntax error.  This function is only called if # errorcount == 0.
++                 if errorcount == 0 or self.errorok:
++                     errorcount = error_count
++                     self.errorok = 0
++@@ -1029,8 +1027,7 @@ class LRParser:
++                 #
++                 # In addition to pushing the error token, we call call
++                 # the user defined p_error() function if this is the
++-                # first syntax error.  This function is only called if
++-                # errorcount == 0.
+++                # first syntax error.  This function is only called if # errorcount == 0.
++                 if errorcount == 0 or self.errorok:
++                     errorcount = error_count
++                     self.errorok = 0
++diff -up comm-esr31/mozilla/python/blessings/blessings/__init__.py.python3 comm-esr31/mozilla/python/blessings/blessings/__init__.py
++--- comm-esr31/mozilla/python/blessings/blessings/__init__.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/blessings/blessings/__init__.py	2014-10-24 11:41:35.477880151 -0600
++@@ -1,4 +1,4 @@
++-from collections import defaultdict
+++from mycollections import defaultdict
++ import curses
++ from curses import tigetstr, tigetnum, setupterm, tparm
++ from fcntl import ioctl
++@@ -73,9 +73,11 @@ class Terminal(object):
++         if stream is None:
++             stream = sys.__stdout__
++         try:
++-            stream_descriptor = (stream.fileno() if hasattr(stream, 'fileno')
++-                                                 and callable(stream.fileno)
++-                                 else None)
+++            stream_descriptor = None
+++            if hasattr(stream, 'fileno') and callable(stream.fileno):
+++               stream_descriptor = (stream.fileno())
+++            else:
+++               stream_descriptor = (None)
++         except IOUnsupportedOperation:
++             stream_descriptor = None
++ 
++@@ -85,9 +87,11 @@ class Terminal(object):
++         # The desciptor to direct terminal initialization sequences to.
++         # sys.__stdout__ seems to always have a descriptor of 1, even if output
++         # is redirected.
++-        self._init_descriptor = (sys.__stdout__.fileno()
++-                                 if stream_descriptor is None
++-                                 else stream_descriptor)
+++        self._init_descriptor = None
+++        if stream_descriptor is None:
+++          self._init_descriptor = (sys.__stdout__.fileno())
+++        else:
+++          self._init_descriptor = (stream_descriptor)
++         if self._does_styling:
++             # Make things like tigetstr() work. Explicit args make setupterm()
++             # work even when -s is passed to nosetests. Lean toward sending
++@@ -154,7 +158,11 @@ class Terminal(object):
++         Return values are always Unicode.
++ 
++         """
++-        resolution = self._resolve_formatter(attr) if self._does_styling else NullCallableString()
+++        resolution = None
+++        if self._does_styling:
+++          resolution = self._resolve_formatter(attr)
+++        else:
+++          resolution = NullCallableString()
++         setattr(self, attr, resolution)  # Cache capability codes.
++         return resolution
++ 
++@@ -200,11 +208,13 @@ class Terminal(object):
++         there, then return the cursor to its original position::
++ 
++             term = Terminal()
++-            with term.location(2, 5):
+++            term.location(2, 5).__enter__()
+++            if 1:
++                 print 'Hello, world!'
++                 for x in xrange(10):
++                     print 'I can do it %i times!' % x
++ 
+++            term.location(2, 5).__exit__(0, 0, 0)
++         Specify ``x`` to move to a certain column, ``y`` to move to a certain
++         row, or both.
++ 
++@@ -256,7 +266,10 @@ class Terminal(object):
++         # access to it.
++         colors = tigetnum('colors')  # Returns -1 if no color support, -2 if no such cap.
++         #self.__dict__['colors'] = ret  # Cache it. It's not changing. (Doesn't work.)
++-        return colors if colors >= 0 else 0
+++        if colors >= 0:
+++          return colors
+++        else:
+++          return 0
++ 
++     def _resolve_formatter(self, attr):
++         """Resolve a sugary or plain capability name, color, or compound formatting function name into a callable capability."""
++@@ -297,11 +310,18 @@ class Terminal(object):
++         # yellow when a terminal supports setf/setb rather than setaf/setab?
++         # I'll be blasted if I can find any documentation. The following
++         # assumes it does.
++-        color_cap = (self._background_color if 'on_' in color else
++-                     self._foreground_color)
+++        color_cap = None
+++        if 'on_' in color:
+++          color_cap = (self._background_color)
+++        else:
+++          color_cap = (self._foreground_color)
++         # curses constants go up to only 7, so add an offset to get at the
++         # bright colors at 8-15:
++-        offset = 8 if 'bright_' in color else 0
+++        offset = None
+++        if 'bright_' in color:
+++          offset = 8
+++        else:
+++          offset = 0
++         base_color = color.rsplit('_', 1)[-1]
++         return self._formatting_string(
++             color_cap(getattr(curses, 'COLOR_' + base_color.upper()) + offset))
++@@ -353,8 +373,7 @@ class ParametrizingString(unicode):
++             # 3. However, appear to be a plain Unicode string otherwise so
++             # concats work.
++             parametrized = tparm(self.encode('utf-8'), *args).decode('utf-8')
++-            return (parametrized if self._normal is None else
++-                    FormattingString(parametrized, self._normal))
+++            return ((FormattingString(parametrized, self._normal), parametrized)[self._normal is None])
++         except curses.error:
++             # Catch "must call (at least) setupterm() first" errors, as when
++             # running simply `nosetests` (without progressive) on nose-
++diff -up comm-esr31/mozilla/python/blessings/blessings/tests.py.python3 comm-esr31/mozilla/python/blessings/blessings/tests.py
++--- comm-esr31/mozilla/python/blessings/blessings/tests.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/blessings/blessings/tests.py	2014-10-24 11:41:35.477880151 -0600
++@@ -9,7 +9,7 @@ All we require from the host machine is
++ xterm-256color exists.
++ 
++ """
++-from __future__ import with_statement  # Make 2.5-compatible
+++  # Make 2.5-compatible
++ from curses import tigetstr, tparm
++ from functools import partial
++ from StringIO import StringIO
++@@ -83,9 +83,11 @@ def test_location():
++     """Make sure ``location()`` does what it claims."""
++     t = TestTerminal(stream=StringIO(), force_styling=True)
++ 
++-    with t.location(3, 4):
+++    t.location(3, 4).__enter__()
+++    if 1:
++         t.stream.write(u'hi')
++ 
+++    t.location(3, 4).__exit__(0, 0, 0)
++     eq_(t.stream.getvalue(), unicode_cap('sc') +
++                              unicode_parm('cup', 4, 3) +
++                              u'hi' +
++@@ -95,8 +97,10 @@ def test_location():
++ def test_horizontal_location():
++     """Make sure we can move the cursor horizontally without changing rows."""
++     t = TestTerminal(stream=StringIO(), force_styling=True)
++-    with t.location(x=5):
+++    t.location(x=5).__enter__()
+++    if 1:
++         pass
+++    t.location(x=5).__exit__(0, 0, 0)
++     eq_(t.stream.getvalue(), unicode_cap('sc') +
++                              unicode_parm('hpa', 5) +
++                              unicode_cap('rc'))
++diff -up comm-esr31/mozilla/python/codegen/makeutils.py.python3 comm-esr31/mozilla/python/codegen/makeutils.py
++--- comm-esr31/mozilla/python/codegen/makeutils.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/codegen/makeutils.py	2014-10-24 11:41:35.477880151 -0600
++@@ -17,11 +17,12 @@ def writeMakeDependOutput(filename):
++     if dir and not os.path.exists(dir):
++         try:
++             os.makedirs(dir)
++-        except OSError as error:
+++        except OSError, error:
++             if error.errno != errno.EEXIST:
++                 raise
++ 
++-    with open(filename, 'w') as f:
+++    f = open(filename, 'w')
+++    if 1:
++         if len(targets) > 0:
++             f.write("%s:" % makeQuote(targets[0]))
++             for filename in dependencies:
++@@ -32,3 +33,5 @@ def writeMakeDependOutput(filename):
++             for filename in dependencies:
++                 f.write('%s:\n' % filename)
++ 
+++    f.close()
+++
++diff -up comm-esr31/mozilla/python/configobj/configobj.py.python3 comm-esr31/mozilla/python/configobj/configobj.py
++--- comm-esr31/mozilla/python/configobj/configobj.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/configobj/configobj.py	2014-10-24 11:41:35.478880146 -0600
++@@ -587,8 +587,7 @@ class Section(dict):
++         (We have to special case 'Section' instances - which are also dicts)
++         
++         Keys must be strings.
++-        Values need only be strings (or lists of strings) if
++-        ``main.stringify`` is set.
+++        Values need only be strings (or lists of strings) if ``main.stringify`` is set.
++         
++         ``unrepr`` must be set when setting a value to a dictionary, without
++         creating a new sub-section.
++diff -up comm-esr31/mozilla/python/mach_commands.py.python3 comm-esr31/mozilla/python/mach_commands.py
++--- comm-esr31/mozilla/python/mach_commands.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach_commands.py	2014-10-24 11:41:35.478880146 -0600
++@@ -2,7 +2,11 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ import argparse
++ import glob
++@@ -106,4 +110,7 @@ class MachCommands(MachCommandBase):
++             if stop and return_code > 0:
++                 return 1
++ 
++-        return 0 if return_code == 0 else 1
+++        if return_code == 0:
+++          return 0
+++        else:
+++          return 1
++diff -up comm-esr31/mozilla/python/mach/mach/base.py.python3 comm-esr31/mozilla/python/mach/mach/base.py
++--- comm-esr31/mozilla/python/mach/mach/base.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/base.py	2014-10-24 11:41:35.478880146 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ 
++ class CommandContext(object):
++diff -up comm-esr31/mozilla/python/mach/mach/commands/commandinfo.py.python3 comm-esr31/mozilla/python/mach/mach/commands/commandinfo.py
++--- comm-esr31/mozilla/python/mach/mach/commands/commandinfo.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/commands/commandinfo.py	2014-10-24 11:41:35.478880146 -0600
++@@ -2,7 +2,11 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, # You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ from mach.decorators import (
++     CommandProvider,
++diff -up comm-esr31/mozilla/python/mach/mach/commands/settings.py.python3 comm-esr31/mozilla/python/mach/mach/commands/settings.py
++--- comm-esr31/mozilla/python/mach/mach/commands/settings.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/commands/settings.py	2014-10-24 11:41:35.478880146 -0600
++@@ -2,7 +2,11 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this file,
++ # You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ from textwrap import TextWrapper
++ 
++diff -up comm-esr31/mozilla/python/mach/mach/config.py.python3 comm-esr31/mozilla/python/mach/mach/config.py
++--- comm-esr31/mozilla/python/mach/mach/config.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/config.py	2014-10-24 11:41:35.479880142 -0600
++@@ -25,7 +25,7 @@ msgfmt binary to perform this conversion
++ can be done via the write_pot() of ConfigSettings.
++ """
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import collections
++ import gettext
++@@ -93,7 +93,7 @@ class BooleanType(ConfigType):
++ 
++     @staticmethod
++     def to_config(value):
++-        return 'true' if value else 'false'
+++        return ('false', 'true')[value]
++ 
++ 
++ class IntegerType(ConfigType):
++@@ -227,7 +227,11 @@ class ConfigProvider(object):
++             raise Exception('Setting has already been registered: %s.%s' % (
++                 section, option))
++ 
++-        domain = domain if domain is not None else section
+++        domain = None
+++        if domain is not None:
+++          domain = domain
+++        else:
+++          domain = section
++ 
++         meta = {
++             'short': '%s.short' % option,
++diff -up comm-esr31/mozilla/python/mach/mach/decorators.py.python3 comm-esr31/mozilla/python/mach/mach/decorators.py
++--- comm-esr31/mozilla/python/mach/mach/decorators.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/decorators.py	2014-10-24 11:41:35.479880142 -0600
++@@ -2,19 +2,19 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import collections
++ import inspect
++ import types
++ 
++-from .base import (
+++from base import (
++     MachError,
++     MethodHandler
++ )
++ 
++-from .config import ConfigProvider
++-from .registrar import Registrar
+++from config import ConfigProvider
+++from registrar import Registrar
++ 
++ 
++ def CommandProvider(cls):
++diff -up comm-esr31/mozilla/python/mach/mach/dispatcher.py.python3 comm-esr31/mozilla/python/mach/mach/dispatcher.py
++--- comm-esr31/mozilla/python/mach/mach/dispatcher.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/dispatcher.py	2014-10-24 11:41:35.479880142 -0600
++@@ -2,14 +2,14 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import argparse
++ import sys
++ 
++ from operator import itemgetter
++ 
++-from .base import (
+++from base import (
++     NoCommandError,
++     UnknownCommandError,
++     UnrecognizedArgumentError,
++diff -up comm-esr31/mozilla/python/mach/mach/logging.py.python3 comm-esr31/mozilla/python/mach/mach/logging.py
++--- comm-esr31/mozilla/python/mach/mach/logging.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/logging.py	2014-10-24 11:41:35.479880142 -0600
++@@ -6,18 +6,25 @@
++ # support for a structured logging framework built on top of Python's built-in
++ # logging framework.
++ 
++-from __future__ import absolute_import, unicode_literals
+++
++ 
++ try:
++     import blessings
++ except ImportError:
++     blessings = None
++ 
++-import json
++-import logging
+++import simplejson as json
+++import rhrebase
+++logging = rhrebase.import_non_local('logging')
+++
+++import logging as moz_logging
++ import sys
++ import time
++ 
+++class NullHandler(logging.Handler):
+++    def emit(self, record):
+++        pass
+++logging.NullHandler = NullHandler
++ 
++ def format_seconds(total):
++     """Format number of seconds to MM:SS.DD form."""
++@@ -145,7 +152,7 @@ class LoggingManager(object):
++         # Installing NullHandler on the root logger ensures that *all* log
++         # messages have at least one handler. This prevents Python from
++         # complaining about "no handlers could be found for logger XXX."
++-        self.root_logger.addHandler(logging.NullHandler())
+++        #FIXME? self.root_logger.addHandler(NullHandler())
++ 
++         self.mach_logger = logging.getLogger('mach')
++         self.mach_logger.setLevel(logging.DEBUG)
++@@ -175,7 +182,7 @@ class LoggingManager(object):
++         """Enable JSON logging on the specified file object."""
++ 
++         # Configure the consumer of structured messages.
++-        handler = logging.StreamHandler(stream=fh)
+++        handler = logging.StreamHandler(fh)
++         handler.setFormatter(StructuredJSONFormatter())
++         handler.setLevel(logging.DEBUG)
++ 
++@@ -197,7 +204,7 @@ class LoggingManager(object):
++                 write_interval=write_interval, write_times=write_times)
++             formatter.set_terminal(self.terminal)
++ 
++-        handler = logging.StreamHandler(stream=fh)
+++        handler = logging.StreamHandler(fh)
++         handler.setFormatter(formatter)
++         handler.setLevel(level)
++ 
++diff -up comm-esr31/mozilla/python/mach/mach/main.py.python3 comm-esr31/mozilla/python/mach/mach/main.py
++--- comm-esr31/mozilla/python/mach/mach/main.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/main.py	2014-10-24 11:41:35.480880138 -0600
++@@ -5,7 +5,7 @@
++ # This module provides functionality for the command-line build tool
++ # (mach). It is packaged as a module because everything is a library.
++ 
++-from __future__ import absolute_import, print_function, unicode_literals
+++, print_function, unicode_literals
++ from collections import Iterable
++ 
++ import argparse
++@@ -18,7 +18,7 @@ import traceback
++ import uuid
++ import sys
++ 
++-from .base import (
+++from base import (
++     CommandContext,
++     MachError,
++     NoCommandError,
++@@ -26,16 +26,16 @@ from .base import (
++     UnrecognizedArgumentError,
++ )
++ 
++-from .decorators import (
+++from decorators import (
++     CommandArgument,
++     CommandProvider,
++     Command,
++ )
++ 
++-from .config import ConfigSettings
++-from .dispatcher import CommandAction
++-from .logging import LoggingManager
++-from .registrar import Registrar
+++from config import ConfigSettings
+++from dispatcher import CommandAction
+++from logging import LoggingManager
+++from registrar import Registrar
++ 
++ 
++ 
++@@ -288,9 +288,16 @@ To see more help for a specific command,
++         # up with UnicodeEncodeError as soon as it encounters a non-ASCII
++         # character in a unicode instance. We simply install a wrapper around
++         # the streams and restore once we have finished.
++-        stdin = sys.stdin if stdin is None else stdin
++-        stdout = sys.stdout if stdout is None else stdout
++-        stderr = sys.stderr if stderr is None else stderr
+++        stdin = (sys.stdin, stdin)[stdin]
+++        stdout = (sys.stdout, stdout)[stdout]
+++        stderr = (sys.stderr, stderr)[stderr]
+++        #else:
+++        #  stdin = stdout
+++        #stderr = None
+++        #if stderr is None:
+++        #  stderr = sys.stderr
+++        #else:
+++        #  stderr = stderr
++ 
++         orig_stdin = sys.stdin
++         orig_stdout = sys.stdout
++@@ -315,7 +322,7 @@ To see more help for a specific command,
++             print('mach interrupted by signal or user action. Stopping.')
++             return 1
++ 
++-        except Exception as e:
+++        except Exception, e:
++             # _run swallows exceptions in invoked handlers and converts them to
++             # a proper exit code. So, the only scenario where we should get an
++             # exception here is if _run itself raises. If _run raises, that's a
++@@ -359,10 +366,10 @@ To see more help for a specific command,
++         except NoCommandError:
++             print(NO_COMMAND_ERROR)
++             return 1
++-        except UnknownCommandError as e:
+++        except UnknownCommandError, e:
++             print(UNKNOWN_COMMAND_ERROR % (e.verb, e.command))
++             return 1
++-        except UnrecognizedArgumentError as e:
+++        except UnrecognizedArgumentError, e:
++             print(UNRECOGNIZED_ARGUMENT_ERROR % (e.command,
++                 ' '.join(e.arguments)))
++             return 1
++@@ -421,9 +428,9 @@ To see more help for a specific command,
++             assert isinstance(result, (int, long))
++ 
++             return result
++-        except KeyboardInterrupt as ki:
+++        except KeyboardInterrupt, ki:
++             raise ki
++-        except Exception as e:
+++        except Exception, e:
++             exc_type, exc_value, exc_tb = sys.exc_info()
++ 
++             # The first frame is us and is never used.
++diff -up comm-esr31/mozilla/python/mach/mach/mixin/logging.py.python3 comm-esr31/mozilla/python/mach/mach/mixin/logging.py
++--- comm-esr31/mozilla/python/mach/mach/mixin/logging.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/mixin/logging.py	2014-10-24 11:41:35.480880138 -0600
++@@ -2,10 +2,11 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import absolute_import, unicode_literals
++ 
++-import logging
++ 
+++#import logging
+++from rhrebase import import_non_local
+++logging = import_non_local('logging')
++ 
++ class LoggingMixin(object):
++     """Provides functionality to control logging."""
++@@ -50,6 +51,7 @@ class LoggingMixin(object):
++         self.log(logging.DEBUG, 'login', {'username': 'johndoe'},
++             'User login: {username}')
++         """
++-        self._logger.log(level, format_str,
++-            extra={'action': action, 'params': params})
+++        self._logger.log(level, format_str)
+++            #extra={'action': action, 'params': params})
+++            #extra={'action': action, 'params': params})
++ 
++diff -up comm-esr31/mozilla/python/mach/mach/mixin/process.py.python3 comm-esr31/mozilla/python/mach/mach/mixin/process.py
++--- comm-esr31/mozilla/python/mach/mach/mixin/process.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/mixin/process.py	2014-10-24 11:41:35.480880138 -0600
++@@ -4,16 +4,18 @@
++ 
++ # This module provides mixins to perform process execution.
++ 
++-from __future__ import absolute_import, unicode_literals
++ 
++-import logging
+++
+++#import logging
+++from rhrebase import import_non_local
+++logging = import_non_local('logging')
++ import os
++ import subprocess
++ import sys
++ 
++ from mozprocess.processhandler import ProcessHandlerMixin
++ 
++-from .logging import LoggingMixin
+++from logging import LoggingMixin
++ 
++ 
++ # Perform detection of operating system environment. This is used by command
++@@ -36,7 +38,7 @@ if os.environ.get('MSYSTEM', None) == 'M
++     if not _current_shell.lower().endswith('.exe'):
++         _current_shell += '.exe'
++ 
++-
+++#print dir(logging)
++ class ProcessExecutionMixin(LoggingMixin):
++     """Mix-in that provides process execution functionality."""
++ 
++diff -up comm-esr31/mozilla/python/mach/mach/registrar.py.python3 comm-esr31/mozilla/python/mach/mach/registrar.py
++--- comm-esr31/mozilla/python/mach/mach/registrar.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/registrar.py	2014-10-24 11:41:35.480880138 -0600
++@@ -2,9 +2,9 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
++ 
++-from .base import MachError
+++
+++from base import MachError
++ 
++ 
++ class MachRegistrar(object):
++diff -up comm-esr31/mozilla/python/mach/mach/terminal.py.python3 comm-esr31/mozilla/python/mach/mach/terminal.py
++--- comm-esr31/mozilla/python/mach/mach/terminal.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/terminal.py	2014-10-24 11:41:35.480880138 -0600
++@@ -8,7 +8,11 @@ All the terminal interaction code is con
++ one place, away from code that is commonly looked at.
++ """
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ import logging
++ import sys
++diff -up comm-esr31/mozilla/python/mach/mach/test/common.py.python3 comm-esr31/mozilla/python/mach/mach/test/common.py
++--- comm-esr31/mozilla/python/mach/mach/test/common.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/test/common.py	2014-10-24 11:41:35.481880134 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ from StringIO import StringIO
++ import os
++diff -up comm-esr31/mozilla/python/mach/mach/test/providers/basic.py.python3 comm-esr31/mozilla/python/mach/mach/test/providers/basic.py
++--- comm-esr31/mozilla/python/mach/mach/test/providers/basic.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/test/providers/basic.py	2014-10-24 11:41:35.481880134 -0600
++@@ -1,7 +1,7 @@
++ # This Source Code Form is subject to the terms of the Mozilla Public
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++-from __future__ import unicode_literals
+++
++ 
++ from mach.decorators import (
++     CommandProvider,
++diff -up comm-esr31/mozilla/python/mach/mach/test/providers/conditions_invalid.py.python3 comm-esr31/mozilla/python/mach/mach/test/providers/conditions_invalid.py
++--- comm-esr31/mozilla/python/mach/mach/test/providers/conditions_invalid.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/test/providers/conditions_invalid.py	2014-10-24 11:41:35.481880134 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ from mach.decorators import (
++     CommandProvider,
++diff -up comm-esr31/mozilla/python/mach/mach/test/providers/conditions.py.python3 comm-esr31/mozilla/python/mach/mach/test/providers/conditions.py
++--- comm-esr31/mozilla/python/mach/mach/test/providers/conditions.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/test/providers/conditions.py	2014-10-24 11:41:35.481880134 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ from mach.decorators import (
++     CommandProvider,
++diff -up comm-esr31/mozilla/python/mach/mach/test/providers/throw.py.python3 comm-esr31/mozilla/python/mach/mach/test/providers/throw.py
++--- comm-esr31/mozilla/python/mach/mach/test/providers/throw.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/test/providers/throw.py	2014-10-24 11:41:35.481880134 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import time
++ 
++diff -up comm-esr31/mozilla/python/mach/mach/test/test_conditions.py.python3 comm-esr31/mozilla/python/mach/mach/test/test_conditions.py
++--- comm-esr31/mozilla/python/mach/mach/test/test_conditions.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/test/test_conditions.py	2014-10-24 11:41:35.481880134 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import os
++ 
++diff -up comm-esr31/mozilla/python/mach/mach/test/test_config.py.python3 comm-esr31/mozilla/python/mach/mach/test/test_config.py
++--- comm-esr31/mozilla/python/mach/mach/test/test_config.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/test/test_config.py	2014-10-24 11:41:35.482880130 -0600
++@@ -1,7 +1,7 @@
++ # This Source Code Form is subject to the terms of the Mozilla Public
++ # License, v. 2.0. If a copy of the MPL was not distributed with this file,
++ # You can obtain one at http://mozilla.org/MPL/2.0/.
++-from __future__ import unicode_literals
+++
++ 
++ import sys
++ import unittest
++@@ -67,10 +67,12 @@ class TestConfigProvider(unittest.TestCa
++         self.assertIn('baz', s['foo'])
++ 
++     def test_duplicate_option(self):
++-        with self.assertRaises(Exception):
+++        self.assertRaises(Exception).__enter__()
+++        if 1:
++             ProviderDuplicate.register_settings()
++ 
++ 
+++        self.assertRaises(Exception).__exit__(0, 0, 0)
++ class Provider2(ConfigProvider):
++     @classmethod
++     def _register_settings(cls):
++@@ -117,56 +119,76 @@ class TestConfigSettings(unittest.TestCa
++         a = s.a
++ 
++         # Assigning an undeclared setting raises.
++-        with self.assertRaises(KeyError):
+++        self.assertRaises(KeyError).__enter__()
+++        if 1:
++             a.undefined = True
++ 
++-        with self.assertRaises(KeyError):
+++        self.assertRaises(KeyError).__exit__(0, 0, 0)
+++        self.assertRaises(KeyError).__enter__()
+++        if 1:
++             a['undefined'] = True
++ 
+++        self.assertRaises(KeyError).__exit__(0, 0, 0)
++         # Basic type validation.
++         a.string = 'foo'
++         a.string = 'foo'
++ 
++-        with self.assertRaises(TypeError):
+++        self.assertRaises(TypeError).__enter__()
+++        if 1:
++             a.string = False
++ 
+++        self.assertRaises(TypeError).__exit__(0, 0, 0)
++         a.boolean = True
++         a.boolean = False
++ 
++-        with self.assertRaises(TypeError):
+++        self.assertRaises(TypeError).__enter__()
+++        if 1:
++             a.boolean = 'foo'
++ 
+++        self.assertRaises(TypeError).__exit__(0, 0, 0)
++         a.pos_int = 5
++         a.pos_int = 0
++ 
++-        with self.assertRaises(ValueError):
+++        self.assertRaises(ValueError).__enter__()
+++        if 1:
++             a.pos_int = -1
++ 
++-        with self.assertRaises(TypeError):
+++        self.assertRaises(ValueError).__exit__(0, 0, 0)
+++        self.assertRaises(TypeError).__enter__()
+++        if 1:
++             a.pos_int = 'foo'
++ 
+++        self.assertRaises(TypeError).__exit__(0, 0, 0)
++         a.int = 5
++         a.int = 0
++         a.int = -5
++ 
++-        with self.assertRaises(TypeError):
+++        self.assertRaises(TypeError).__enter__()
+++        if 1:
++             a.int = 1.24
++ 
++-        with self.assertRaises(TypeError):
+++        self.assertRaises(TypeError).__exit__(0, 0, 0)
+++        self.assertRaises(TypeError).__enter__()
+++        if 1:
++             a.int = 'foo'
++ 
+++        self.assertRaises(TypeError).__exit__(0, 0, 0)
++         a.abs_path = '/home/gps'
++ 
++-        with self.assertRaises(ValueError):
+++        self.assertRaises(ValueError).__enter__()
+++        if 1:
++             a.abs_path = 'home/gps'
++ 
+++        self.assertRaises(ValueError).__exit__(0, 0, 0)
++         a.rel_path = 'home/gps'
++         a.rel_path = './foo/bar'
++         a.rel_path = 'foo.c'
++ 
++-        with self.assertRaises(ValueError):
+++        self.assertRaises(ValueError).__enter__()
+++        if 1:
++             a.rel_path = '/foo/bar'
++ 
+++        self.assertRaises(ValueError).__exit__(0, 0, 0)
++         a.path = '/home/gps'
++         a.path = 'foo.c'
++         a.path = 'foo/bar'
++diff -up comm-esr31/mozilla/python/mach/mach/test/test_entry_point.py.python3 comm-esr31/mozilla/python/mach/mach/test/test_entry_point.py
++--- comm-esr31/mozilla/python/mach/mach/test/test_entry_point.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/test/test_entry_point.py	2014-10-24 11:41:35.482880130 -0600
++@@ -1,7 +1,7 @@
++ # This Source Code Form is subject to the terms of the Mozilla Public
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++-from __future__ import unicode_literals
+++
++ 
++ import imp
++ import os
++@@ -43,9 +43,11 @@ class TestEntryPoints(TestBase):
++ 
++         mock.return_value = [Entry(['providers'])]
++         # Mach error raised due to conditions_invalid.py
++-        with self.assertRaises(MachError):
+++        self.assertRaises(MachError).__enter__()
+++        if 1:
++             self._run_mach()
++ 
+++        self.assertRaises(MachError).__exit__(0, 0, 0)
++     @patch('pkg_resources.iter_entry_points')
++     def test_load_entry_point_from_file(self, mock):
++         mock.return_value = [Entry([os.path.join('providers', 'basic.py')])]
++diff -up comm-esr31/mozilla/python/mach/mach/test/test_error_output.py.python3 comm-esr31/mozilla/python/mach/mach/test/test_error_output.py
++--- comm-esr31/mozilla/python/mach/mach/test/test_error_output.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/test/test_error_output.py	2014-10-24 11:41:35.482880130 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ from mach.main import (
++     COMMAND_ERROR,
++diff -up comm-esr31/mozilla/python/mach/mach/test/test_logger.py.python3 comm-esr31/mozilla/python/mach/mach/test/test_logger.py
++--- comm-esr31/mozilla/python/mach/mach/test/test_logger.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mach/mach/test/test_logger.py	2014-10-24 11:41:35.482880130 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import absolute_import, unicode_literals
+++
++ 
++ import logging
++ import time
++diff -up comm-esr31/mozilla/python/mock-1.0.0/mock.py.python3 comm-esr31/mozilla/python/mock-1.0.0/mock.py
++--- comm-esr31/mozilla/python/mock-1.0.0/mock.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mock-1.0.0/mock.py	2014-10-24 11:41:35.483880125 -0600
++@@ -871,8 +871,7 @@ class NonCallableMock(Base):
++         """assert the mock has been called with the specified arguments.
++ 
++         The assert passes if the mock has *ever* been called, unlike
++-        `assert_called_with` and `assert_called_once_with` that only pass if
++-        the call is the most recent one."""
+++        `assert_called_with` and `assert_called_once_with` that only pass if the call is the most recent one."""
++         kall = call(*args, **kwargs)
++         if kall not in self.call_args_list:
++             expected_string = self._format_mock_call_signature(args, kwargs)
++@@ -1438,9 +1437,11 @@ def _patch_multiple(target, spec=None, c
++     patched (either as an object or a string to fetch the object by importing)
++     and keyword arguments for the patches::
++ 
++-        with patch.multiple(settings, FIRST_PATCH='one', SECOND_PATCH='two'):
+++        patch.multiple(settings, FIRST_PATCH='one', SECOND_PATCH='two').__enter__()
+++        if 1:
++             ...
++ 
+++        patch.multiple(settings, FIRST_PATCH='one', SECOND_PATCH='two').__exit__(0, 0, 0)
++     Use `DEFAULT` as the value if you want `patch.multiple` to create
++     mocks for you. In this case the created mocks are passed into a decorated
++     function by keyword, and a dictionary is returned when `patch.multiple` is
++@@ -1517,8 +1518,7 @@ def patch(
++     then the mock with be created with a spec from the object being replaced.
++     All attributes of the mock will also have the spec of the corresponding
++     attribute of the object being replaced. Methods and functions being
++-    mocked will have their arguments checked and will raise a `TypeError` if
++-    they are called with the wrong signature. For mocks replacing a class,
+++    mocked will have their arguments checked and will raise a `TypeError` if they are called with the wrong signature. For mocks replacing a class,
++     their return value (the 'instance') will have the same spec as the class.
++ 
++     Instead of `autospec=True` you can pass `autospec=some_object` to use an
++@@ -1578,9 +1578,11 @@ class _patch_dict(object):
++     `patch.dict` can also be called with arbitrary keyword arguments to set
++     values in the dictionary::
++ 
++-        with patch.dict('sys.modules', mymodule=Mock(), other_module=Mock()):
+++        patch.dict('sys.modules', mymodule=Mock(), other_module=Mock()).__enter__()
+++        if 1:
++             ...
++ 
+++        patch.dict('sys.modules', mymodule=Mock(), other_module=Mock()).__exit__(0, 0, 0)
++     `patch.dict` can be used as a context manager, decorator or class
++     decorator. When used as a class decorator `patch.dict` honours
++     `patch.TEST_PREFIX` for choosing which methods to wrap.
++diff -up comm-esr31/mozilla/python/mock-1.0.0/tests/support_with.py.python3 comm-esr31/mozilla/python/mock-1.0.0/tests/support_with.py
++--- comm-esr31/mozilla/python/mock-1.0.0/tests/support_with.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mock-1.0.0/tests/support_with.py	2014-10-24 11:41:35.483880125 -0600
++@@ -1,4 +1,4 @@
++-from __future__ import with_statement
+++
++ 
++ import sys
++ 
++@@ -88,6 +88,8 @@ except ImportError:
++ 
++ def examine_warnings(func):
++     def wrapper():
++-        with catch_warnings(record=True) as ws:
+++        ws = catch_warnings(record=True).__enter__()
+++        if 1:
++             func(ws)
+++        ws.__exit__(0, 0, 0)
++     return wrapper
++diff -up comm-esr31/mozilla/python/mock-1.0.0/tests/testmagicmethods.py.python3 comm-esr31/mozilla/python/mock-1.0.0/tests/testmagicmethods.py
++--- comm-esr31/mozilla/python/mock-1.0.0/tests/testmagicmethods.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mock-1.0.0/tests/testmagicmethods.py	2014-10-24 11:41:35.483880125 -0600
++@@ -329,7 +329,7 @@ class TestMockingMagicMethods(unittest2.
++         else:
++             # in Python 3 oct and hex use __index__
++             # so these tests are for __index__ in py3k
++-            self.assertEqual(oct(mock), '0o1')
+++            self.assertEqual(oct(mock), '01')
++         self.assertEqual(hex(mock), '0x1')
++         # how to test __sizeof__ ?
++ 
++diff -up comm-esr31/mozilla/python/mock-1.0.0/tests/_testwith.py.python3 comm-esr31/mozilla/python/mock-1.0.0/tests/_testwith.py
++--- comm-esr31/mozilla/python/mock-1.0.0/tests/_testwith.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mock-1.0.0/tests/_testwith.py	2014-10-24 11:41:35.483880125 -0600
++@@ -2,7 +2,7 @@
++ # E-mail: fuzzyman AT voidspace DOT org DOT uk
++ # http://www.voidspace.org.uk/python/mock/
++ 
++-from __future__ import with_statement
+++
++ 
++ from tests.support import unittest2, is_instance
++ 
++@@ -18,16 +18,20 @@ something_else  = sentinel.SomethingElse
++ class WithTest(unittest2.TestCase):
++ 
++     def test_with_statement(self):
++-        with patch('tests._testwith.something', sentinel.Something2):
+++        patch('tests._testwith.something', sentinel.Something2).__enter__()
+++        if 1:
++             self.assertEqual(something, sentinel.Something2, "unpatched")
+++        patch('tests._testwith.something', sentinel.Something2).__exit__(0, 0, 0)
++         self.assertEqual(something, sentinel.Something)
++ 
++ 
++     def test_with_statement_exception(self):
++         try:
++-            with patch('tests._testwith.something', sentinel.Something2):
+++            patch('tests._testwith.something', sentinel.Something2).__enter__()
+++            if 1:
++                 self.assertEqual(something, sentinel.Something2, "unpatched")
++                 raise Exception('pow')
+++            patch('tests._testwith.something', sentinel.Something2).__exit__(0, 0, 0)
++         except Exception:
++             pass
++         else:
++@@ -36,10 +40,12 @@ class WithTest(unittest2.TestCase):
++ 
++ 
++     def test_with_statement_as(self):
++-        with patch('tests._testwith.something') as mock_something:
+++        mock_something = patch('tests._testwith.something').__enter__()
+++        if 1:
++             self.assertEqual(something, mock_something, "unpatched")
++             self.assertTrue(is_instance(mock_something, MagicMock),
++                             "patching wrong type")
+++        mock_something.__exit__(0, 0, 0)
++         self.assertEqual(something, sentinel.Something)
++ 
++ 
++@@ -47,27 +53,33 @@ class WithTest(unittest2.TestCase):
++         class Foo(object):
++             something = 'foo'
++         original = Foo.something
++-        with patch.object(Foo, 'something'):
+++        patch.object(Foo, 'something').__enter__()
+++        if 1:
++             self.assertNotEqual(Foo.something, original, "unpatched")
+++        patch.object(Foo, 'something').__exit__(0, 0, 0)
++         self.assertEqual(Foo.something, original)
++ 
++ 
++     def test_with_statement_nested(self):
++-        with catch_warnings(record=True):
+++        catch_warnings(record=True).__enter__()
+++        if 1:
++             # nested is deprecated in Python 2.7
++             with nested(patch('tests._testwith.something'),
++                     patch('tests._testwith.something_else')) as (mock_something, mock_something_else):
++                 self.assertEqual(something, mock_something, "unpatched")
++                 self.assertEqual(something_else, mock_something_else,
++                                  "unpatched")
+++        catch_warnings(record=True).__exit__(0, 0, 0)
++         self.assertEqual(something, sentinel.Something)
++         self.assertEqual(something_else, sentinel.SomethingElse)
++ 
++ 
++     def test_with_statement_specified(self):
++-        with patch('tests._testwith.something', sentinel.Patched) as mock_something:
+++        mock_something = patch('tests._testwith.something', sentinel.Patched).__enter__()
+++        if 1:
++             self.assertEqual(something, mock_something, "unpatched")
++             self.assertEqual(mock_something, sentinel.Patched, "wrong patch")
+++        mock_something.__exit__(0, 0, 0)
++         self.assertEqual(something, sentinel.Something)
++ 
++ 
++@@ -77,8 +89,10 @@ class WithTest(unittest2.TestCase):
++         mock.__exit__ = Mock()
++         mock.__exit__.return_value = False
++ 
++-        with mock as m:
+++        m = mock.__enter__()
+++        if 1:
++             self.assertEqual(m, mock.__enter__.return_value)
+++        m.__exit__(0, 0, 0)
++         mock.__enter__.assert_called_with()
++         mock.__exit__.assert_called_with(None, None, None)
++ 
++@@ -86,49 +100,63 @@ class WithTest(unittest2.TestCase):
++     def test_context_manager_with_magic_mock(self):
++         mock = MagicMock()
++ 
++-        with self.assertRaises(TypeError):
+++        self.assertRaises(TypeError).__enter__()
+++        if 1:
++             with mock:
++                 'foo' + 3
+++        self.assertRaises(TypeError).__exit__(0, 0, 0)
++         mock.__enter__.assert_called_with()
++         self.assertTrue(mock.__exit__.called)
++ 
++ 
++     def test_with_statement_same_attribute(self):
++-        with patch('tests._testwith.something', sentinel.Patched) as mock_something:
+++        mock_something = patch('tests._testwith.something', sentinel.Patched).__enter__()
+++        if 1:
++             self.assertEqual(something, mock_something, "unpatched")
++ 
++-            with patch('tests._testwith.something') as mock_again:
+++            mock_again = patch('tests._testwith.something').__enter__()
+++            if 1:
++                 self.assertEqual(something, mock_again, "unpatched")
++ 
+++            mock_again.__exit__(0, 0, 0)
++             self.assertEqual(something, mock_something,
++                              "restored with wrong instance")
++ 
+++        mock_something.__exit__(0, 0, 0)
++         self.assertEqual(something, sentinel.Something, "not restored")
++ 
++ 
++     def test_with_statement_imbricated(self):
++-        with patch('tests._testwith.something') as mock_something:
+++        mock_something = patch('tests._testwith.something').__enter__()
+++        if 1:
++             self.assertEqual(something, mock_something, "unpatched")
++ 
++-            with patch('tests._testwith.something_else') as mock_something_else:
+++            mock_something_else = patch('tests._testwith.something_else').__enter__()
+++            if 1:
++                 self.assertEqual(something_else, mock_something_else,
++                                  "unpatched")
++ 
+++            mock_something_else.__exit__(0, 0, 0)
+++        mock_something.__exit__(0, 0, 0)
++         self.assertEqual(something, sentinel.Something)
++         self.assertEqual(something_else, sentinel.SomethingElse)
++ 
++ 
++     def test_dict_context_manager(self):
++         foo = {}
++-        with patch.dict(foo, {'a': 'b'}):
+++        patch.dict(foo, {'a': 'b'}).__enter__()
+++        if 1:
++             self.assertEqual(foo, {'a': 'b'})
+++        patch.dict(foo, {'a': 'b'}).__exit__(0, 0, 0)
++         self.assertEqual(foo, {})
++ 
++-        with self.assertRaises(NameError):
+++        self.assertRaises(NameError).__enter__()
+++        if 1:
++             with patch.dict(foo, {'a': 'b'}):
++                 self.assertEqual(foo, {'a': 'b'})
++                 raise NameError('Konrad')
++ 
+++        self.assertRaises(NameError).__exit__(0, 0, 0)
++         self.assertEqual(foo, {})
++ 
++ 
++@@ -137,20 +165,26 @@ class TestMockOpen(unittest2.TestCase):
++ 
++     def test_mock_open(self):
++         mock = mock_open()
++-        with patch('%s.open' % __name__, mock, create=True) as patched:
+++        patched = patch('%s.open' % __name__, mock, create=True).__enter__()
+++        if 1:
++             self.assertIs(patched, mock)
++             open('foo')
++ 
+++        patched.__exit__(0, 0, 0)
++         mock.assert_called_once_with('foo')
++ 
++ 
++     def test_mock_open_context_manager(self):
++         mock = mock_open()
++         handle = mock.return_value
++-        with patch('%s.open' % __name__, mock, create=True):
++-            with open('foo') as f:
+++        patch('%s.open' % __name__, mock, create=True).__enter__()
+++        if 1:
+++            f = open('foo')
+++            if 1:
++                 f.read()
++ 
+++            f.close()
+++        patch('%s.open' % __name__, mock, create=True).__exit__(0, 0, 0)
++         expected_calls = [call('foo'), call().__enter__(), call().read(),
++                           call().__exit__(None, None, None)]
++         self.assertEqual(mock.mock_calls, expected_calls)
++@@ -161,19 +195,23 @@ class TestMockOpen(unittest2.TestCase):
++         mock = MagicMock()
++         mock_open(mock)
++ 
++-        with patch('%s.open' % __name__, mock, create=True) as patched:
+++        patched = patch('%s.open' % __name__, mock, create=True).__enter__()
+++        if 1:
++             self.assertIs(patched, mock)
++             open('foo')
++ 
+++        patched.__exit__(0, 0, 0)
++         mock.assert_called_once_with('foo')
++ 
++ 
++     def test_read_data(self):
++         mock = mock_open(read_data='foo')
++-        with patch('%s.open' % __name__, mock, create=True):
+++        patch('%s.open' % __name__, mock, create=True).__enter__()
+++        if 1:
++             h = open('bar')
++             result = h.read()
++ 
+++        patch('%s.open' % __name__, mock, create=True).__exit__(0, 0, 0)
++         self.assertEqual(result, 'foo')
++ 
++ 
++diff -up comm-esr31/mozilla/python/mozboot/mozboot/base.py.python3 comm-esr31/mozilla/python/mozboot/mozboot/base.py
++--- comm-esr31/mozilla/python/mozboot/mozboot/base.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozboot/mozboot/base.py	2014-10-24 11:41:35.484880121 -0600
++@@ -2,7 +2,11 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this file,
++ # You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ import os
++ import re
++diff -up comm-esr31/mozilla/python/mozboot/mozboot/mach_commands.py.python3 comm-esr31/mozilla/python/mozboot/mozboot/mach_commands.py
++--- comm-esr31/mozilla/python/mozboot/mozboot/mach_commands.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozboot/mozboot/mach_commands.py	2014-10-24 11:41:35.484880121 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this,
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ from mach.decorators import (
++     CommandArgument,
++diff -up comm-esr31/mozilla/python/mozboot/mozboot/osx.py.python3 comm-esr31/mozilla/python/mozboot/mozboot/osx.py
++--- comm-esr31/mozilla/python/mozboot/mozboot/osx.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozboot/mozboot/osx.py	2014-10-24 11:41:35.484880121 -0600
++@@ -2,7 +2,11 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this file,
++ # You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ import os
++ import re
++@@ -197,7 +201,7 @@ class OSXBootstrapper(BaseBootstrapper):
++             try:
++                 output = self.check_output([select, '--print-path'],
++                     stderr=subprocess.STDOUT)
++-            except subprocess.CalledProcessError as e:
+++            except subprocess.CalledProcessError, e:
++                 # This seems to appear on fresh OS X machines before any Xcode
++                 # has been installed. It may only occur on OS X 10.9 and later.
++                 if 'unable to get active developer directory' in e.output:
++@@ -218,13 +222,13 @@ class OSXBootstrapper(BaseBootstrapper):
++         try:
++             output = self.check_output(['/usr/bin/xcrun', 'clang'],
++                 stderr=subprocess.STDOUT)
++-        except subprocess.CalledProcessError as e:
+++        except subprocess.CalledProcessError, e:
++             if 'license' in e.output:
++                 xcodebuild = self.which('xcodebuild')
++                 try:
++                     subprocess.check_call([xcodebuild, '-license'],
++                         stderr=subprocess.STDOUT)
++-                except subprocess.CalledProcessError as e:
+++                except subprocess.CalledProcessError, e:
++                     if 'requires admin privileges' in e.output:
++                         self.run_as_root([xcodebuild, '-license'])
++ 
++@@ -372,12 +376,14 @@ class OSXBootstrapper(BaseBootstrapper):
++     def install_homebrew(self):
++         print(PACKAGE_MANAGER_INSTALL % ('Homebrew', 'Homebrew', 'Homebrew', 'brew'))
++         bootstrap = urlopen(url=HOMEBREW_BOOTSTRAP, timeout=20).read()
++-        with tempfile.NamedTemporaryFile() as tf:
+++        tf = tempfile.NamedTemporaryFile().__enter__()
+++        if 1:
++             tf.write(bootstrap)
++             tf.flush()
++ 
++             subprocess.check_call(['ruby', tf.name])
++ 
+++        tf.__exit__(0, 0, 0)
++     def install_macports(self):
++         url = MACPORTS_URL.get(self.minor_version, None)
++         if not url:
++@@ -386,12 +392,14 @@ class OSXBootstrapper(BaseBootstrapper):
++ 
++         print(PACKAGE_MANAGER_INSTALL % ('MacPorts', 'MacPorts', 'MacPorts', 'port'))
++         pkg = urlopen(url=url, timeout=300).read()
++-        with tempfile.NamedTemporaryFile(suffix='.pkg') as tf:
+++        tf = tempfile.NamedTemporaryFile(suffix='.pkg').__enter__()
+++        if 1:
++             tf.write(pkg)
++             tf.flush()
++ 
++             self.run_as_root(['installer', '-pkg', tf.name, '-target', '/'])
++ 
+++        tf.__exit__(0, 0, 0)
++     def _update_package_manager(self):
++         if self.package_manager == 'homebrew':
++             subprocess.check_call([self.brew, '-v', 'update'])
++@@ -406,7 +414,7 @@ class OSXBootstrapper(BaseBootstrapper):
++             try:
++                 subprocess.check_output([self.brew, '-v', 'upgrade', package],
++                     stderr=subprocess.STDOUT)
++-            except subprocess.CalledProcessError as e:
+++            except subprocess.CalledProcessError, e:
++                 if 'already installed' not in e.output:
++                     raise
++         else:
++diff -up comm-esr31/mozilla/python/mozbuild/dumbmake/dumbmake.py.python3 comm-esr31/mozilla/python/mozbuild/dumbmake/dumbmake.py
++--- comm-esr31/mozilla/python/mozbuild/dumbmake/dumbmake.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/dumbmake/dumbmake.py	2014-10-24 11:41:35.484880121 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ from collections import OrderedDict
++ from itertools import groupby
++diff -up comm-esr31/mozilla/python/mozbuild/dumbmake/test/test_dumbmake.py.python3 comm-esr31/mozilla/python/mozbuild/dumbmake/test/test_dumbmake.py
++--- comm-esr31/mozilla/python/mozbuild/dumbmake/test/test_dumbmake.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/dumbmake/test/test_dumbmake.py	2014-10-24 11:41:35.484880121 -0600
++@@ -1,7 +1,7 @@
++ # This Source Code Form is subject to the terms of the Mozilla Public
++ # License, v. 2.0. If a copy of the MPL was not distributed with this file,
++ # You can obtain one at http://mozilla.org/MPL/2.0/.
++-from __future__ import unicode_literals
+++
++ 
++ import unittest
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/action/buildlist.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/action/buildlist.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/action/buildlist.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/action/buildlist.py	2014-10-24 11:41:35.485880117 -0600
++@@ -7,7 +7,11 @@ if the entry does not already exist.
++ 
++ Usage: buildlist.py <filename> <entry> [<entry> ...]
++ '''
++-from __future__ import print_function
+++def print24(msg, file=None, end="\n"):
+++  if file:
+++    file.write(msg + end)
+++  else:
+++    sys.stdout.write(msg + end)
++ 
++ import sys
++ import os
++@@ -29,15 +33,17 @@ def addEntriesToListFile(listFile, entri
++     for e in entries:
++       if e not in existing:
++         existing.add(e)
++-    with open(listFile, 'w') as f:
+++    f = open(listFile, 'w')
+++    if 1:
++       f.write("\n".join(sorted(existing))+"\n")
+++    f.close()
++   finally:
++     lock = None
++ 
++ 
++ def main(args):
++     if len(args) < 2:
++-        print("Usage: buildlist.py <list file> <entry> [<entry> ...]",
+++        print24("Usage: buildlist.py <list file> <entry> [<entry> ...]",
++             file=sys.stderr)
++         return 1
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/action/cl.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/action/cl.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/action/cl.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/action/cl.py	2014-10-24 11:41:35.485880117 -0600
++@@ -110,9 +110,11 @@ def InvokeClWithDependencyGeneration(cmd
++                  # cost of masking failure to create the directory.  We'll just
++                  # die on the next line though, so it's not that much of a loss.
++ 
++-    with open(depstarget, "w") as f:
+++    f = open(depstarget, "w")
+++    if 1:
++         mk.dump(f)
++ 
+++    f.close()
++     return 0
++ 
++ def main(args):
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/action/link_deps.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/action/link_deps.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/action/link_deps.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/action/link_deps.py	2014-10-24 11:41:35.485880117 -0600
++@@ -1,3 +1,57 @@
+++# relpath
+++import os, sys
+++# Creates os.path.relpath for Python 2.4
+++
+++if not hasattr(os, "relpath"):
+++    if os.path is sys.modules.get("ntpath"):
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++            if start_list[0].lower() != path_list[0].lower():
+++                unc_path, rest = os.path.splitunc(path)
+++                unc_start, rest = os.path.splitunc(start)
+++                if bool(unc_path) ^ bool(unc_start):
+++                    raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
+++                                                                        % (path, start))
+++                else:
+++                    raise ValueError("path is on drive %s, start on drive %s"
+++                                                        % (path_list[0], start_list[0]))
+++            # Work out how much of the filepath is shared by start and path.
+++            for i in range(min(len(start_list), len(path_list))):
+++                if start_list[i].lower() != path_list[i].lower():
+++                    break
+++            else:
+++                i += 1
+++ 
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++    
+++    else:
+++        # default to posixpath definition
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++        
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++        
+++            # Work out how much of the filepath is shared by start and path.
+++            i = len(os.path.commonprefix([start_list, path_list]))
+++        
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++        
+++    os.path.relpath = relpath
++ # This Source Code Form is subject to the terms of the Mozilla Public
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++@@ -68,7 +122,7 @@ build/binaries.
++ import argparse
++ import os
++ import sys
++-from collections import OrderedDict
+++from mycollections import OrderedDict
++ from mozbuild.makeutil import (
++     Makefile,
++     read_dep_makefile,
++@@ -140,7 +194,14 @@ class DependencyLinker(Makefile):
++             if self._group == Grouping.BY_DEPFILE:
++                 if depfile not in rules:
++                     rules[depfile] = self.create_rule([depfile])
++-                rules[depfile].add_dependencies(d if d not in self._targets else self._targets[d][0] for d in deps)
+++                my_deps = []
+++                for d in deps:
+++                  if d not in self._targets:
+++                    my_deps.append(d)
+++                  else:
+++                    my_deps.append(self._targets[d][0])
+++                rules[depfile].add_dependencies(my_deps)
+++                #rules[depfile].add_dependencies(dd not in self._targets = (self._targets[d][0] for d in deps), )[]
++             elif self._group == Grouping.ALL_TARGETS:
++                 if 'all' not in rules:
++                     rules['all'] = self.create_rule()
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/action/process_install_manifest.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/action/process_install_manifest.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/action/process_install_manifest.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/action/process_install_manifest.py	2014-10-24 11:41:35.485880117 -0600
++@@ -2,7 +2,11 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ import argparse
++ import sys
++@@ -10,8 +14,8 @@ from mozpack.copier import FileCopier
++ from mozpack.manifests import InstallManifest
++ 
++ 
++-COMPLETE = 'From {dest}: Kept {existing} existing; Added/updated {updated}; ' \
++-    'Removed {rm_files} files and {rm_dirs} directories.'
+++COMPLETE = 'From %(dest)s: Kept %(existing)s existing; Added/updated %(updated)s; ' \
+++    'Removed %(rm_files)s files and %(rm_dirs)s directories.'
++ 
++ 
++ def process_manifest(destdir, paths,
++@@ -49,12 +53,19 @@ def main(argv):
++         remove_unaccounted=not args.no_remove,
++         remove_all_directory_symlinks=not args.no_remove_all_directory_symlinks,
++         remove_empty_directories=not args.no_remove_empty_directories)
++-
++-    print(COMPLETE.format(dest=args.destdir,
+++    parms = dict()
+++    parms = {"dest":args.destdir,
+++        "existing" : result.existing_files_count,
+++        "updated" : result.updated_files_count,
+++        "rm_files" : result.removed_files_count,
+++        "rm_dirs" : result.removed_directories_count}
+++    
+++    #print(COMPLETE % parms)
+++    '''(dest=args.destdir,
++         existing=result.existing_files_count,
++         updated=result.updated_files_count,
++         rm_files=result.removed_files_count,
++         rm_dirs=result.removed_directories_count))
++-
+++    '''
++ if __name__ == '__main__':
++     main(sys.argv[1:])
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/action/xpidl-process.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/action/xpidl-process.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/action/xpidl-process.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/action/xpidl-process.py	2014-10-24 11:41:35.485880117 -0600
++@@ -11,7 +11,7 @@ import argparse
++ import os
++ import sys
++ 
++-from io import BytesIO
+++from StringIO import StringIO as BytesIO
++ 
++ from buildconfig import topsrcdir
++ from header import print_header
++@@ -52,19 +52,23 @@ def process(input_dir, inc_paths, cache_
++ 
++         rule.add_dependencies(idl.deps)
++ 
++-        with FileAvoidWrite(header_path) as fh:
+++        fh = FileAvoidWrite(header_path).__enter__()
+++        if 1:
++             print_header(idl, fh, path)
++ 
+++        fh.__exit__(0, 0, 0)
++     # TODO use FileAvoidWrite once it supports binary mode.
++     xpt_path = os.path.join(xpt_dir, '%s.xpt' % module)
++     xpt_link(xpts.values()).write(xpt_path)
++ 
++     rule.add_targets([xpt_path])
++     deps_path = os.path.join(deps_dir, '%s.pp' % module)
++-    with FileAvoidWrite(deps_path) as fh:
+++    fh = FileAvoidWrite(deps_path).__enter__()
+++    if 1:
++         mk.dump(fh)
++ 
++ 
+++    fh.__exit__(0, 0, 0)
++ def main(argv):
++     parser = argparse.ArgumentParser()
++     parser.add_argument('--cache-dir',
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/backend/android_eclipse.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/backend/android_eclipse.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/backend/android_eclipse.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/backend/android_eclipse.py	2014-10-24 11:41:35.486880112 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import itertools
++ import os
++@@ -16,7 +16,7 @@ from mozpack.files import (FileFinder, P
++ from mozpack.manifests import InstallManifest
++ import mozpack.path as mozpath
++ 
++-from .common import CommonBackend
+++from common import CommonBackend
++ from ..frontend.data import (
++     AndroidEclipseProjectData,
++     SandboxDerived,
++@@ -228,7 +228,7 @@ class AndroidEclipseBackend(CommonBacken
++         defines['IDE_CLASSPATH_ENTRIES'] = '\n'.join('\t' + cpe for cpe in classpathentries)
++         defines['IDE_RECURSIVE_MAKE_TARGETS'] = ' '.join(sorted(data.recursive_make_targets))
++         # Like android.library=true
++-        defines['IDE_PROJECT_LIBRARY_SETTING'] = 'android.library=true' if data.is_library else ''
+++        defines['IDE_PROJECT_LIBRARY_SETTING'] = ('', 'android.library=true')[data.is_library]
++         # Like android.library.reference.1=FennecBrandingResources
++         defines['IDE_PROJECT_LIBRARY_REFERENCES'] = '\n'.join(
++             'android.library.reference.%s=%s' % (i + 1, ref)
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/backend/base.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/backend/base.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/backend/base.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/backend/base.py	2014-10-24 11:41:35.486880112 -0600
++@@ -1,8 +1,62 @@
+++# relpath
+++import os, sys
+++# Creates os.path.relpath for Python 2.4
+++
+++if not hasattr(os, "relpath"):
+++    if os.path is sys.modules.get("ntpath"):
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++            if start_list[0].lower() != path_list[0].lower():
+++                unc_path, rest = os.path.splitunc(path)
+++                unc_start, rest = os.path.splitunc(start)
+++                if bool(unc_path) ^ bool(unc_start):
+++                    raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
+++                                                                        % (path, start))
+++                else:
+++                    raise ValueError("path is on drive %s, start on drive %s"
+++                                                        % (path_list[0], start_list[0]))
+++            # Work out how much of the filepath is shared by start and path.
+++            for i in range(min(len(start_list), len(path_list))):
+++                if start_list[i].lower() != path_list[i].lower():
+++                    break
+++            else:
+++                i += 1
+++ 
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++    
+++    else:
+++        # default to posixpath definition
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++        
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++        
+++            # Work out how much of the filepath is shared by start and path.
+++            i = len(os.path.commonprefix([start_list, path_list]))
+++        
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++        
+++    os.path.relpath = relpath
++ # This Source Code Form is subject to the terms of the Mozilla Public
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ from abc import (
++     ABCMeta,
++@@ -13,20 +67,21 @@ import errno
++ import os
++ import time
++ 
++-from contextlib import contextmanager
+++
++ 
++ from mach.mixin.logging import LoggingMixin
++ 
++ import mozpack.path as mozpath
++-from ..preprocessor import Preprocessor
++-from ..pythonutil import iter_modules_in_path
++-from ..util import FileAvoidWrite
++-from ..frontend.data import (
+++from preprocessor import Preprocessor
+++from pythonutil import iter_modules_in_path
+++from util import FileAvoidWrite
+++from frontend.data import (
++     ReaderSummary,
++     SandboxDerived,
++ )
++-from .configenvironment import ConfigEnvironment
+++from configenvironment import ConfigEnvironment
++ import mozpack.path as mozpath
+++from contextdecorator import contextmanager
++ 
++ 
++ class BackendConsumeSummary(object):
++@@ -83,18 +138,18 @@ class BackendConsumeSummary(object):
++ 
++     @property
++     def reader_summary(self):
++-        return 'Finished reading {:d} moz.build files in {:.2f}s'.format(
+++        return 'Finished reading %d moz.build files in %fs' % (
++             self.mozbuild_count,
++             self.mozbuild_execution_time)
++ 
++     @property
++     def emitter_summary(self):
++-        return 'Processed into {:d} build config descriptors in {:.2f}s'.format(
+++        return 'Processed into %d build config descriptors in %fs' % (
++             self.object_count, self.emitter_execution_time)
++ 
++     @property
++     def backend_summary(self):
++-        return 'Backend executed in {:.2f}s'.format(self.backend_execution_time)
+++        return 'Backend executed in %fs' % (self.backend_execution_time)
++ 
++     def backend_detailed_summary(self):
++         """Backend summary to be supplied by BuildBackend implementations."""
++@@ -102,9 +157,13 @@ class BackendConsumeSummary(object):
++ 
++     @property
++     def total_summary(self):
++-        efficiency_value = self.cpu_time / self.wall_time if self.wall_time else 100
++-        return 'Total wall time: {:.2f}s; CPU time: {:.2f}s; Efficiency: ' \
++-            '{:.0%}; Untracked: {:.2f}s'.format(
+++        efficiency_value = None
+++        if self.wall_time:
+++          efficiency_value = self.cpu_time / self.wall_time
+++        else:
+++          efficiency_value = 100
+++        return 'Total wall time: %.2fs; CPU time: %.2fs; Efficiency: ' \
+++            '%.0f; Untracked: %.2fs' % (
++                 self.wall_time, self.cpu_time, efficiency_value,
++                 self.other_time)
++ 
++@@ -179,11 +238,13 @@ class BuildBackend(LoggingMixin):
++         base class consumes objects and calls methods (possibly) implemented by
++         child classes.
++         """
+++        #print objs
++         cpu_start = time.clock()
++         time_start = time.time()
++         backend_time = 0.0
++ 
++         for obj in objs:
+++            #print self, obj, obj._ack
++             self.summary.object_count += 1
++             obj_start = time.time()
++             self.consume_object(obj)
++@@ -219,12 +280,16 @@ class BuildBackend(LoggingMixin):
++         # Write out the list of backend files generated, if it changed.
++         if self.summary.deleted_count or self.summary.created_count or \
++                 not os.path.exists(self._backend_output_list_file):
++-            with open(self._backend_output_list_file, 'w') as fh:
+++            fh = open(self._backend_output_list_file, 'w')
+++            if 1:
++                 fh.write('\n'.join(sorted(self._backend_output_files)))
+++            fh.__exit__(0, 0, 0)
++         elif self.summary.updated_count:
++-            with open(self._backend_output_list_file, 'a'):
+++            open(self._backend_output_list_file, 'a').__enter__()
+++            if 1:
++                 os.utime(self._backend_output_list_file, None)
++ 
+++            open(self._backend_output_list_file, 'a').__exit__(0, 0, 0)
++         self.summary.cpu_time = time.clock() - cpu_start
++         self.summary.wall_time = time.time() - time_start
++         self.summary.backend_execution_time = backend_time
++@@ -255,8 +320,10 @@ class BuildBackend(LoggingMixin):
++ 
++         Example usage:
++ 
++-            with self._write_file('foo.txt') as fh:
+++            fh = self._write_file('foo.txt').__enter__()
+++            if 1:
++                 fh.write('hello world')
+++            fh.close()
++         """
++ 
++         if path is not None:
++@@ -268,12 +335,13 @@ class BuildBackend(LoggingMixin):
++         dirname = mozpath.dirname(fh.name)
++         try:
++             os.makedirs(dirname)
++-        except OSError as error:
+++        except OSError, error:
++             if error.errno != errno.EEXIST:
++                 raise
++ 
+++        #print "preYIELD"
++         yield fh
++-
+++        #print "Ceka na yield?"
++         self._backend_output_files.add(mozpath.relpath(fh.name, self.environment.topobjdir))
++         existed, updated = fh.close()
++         if not existed:
++@@ -301,6 +369,9 @@ class BuildBackend(LoggingMixin):
++         )
++         pp.do_filter('attemptSubstitution')
++         pp.setMarker(None)
++-        with self._write_file(obj.output_path) as fh:
+++        fh = self._write_file(obj.output_path).__enter__()
+++        if 1:
++             pp.out = fh
++             yield pp
+++        fh.__exit__(0, 0, 0)
+++
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/backend/common.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/backend/common.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/backend/common.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/backend/common.py	2014-10-24 11:41:35.486880112 -0600
++@@ -1,18 +1,72 @@
+++# relpath
+++import os, sys
+++# Creates os.path.relpath for Python 2.4
+++
+++if not hasattr(os, "relpath"):
+++    if os.path is sys.modules.get("ntpath"):
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++            if start_list[0].lower() != path_list[0].lower():
+++                unc_path, rest = os.path.splitunc(path)
+++                unc_start, rest = os.path.splitunc(start)
+++                if bool(unc_path) ^ bool(unc_start):
+++                    raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
+++                                                                        % (path, start))
+++                else:
+++                    raise ValueError("path is on drive %s, start on drive %s"
+++                                                        % (path_list[0], start_list[0]))
+++            # Work out how much of the filepath is shared by start and path.
+++            for i in range(min(len(start_list), len(path_list))):
+++                if start_list[i].lower() != path_list[i].lower():
+++                    break
+++            else:
+++                i += 1
+++ 
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++    
+++    else:
+++        # default to posixpath definition
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++        
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++        
+++            # Work out how much of the filepath is shared by start and path.
+++            i = len(os.path.commonprefix([start_list, path_list]))
+++        
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++        
+++    os.path.relpath = relpath
++ # This Source Code Form is subject to the terms of the Mozilla Public
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
++ 
++-import json
+++
+++import simplejson as json
++ import os
++ import re
++ 
++ import mozpack.path as mozpath
++ 
++-from .base import BuildBackend
+++from base import BuildBackend
++ 
++-from ..frontend.data import (
+++from mozbuild.frontend.data import (
++     ConfigFileSubstitution,
++     ExampleWebIDLInterface,
++     HeaderFileSubstitution,
++@@ -26,7 +80,7 @@ from ..frontend.data import (
++     WebIDLFile,
++ )
++ 
++-from ..util import DefaultOnReadDict
+++from util import DefaultOnReadDict
++ 
++ 
++ class XPIDLManager(object):
++@@ -188,8 +242,10 @@ class CommonBackend(BuildBackend):
++             # to other
++             if mozpath.basename(obj.output_path) == 'Makefile':
++                 return
++-            with self._get_preprocessor(obj) as pp:
+++            pp = self._get_preprocessor(obj).__enter__()
+++            if 1:
++                 pp.do_include(obj.input_path)
+++            pp.out.close() #__exit__(0, 0, 0)
++             self.backend_input_files.add(obj.input_path)
++ 
++         elif isinstance(obj, HeaderFileSubstitution):
++@@ -239,10 +295,13 @@ class CommonBackend(BuildBackend):
++ 
++         # Write out a machine-readable file describing every test.
++         path = mozpath.join(self.environment.topobjdir, 'all-tests.json')
++-        with self._write_file(path) as fh:
+++        fh = file(path, "w")
+++        #fh = self._write_file(path)
+++        if 1:
++             json.dump(self._test_manager.tests_by_path, fh, sort_keys=True,
++                 indent=2)
++ 
+++        fh.close()
++     def _create_config_header(self, obj):
++         '''Creates the given config header. A config header is generated by
++         taking the corresponding source file and replacing some #define/#undef
++@@ -253,8 +312,11 @@ class CommonBackend(BuildBackend):
++             "#undef UNKNOWN_NAME" is turned into "/* #undef UNKNOWN_NAME */"
++             Whitespaces are preserved.
++         '''
++-        with self._write_file(obj.output_path) as fh, \
++-             open(obj.input_path, 'rU') as input:
+++        fh = self._write_file(obj.output_path).__enter__()
+++        input = open(obj.input_path, 'rU') 
+++        if 1:
+++        #with self._write_file(obj.output_path) as fh, \
+++        #     open(obj.input_path, 'rU') as input:
++             r = re.compile('^\s*#\s*(?P<cmd>[a-z]+)(?:\s+(?P<name>\S+)(?:\s+(?P<value>\S+))?)?', re.U)
++             for l in input:
++                 m = r.match(l)
++@@ -277,5 +339,7 @@ class CommonBackend(BuildBackend):
++                                     + l[m.end('name'):]
++                         elif cmd == 'undef':
++                            l = '/* ' + l[:m.end('name')] + ' */' + l[m.end('name'):]
++-
+++                #print dir(fh)
++                 fh.write(l)
+++        fh.close() #__exit__(None, None, None)
+++        input.close()
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/backend/configenvironment.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/backend/configenvironment.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/backend/configenvironment.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/backend/configenvironment.py	2014-10-24 11:41:35.486880112 -0600
++@@ -4,21 +4,22 @@
++ 
++ import sys
++ 
++-from collections import Iterable
+++from rhrebase import isIterable
+++#from collections import Iterable
++ from types import StringTypes
++ 
++ import mozpack.path as mozpath
++ 
++-from ..util import (
+++from util import (
++     ReadOnlyDict,
++     shell_quote,
++ )
++ 
++ 
++-if sys.version_info.major == 2:
++-    text_type = unicode
++-else:
++-    text_type = str
+++#if sys.version_info.major == 2:
+++text_type = str
+++#else:
+++text_type = str
++ 
++ 
++ class BuildConfig(object):
++@@ -36,9 +37,10 @@ class BuildConfig(object):
++     def from_config_status(path):
++         """Create an instance from a config.status file."""
++ 
++-        with open(path, 'rt') as fh:
+++        fh = open(path, 'rt')
+++        if 1:
++             source = fh.read()
++-            code = compile(source, path, 'exec', dont_inherit=1)
+++            code = compile(source, path, 'exec', 0, 1)
++             g = {
++                 '__builtins__': __builtins__,
++                 '__file__': path,
++@@ -51,7 +53,8 @@ class BuildConfig(object):
++             for name in l['__all__']:
++                 setattr(config, name, l[name])
++ 
++-            return config
+++        fh.close()
+++        return config
++ 
++ 
++ class ConfigEnvironment(object):
++@@ -115,7 +118,7 @@ class ConfigEnvironment(object):
++         def serialize(obj):
++             if isinstance(obj, StringTypes):
++                 return obj
++-            if isinstance(obj, Iterable):
+++            if isIterable(obj):
++                 return ' '.join(obj)
++             raise Exception('Unhandled type %s', type(obj))
++         self.substs['ALLSUBSTS'] = '\n'.join(sorted(['%s = %s' % (name,
++@@ -143,7 +146,7 @@ class ConfigEnvironment(object):
++ 
++         for k, v in self.substs.items():
++             if not isinstance(v, StringTypes):
++-                if isinstance(v, Iterable):
+++                if isIterable(v):
++                     type(v)(decode(i) for i in v)
++             elif not isinstance(v, text_type):
++                 v = decode(v)
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/backend/cpp_eclipse.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/backend/cpp_eclipse.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/backend/cpp_eclipse.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/backend/cpp_eclipse.py	2014-10-24 11:41:35.487880108 -0600
++@@ -7,7 +7,7 @@ import errno
++ import types
++ import os
++ import xml.etree.ElementTree as ET
++-from .common import CommonBackend
+++from common import CommonBackend
++ 
++ from ..frontend.data import (
++     Defines,
++@@ -67,40 +67,52 @@ class CppEclipseBackend(CommonBackend):
++         for dir_name in [self._project_dir, settings_dir, launch_dir, workspace_settings_dir, workspace_language_dir]:
++             try:
++                 os.makedirs(dir_name)
++-            except OSError as e:
+++            except OSError, e:
++                 if e.errno != errno.EEXIST:
++                     raise
++ 
++         project_path = os.path.join(self._project_dir, '.project')
++-        with open(project_path, 'wb') as fh:
+++        fh = open(project_path, 'wb')
+++        if 1:
++             self._write_project(fh)
++ 
+++        fh.close()
++         cproject_path = os.path.join(self._project_dir, '.cproject')
++-        with open(cproject_path, 'wb') as fh:
+++        fh = open(cproject_path, 'wb')
+++        if 1:
++             self._write_cproject(fh)
++ 
+++        fh.close()
++         language_path = os.path.join(settings_dir, 'language.settings.xml')
++-        with open(language_path, 'wb') as fh:
+++        fh = open(language_path, 'wb')
+++        if 1:
++             self._write_language_settings(fh)
++ 
+++        fh.close()
++         workspace_language_path = os.path.join(workspace_language_dir, 'language.settings.xml')
++-        with open(workspace_language_path, 'wb') as fh:
+++        fh = open(workspace_language_path, 'wb')
+++        if 1:
++             workspace_lang_settings = WORKSPACE_LANGUAGE_SETTINGS_TEMPLATE
++             workspace_lang_settings = workspace_lang_settings.replace("@COMPILER_FLAGS@", self._cxx + " " + self._cppflags);
++             fh.write(workspace_lang_settings)
++ 
+++        fh.close()
++         self._write_launch_files(launch_dir)
++ 
++         # This will show up as an 'unmanged' formatter. This can be named by generating
++         # another file.
++         formatter_prefs_path = os.path.join(settings_dir, 'org.eclipse.cdt.core.prefs')
++-        with open(formatter_prefs_path, 'wb') as fh:
+++        fh = open(formatter_prefs_path, 'wb')
+++        if 1:
++             fh.write(FORMATTER_SETTINGS);
++ 
+++        fh.close()
++         editor_prefs_path = os.path.join(workspace_settings_dir, "org.eclipse.ui.editors.prefs");
++-        with open(editor_prefs_path, 'wb') as fh:
+++        fh = open(editor_prefs_path, 'wb')
+++        if 1:
++             fh.write(EDITOR_SETTINGS);
++ 
+++        fh.close()
++     def _define_entry(self, name, value):
++         define = ET.Element('entry')
++         define.set('kind', 'macro')
++@@ -134,15 +146,18 @@ class CppEclipseBackend(CommonBackend):
++ 
++         if self.environment.substs['MOZ_WIDGET_TOOLKIT'] != 'gonk':
++             main_gecko_launch = os.path.join(launch_dir, 'gecko.launch')
++-            with open(main_gecko_launch, 'wb') as fh:
+++            fh = open(main_gecko_launch, 'wb')
+++            if 1:
++                 launch = GECKO_LAUNCH_CONFIG_TEMPLATE
++                 launch = launch.replace('@LAUNCH_PROGRAM@', exe_path)
++                 launch = launch.replace('@LAUNCH_ARGS@', '-P -no-remote')
++                 fh.write(launch)
++ 
+++            fh.close()
++         if self.environment.substs['MOZ_WIDGET_TOOLKIT'] == 'gonk':
++             b2g_flash = os.path.join(launch_dir, 'b2g-flash.launch')
++-            with open(b2g_flash, 'wb') as fh:
+++            fh = open(b2g_flash, 'wb')
+++            if 1:
++                 # We assume that the srcdir is inside the b2g tree.
++                 # If that's not the case the user can always adjust the path
++                 # from the eclipse IDE.
++@@ -152,6 +167,7 @@ class CppEclipseBackend(CommonBackend):
++                 launch = launch.replace('@OBJDIR@', self.environment.topobjdir)
++                 fh.write(launch)
++ 
+++            fh.close()
++         #TODO Add more launch configs (and delegate calls to mach)
++ 
++     def _write_project(self, fh):
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/backend/recursivemake.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/backend/recursivemake.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/backend/recursivemake.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/backend/recursivemake.py	2014-10-24 11:41:35.487880108 -0600
++@@ -1,16 +1,106 @@
+++# relpath
+++import os, sys
+++# Creates os.path.relpath for Python 2.4
+++
+++if not hasattr(os, "relpath"):
+++    if os.path is sys.modules.get("ntpath"):
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++            if start_list[0].lower() != path_list[0].lower():
+++                unc_path, rest = os.path.splitunc(path)
+++                unc_start, rest = os.path.splitunc(start)
+++                if bool(unc_path) ^ bool(unc_start):
+++                    raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
+++                                                                        % (path, start))
+++                else:
+++                    raise ValueError("path is on drive %s, start on drive %s"
+++                                                        % (path_list[0], start_list[0]))
+++            # Work out how much of the filepath is shared by start and path.
+++            for i in range(min(len(start_list), len(path_list))):
+++                if start_list[i].lower() != path_list[i].lower():
+++                    break
+++            else:
+++                i += 1
+++ 
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++    
+++    else:
+++        # default to posixpath definition
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++        
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++        
+++            # Work out how much of the filepath is shared by start and path.
+++            i = len(os.path.commonprefix([start_list, path_list]))
+++        
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++        
+++    os.path.relpath = relpath
++ # This Source Code Form is subject to the terms of the Mozilla Public
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++class ZipExhausted(Exception):
+++    pass
+++
+++def next(iter):
+++  return iter.next()
+++
+++def izip_longest(*args, **kwds):
+++    # izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
+++    fillvalue = kwds.get('fillvalue')
+++    counter = [len(args) - 1]
+++    def sentinel():
+++        if not counter[0]:
+++            raise ZipExhausted
+++        counter[0] -= 1
+++        yield fillvalue
+++    fillers = repeat(fillvalue)
+++    iterators = [chain(it, sentinel(), fillers) for it in args]
+++    try:
+++        while iterators:
+++            yield tuple(map(next, iterators))
+++    except ZipExhausted:
+++        pass
+++
+++def repeat(object, times=None):
+++    # repeat(10, 3) --> 10 10 10
+++    if times is None:
+++        while True:
+++            yield object
+++    else:
+++        for i in xrange(times):
+++            yield object
+++
+++def chain(*iterables):
+++    # chain('ABC', 'DEF') --> A B C D E F
+++    for it in iterables:
+++        for element in it:
+++            yield element
++ 
++ import itertools
++-import json
+++import simplejson as json
++ import logging
++ import os
++ import types
++ 
++-from collections import namedtuple
+++from namedtuple import namedtuple
++ 
++ import mozwebidlcodegen
++ 
++@@ -21,8 +111,8 @@ from mozpack.manifests import (
++ )
++ import mozpack.path as mozpath
++ 
++-from .common import CommonBackend
++-from ..frontend.data import (
+++from common import CommonBackend
+++from mozbuild.frontend.data import (
++     AndroidEclipseProjectData,
++     ConfigFileSubstitution,
++     Defines,
++@@ -47,11 +137,11 @@ from ..frontend.data import (
++     VariablePassthru,
++     XPIDLFile,
++ )
++-from ..util import (
+++from util import (
++     ensureParentDir,
++     FileAvoidWrite,
++ )
++-from ..makeutil import Makefile
+++from makeutil import Makefile
++ 
++ class BackendMakeFile(object):
++     """Represents a generated backend.mk file.
++@@ -190,8 +280,7 @@ class RecursiveMakeTraversal(object):
++         where current is the directory being traversed, and subdirs the
++         SubDirectories instance corresponding to it.
++         The filter function returns a tuple (filtered_current, filtered_parallel,
++-        filtered_dirs) where filtered_current is either current or None if
++-        the current directory is to be skipped, and filtered_parallel and
+++        filtered_dirs) where filtered_current is either current or None if the current directory is to be skipped, and filtered_parallel and
++         filtered_dirs are lists of parallel directories and sequential
++         directories, which can be rearranged from whatever is given in the
++         SubDirectories members.
++@@ -272,9 +361,9 @@ class RecursiveMakeBackend(CommonBackend
++         self._ipdl_sources = set()
++ 
++         def detailed(summary):
++-            s = '{:d} total backend files; ' \
++-                '{:d} created; {:d} updated; {:d} unchanged; ' \
++-                '{:d} deleted; {:d} -> {:d} Makefile'.format(
+++            s = '%d total backend files; ' \
+++                '%d created; %d updated; %d unchanged; ' \
+++                '%d deleted; %d -> %d Makefile' % (
++                 summary.created_count + summary.updated_count +
++                 summary.unchanged_count,
++                 summary.created_count,
++@@ -297,6 +386,18 @@ class RecursiveMakeBackend(CommonBackend
++         self.backend_input_files.add(mozpath.join(self.environment.topobjdir,
++             'config', 'autoconf.mk'))
++ 
+++        self._install_manifests = {}
+++        for k in [
+++                'dist_bin',
+++                'dist_idl',
+++                'dist_include',
+++                'dist_public',
+++                'dist_private',
+++                'dist_sdk',
+++                'tests',
+++                'xpidl']:
+++          self._install_manifests[k] = InstallManifest()
+++        ''' 
++         self._install_manifests = {
++             k: InstallManifest() for k in [
++                 'dist_bin',
++@@ -308,7 +409,7 @@ class RecursiveMakeBackend(CommonBackend
++                 'tests',
++                 'xpidl',
++             ]}
++-
+++        '''
++         self._traversal = RecursiveMakeTraversal()
++         self._may_skip = {
++             'export': set(),
++@@ -330,7 +431,7 @@ class RecursiveMakeBackend(CommonBackend
++ 
++         if not isinstance(obj, SandboxDerived):
++             return
++-
+++        #print "consume obj", obj
++         if obj.objdir not in self._backend_files:
++             self._backend_files[obj.objdir] = \
++                 BackendMakeFile(obj.srcdir, obj.objdir, obj.config)
++@@ -348,8 +449,10 @@ class RecursiveMakeBackend(CommonBackend
++             self._process_test_manifest(obj, backend_file)
++ 
++         # If CommonBackend acknowledged the object, we're done with it.
+++        #print "pre ack", obj
++         if obj._ack:
++             return
+++        #print "post ack", obj
++ 
++         if isinstance(obj, DirectoryTraversal):
++             self._process_directory_traversal(obj, backend_file)
++@@ -466,7 +569,9 @@ class RecursiveMakeBackend(CommonBackend
++             self._process_library_definition(obj, backend_file)
++ 
++         else:
+++            #print "wasn't ack", obj
++             return
+++        #print "acking"
++         obj.ack()
++ 
++     def _fill_root_mk(self):
++@@ -479,7 +584,7 @@ class RecursiveMakeBackend(CommonBackend
++             for tier, skip in self._may_skip.items():
++                 self.log(logging.DEBUG, 'fill_root_mk', {
++                     'number': len(skip), 'tier': tier
++-                    }, 'Ignoring {number} directories during {tier}')
+++                    }, 'Ignoring %(number)d directories during %(tier)s')
++ 
++         # Traverse directories in parallel, and skip static dirs
++         def parallel_filter(current, subdirs):
++@@ -589,14 +694,16 @@ class RecursiveMakeBackend(CommonBackend
++ 
++         root_mk.add_statement('$(call include_deps,root-deps.mk)')
++ 
++-        with self._write_file(
++-                mozpath.join(self.environment.topobjdir, 'root.mk')) as root:
+++        root = self._write_file( mozpath.join(self.environment.topobjdir, 'root.mk')).__enter__()
+++        if 1:
++             root_mk.dump(root, removal_guard=False)
++ 
++-        with self._write_file(
++-                mozpath.join(self.environment.topobjdir, 'root-deps.mk')) as root_deps:
+++        root.__exit__(0, 0, 0)
+++        root_deps = self._write_file( mozpath.join(self.environment.topobjdir, 'root-deps.mk')).__enter__()
+++        if 1:
++             root_deps_mk.dump(root_deps, removal_guard=False)
++ 
+++        root_deps.__exit__(0, 0, 0)
++     def _add_unified_build_rules(self, makefile, files, output_directory,
++                                  unified_prefix='Unified',
++                                  unified_suffix='cpp',
++@@ -631,14 +738,17 @@ class RecursiveMakeBackend(CommonBackend
++             def grouper(n, iterable):
++                 "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
++                 args = [iter(iterable)] * n
++-                return itertools.izip_longest(fillvalue=dummy_fill_value, *args)
+++                #return itertools.izip_longest(fillvalue=dummy_fill_value, *args)
+++                #return itertools.izip(fillvalue=dummy_fill_value, *args)
+++                return izip_longest(fillvalue=dummy_fill_value, *args)
++ 
++             for i, unified_group in enumerate(grouper(files_per_unified_file,
++                                                       files)):
++                 just_the_filenames = list(filter_out_dummy(unified_group))
++                 yield '%s%d.%s' % (unified_prefix, i, unified_suffix), just_the_filenames
++ 
++-        all_sources = ' '.join(source for source, _ in unified_files())
+++        my_unified_files = [f for f in unified_files()]
+++        all_sources = ' '.join(source for source, _ in my_unified_files)
++         makefile.add_statement('%s := %s' % (unified_files_makefile_variable,
++                                                all_sources))
++ 
++@@ -651,7 +761,8 @@ class RecursiveMakeBackend(CommonBackend
++             # blown away and we need to regenerate them.  The rule doesn't correctly
++             # handle source files being added/removed/renamed.  Therefore, we
++             # generate them here also to make sure everything's up-to-date.
++-            with self._write_file(mozpath.join(output_directory, unified_file)) as f:
+++            f = self._write_file(mozpath.join(output_directory, unified_file)).__enter__()
+++            if 1:
++                 f.write('#define MOZ_UNIFIED_BUILD\n')
++                 includeTemplate = '#include "%(cppfile)s"'
++                 if poison_windows_h:
++@@ -680,6 +791,7 @@ class RecursiveMakeBackend(CommonBackend
++                 f.write('\n'.join(includeTemplate % { "cppfile": s } for
++                                   s in source_filenames))
++ 
+++            f.close() #f.__exit__(0, 0, 0)
++         if include_curdir_build_rules:
++             makefile.add_statement('\n'
++                 '# Make sometimes gets confused between "foo" and "$(CURDIR)/foo".\n'
++@@ -695,7 +807,8 @@ class RecursiveMakeBackend(CommonBackend
++ 
++         for objdir, backend_file in sorted(self._backend_files.items()):
++             srcdir = backend_file.srcdir
++-            with self._write_file(fh=backend_file) as bf:
+++            bf = self._write_file(fh=backend_file).__enter__()
+++            if 1:
++                 makefile_in = mozpath.join(srcdir, 'Makefile.in')
++                 makefile = mozpath.join(objdir, 'Makefile')
++ 
++@@ -724,6 +837,7 @@ class RecursiveMakeBackend(CommonBackend
++                 obj.config = bf.environment
++                 self._create_makefile(obj, stub=stub)
++ 
+++            bf.close()
++         # Write out a master list of all IPDL source files.
++         ipdl_dir = mozpath.join(self.environment.topobjdir, 'ipc', 'ipdl')
++         mk = mozmakeutil.Makefile()
++@@ -751,15 +865,27 @@ class RecursiveMakeBackend(CommonBackend
++         mk.add_statement('IPDLDIRS := %s' % ' '.join(sorted(set(mozpath.dirname(p)
++             for p in self._ipdl_sources))))
++ 
++-        with self._write_file(mozpath.join(ipdl_dir, 'ipdlsrcs.mk')) as ipdls:
+++        ipdls = self._write_file(mozpath.join(ipdl_dir, 'ipdlsrcs.mk')).__enter__()
+++        #ipdls = file(mozpath.join(ipdl_dir, 'ipdlsrcs.mk'), "w")
+++        if 1:
++             mk.dump(ipdls, removal_guard=False)
++ 
+++        ipdls.__exit__(0,0,0)
++         # These contain autogenerated sources that the build config doesn't
++         # yet know about.
++         # TODO Emit GENERATED_SOURCES so these special cases are dealt with
++         # the proper way.
++-        self._may_skip['compile'] -= {'ipc/ipdl'}
++-        self._may_skip['compile'] -= {'dom/bindings', 'dom/bindings/test'}
+++        #print self._may_skip['compile']
+++        if 'ipc/ipdl' in self._may_skip['compile']:
+++          self._may_skip['compile'].remove('ipc/ipdl')
+++        #print self._may_skip['compile']
+++        #self._may_skip['compile'] -= {'ipc/ipdl'}
+++        if 'dom/bindings' in self._may_skip['compile']:
+++          self._may_skip['compile'].remove('dom/bindings')
+++        if 'dom/bindings/test' in self._may_skip['compile']:
+++          self._may_skip['compile'].remove('dom/bindings/test')
+++        #print self._may_skip['compile']
+++        #self._may_skip['compile'] -= {'dom/bindings', 'dom/bindings/test'}
++ 
++         self._fill_root_mk()
++ 
++@@ -770,13 +896,16 @@ class RecursiveMakeBackend(CommonBackend
++         # We need to use $(DEPTH) so the target here matches what's in
++         # rules.mk. If they are different, the dependencies don't get pulled in
++         # properly.
++-        with self._write_file('%s.pp' % self._backend_output_list_file) as backend_deps:
+++        backend_deps = self._write_file('%s.pp' % self._backend_output_list_file).__enter__()
+++        if 1:
++             backend_deps.write('$(DEPTH)/backend.%s: %s\n' %
++                 (self.__class__.__name__, ' '.join(inputs)))
++             for path in inputs:
++                 backend_deps.write('%s:\n' % path)
++ 
++-        with open(self._backend_output_list_file, 'a'):
+++        backend_deps.__exit__(0, 0, 0)
+++        open(self._backend_output_list_file, 'a')
+++        if 1:
++             pass
++         os.utime(self._backend_output_list_file, None)
++ 
++@@ -1047,8 +1176,7 @@ class RecursiveMakeBackend(CommonBackend
++             obj.manifest_relpath))
++ 
++         # Don't allow files to be defined multiple times unless it is allowed.
++-        # We currently allow duplicates for non-test files or test files if
++-        # the manifest is listed as a duplicate.
+++        # We currently allow duplicates for non-test files or test files if # the manifest is listed as a duplicate.
++         for source, (dest, is_test) in obj.installs.items():
++             try:
++                 self._install_manifests['tests'].add_symlink(source, dest)
++@@ -1154,22 +1282,28 @@ class RecursiveMakeBackend(CommonBackend
++         # manifests are deleted.
++         purger = FilePurger()
++ 
+++        #print(manifests.items())
++         for k, manifest in manifests.items():
++             purger.add(k)
+++            fh = self._write_file(mozpath.join(man_dir, k)).__enter__()
+++            if 1:
+++               manifest.write(fileobj=fh)
+++            fh.close()
++ 
++-            with self._write_file(mozpath.join(man_dir, k)) as fh:
++-                manifest.write(fileobj=fh)
+++            #with self._write_file(mozpath.join(man_dir, k)) as fh:
+++            #    manifest.write(fileobj=fh)
++ 
++         purger.purge(man_dir)
++ 
++     def _write_master_test_manifest(self, path, manifests):
++-        with self._write_file(path) as master:
+++        master = self._write_file(path).__enter__()
+++        if 1:
++             master.write(
++                 '; THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT MODIFY BY HAND.\n\n')
++ 
++             for manifest in sorted(manifests):
++                 master.write('[include:%s]\n' % manifest)
++-
+++        master.__exit__(0, 0, 0)
++     class Substitution(object):
++         """BaseConfigSubstitution-like class for use with _create_makefile."""
++         __slots__ = (
++@@ -1188,24 +1322,26 @@ class RecursiveMakeBackend(CommonBackend
++         When the stub argument is True, no source file is used, and a stub
++         makefile with the default header and footer only is created.
++         '''
++-        with self._get_preprocessor(obj) as pp:
+++        pp = self._get_preprocessor(obj).__enter__()
+++        if 1:
++             if extra:
++                 pp.context.update(extra)
++             if not pp.context.get('autoconfmk', ''):
++                 pp.context['autoconfmk'] = 'autoconf.mk'
++-            pp.handleLine(b'# THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT MODIFY BY HAND.\n');
++-            pp.handleLine(b'DEPTH := @DEPTH@\n')
++-            pp.handleLine(b'topsrcdir := @top_srcdir@\n')
++-            pp.handleLine(b'srcdir := @srcdir@\n')
++-            pp.handleLine(b'VPATH := @srcdir@\n')
++-            pp.handleLine(b'relativesrcdir := @relativesrcdir@\n')
++-            pp.handleLine(b'include $(DEPTH)/config/@autoconfmk@\n')
+++            pp.handleLine('# THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT MODIFY BY HAND.\n');
+++            pp.handleLine('DEPTH := @DEPTH@\n')
+++            pp.handleLine('topsrcdir := @top_srcdir@\n')
+++            pp.handleLine('srcdir := @srcdir@\n')
+++            pp.handleLine('VPATH := @srcdir@\n')
+++            pp.handleLine('relativesrcdir := @relativesrcdir@\n')
+++            pp.handleLine('include $(DEPTH)/config/@autoconfmk@\n')
++             if not stub:
++                 pp.do_include(obj.input_path)
++             # Empty line to avoid failures when last line in Makefile.in ends
++             # with a backslash.
++-            pp.handleLine(b'\n')
++-            pp.handleLine(b'include $(topsrcdir)/config/recurse.mk\n')
+++            pp.handleLine('\n')
+++            pp.handleLine('include $(topsrcdir)/config/recurse.mk\n')
+++        pp.out.close()
++         if not stub:
++             # Adding the Makefile.in here has the desired side-effect
++             # that if the Makefile.in disappears, this will force
++@@ -1240,9 +1376,11 @@ class RecursiveMakeBackend(CommonBackend
++         )
++ 
++         file_lists = mozpath.join(bindings_dir, 'file-lists.json')
++-        with self._write_file(file_lists) as fh:
+++        fh = self._write_file(file_lists).__enter__()
+++        if 1:
++             json.dump(o, fh, sort_keys=True, indent=2)
++ 
+++        fh.close() #__exit__(0, 0, 0)
++         manager = mozwebidlcodegen.create_build_system_manager(
++             self.environment.topsrcdir,
++             self.environment.topobjdir,
++@@ -1297,5 +1435,8 @@ class RecursiveMakeBackend(CommonBackend
++             poison_windows_h=True)
++ 
++         webidls_mk = mozpath.join(bindings_dir, 'webidlsrcs.mk')
++-        with self._write_file(webidls_mk) as fh:
+++        fh = self._write_file(webidls_mk).__enter__()
+++        if 1:
++             mk.dump(fh, removal_guard=False)
+++        fh.close() #exit__(0, 0, 0)
+++
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/backend/visualstudio.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/backend/visualstudio.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/backend/visualstudio.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/backend/visualstudio.py	2014-10-24 11:41:35.488880104 -0600
++@@ -5,7 +5,7 @@
++ # This file contains a build backend for generating Visual Studio project
++ # files.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import errno
++ import os
++@@ -17,7 +17,7 @@ from xml.dom import getDOMImplementation
++ 
++ from mozpack.files import FileFinder
++ 
++-from .common import CommonBackend
+++from common import CommonBackend
++ from ..frontend.data import (
++     Defines,
++     LibraryDefinition,
++@@ -122,7 +122,7 @@ class VisualStudioBackend(CommonBackend)
++         out_dir = self._out_dir
++         try:
++             os.makedirs(out_dir)
++-        except OSError as e:
+++        except OSError, e:
++             if e.errno != errno.EEXIST:
++                 raise
++ 
++@@ -218,26 +218,34 @@ class VisualStudioBackend(CommonBackend)
++ 
++         # Write out a shared property file with common variables.
++         props_path = os.path.join(out_dir, 'mozilla.props')
++-        with open(props_path, 'wb') as fh:
+++        fh = open(props_path, 'wb')
+++        if 1:
++             self._write_props(fh)
++ 
+++        fh.close()
++         # Generate some wrapper scripts that allow us to invoke mach inside
++         # a MozillaBuild-like environment. We currently only use the batch
++         # script. We'd like to use the PowerShell script. However, it seems
++         # to buffer output from within Visual Studio (surely this is
++         # configurable) and the default execution policy of PowerShell doesn't
++         # allow custom scripts to be executed.
++-        with open(os.path.join(out_dir, 'mach.bat'), 'wb') as fh:
+++        fh = open(os.path.join(out_dir, 'mach.bat'), 'wb')
+++        if 1:
++             self._write_mach_batch(fh)
++ 
++-        with open(os.path.join(out_dir, 'mach.ps1'), 'wb') as fh:
+++        fh.close()
+++        fh = open(os.path.join(out_dir, 'mach.ps1'), 'wb')
+++        if 1:
++             self._write_mach_powershell(fh)
++ 
+++        fh.close()
++         # Write out a solution file to tie it all together.
++         solution_path = os.path.join(out_dir, 'mozilla.sln')
++-        with open(solution_path, 'wb') as fh:
+++        fh = open(solution_path, 'wb')
+++        if 1:
++             self._write_solution(fh, projects)
++ 
+++        fh.close()
++     def _write_solution(self, fh, projects):
++         version = visual_studio_product_to_internal_version(self._version, True)
++         # This is a Visual C++ Project type.
++@@ -425,16 +433,20 @@ class VisualStudioBackend(CommonBackend)
++ 
++     def _write_vs_project(self, out_dir, basename, name, **kwargs):
++         root = '%s.vcxproj' % basename
++-        with open(os.path.join(out_dir, root), 'wb') as fh:
+++        fh = open(os.path.join(out_dir, root), 'wb')
+++        if 1:
++             project_id, name = VisualStudioBackend.write_vs_project(fh,
++                 self._version, name, **kwargs)
++ 
++-        with open(os.path.join(out_dir, '%s.user' % root), 'w') as fh:
+++        fh.close()
+++        fh = open(os.path.join(out_dir, '%s.user' % root), 'w')
+++        if 1:
++             fh.write('<?xml version="1.0" encoding="utf-8"?>\r\n')
++             fh.write('<Project ToolsVersion="4.0" xmlns="%s">\r\n' %
++                 MSBUILD_NAMESPACE)
++             fh.write('</Project>\r\n')
++ 
+++        fh.close()
++         return project_id
++ 
++     @staticmethod
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/base.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/base.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/base.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/base.py	2014-10-24 11:41:35.488880104 -0600
++@@ -2,12 +2,16 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++-import json
+++import simplejson as json
++ import logging
++ import mozpack.path
++-import multiprocessing
+++#import multiprocessing
++ import os
++ import subprocess
++ import sys
++@@ -18,14 +22,14 @@ from mach.mixin.process import ProcessEx
++ 
++ from mozfile.mozfile import rmtree
++ 
++-from .backend.configenvironment import ConfigEnvironment
++-from .controller.clobber import Clobberer
++-from .mozconfig import (
+++from backend.configenvironment import ConfigEnvironment
+++from controller.clobber import Clobberer
+++from mozconfig import (
++     MozconfigFindException,
++     MozconfigLoadException,
++     MozconfigLoader,
++ )
++-from .virtualenv import VirtualenvManager
+++from virtualenv import VirtualenvManager
++ 
++ 
++ def ancestors(path):
++@@ -327,7 +331,11 @@ class MozbuildObject(ProcessExecutionMix
++ 
++         leaf = None
++ 
++-        leaf = (substs['MOZ_APP_NAME'] if what == 'app' else what) + substs['BIN_SUFFIX']
+++        leaf = None
+++        if what == 'app':
+++          leaf = (substs['MOZ_APP_NAME'])
+++        else:
+++          leaf = (what) + substs['BIN_SUFFIX']
++         path = os.path.join(stem, leaf)
++ 
++         if validate_exists and not os.path.exists(path):
++@@ -421,7 +429,7 @@ class MozbuildObject(ProcessExecutionMix
++             if num_jobs > 0:
++                 args.append('-j%d' % num_jobs)
++             else:
++-                args.append('-j%d' % multiprocessing.cpu_count())
+++                args.append('-j%d' % 1)#multiprocessing.cpu_count())
++         elif num_jobs > 0:
++             args.append('MOZ_PARALLEL_BUILD=%d' % num_jobs)
++ 
++@@ -449,7 +457,7 @@ class MozbuildObject(ProcessExecutionMix
++             fn = self._run_command_in_srcdir
++ 
++         append_env = dict(append_env or ())
++-        append_env[b'MACH'] = '1'
+++        append_env['MACH'] = '1'
++ 
++         params = {
++             'args': args,
++@@ -566,11 +574,11 @@ class MachCommandBase(MozbuildObject):
++         try:
++             self.mozconfig
++ 
++-        except MozconfigFindException as e:
+++        except MozconfigFindException, e:
++             print(e.message)
++             sys.exit(1)
++ 
++-        except MozconfigLoadException as e:
+++        except MozconfigLoadException, e:
++             print('Error loading mozconfig: ' + e.path)
++             print('')
++             print(e.message)
++@@ -625,7 +633,11 @@ class PathArgument(object):
++         self.arg = arg
++         self.topsrcdir = topsrcdir
++         self.topobjdir = topobjdir
++-        self.cwd = os.getcwd() if cwd is None else cwd
+++        self.cwd = None
+++        if cwd is None:
+++          self.cwd = os.getcwd()
+++        else:
+++          self.cwd = cwd
++ 
++     def relpath(self):
++         """Return a path relative to the topsrcdir or topobjdir.
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/compilation/warnings.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/compilation/warnings.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/compilation/warnings.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/compilation/warnings.py	2014-10-24 11:41:35.488880104 -0600
++@@ -4,7 +4,7 @@
++ 
++ # This modules provides functionality for dealing with compiler warnings.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import errno
++ import json
++@@ -261,21 +261,25 @@ class WarningsDatabase(object):
++ 
++     def load_from_file(self, filename):
++         """Load the database from a file."""
++-        with open(filename, 'rb') as fh:
+++        fh = open(filename, 'rb')
+++        if 1:
++             self.deserialize(fh)
++ 
+++        fh.close()
++     def save_to_file(self, filename):
++         """Save the database to a file."""
++         try:
++             # Ensure the directory exists
++             os.makedirs(os.path.dirname(filename))
++-        except OSError as e:
+++        except OSError, e:
++             if e.errno != errno.EEXIST:
++                 raise
++-        with open(filename, 'wb') as fh:
+++        fh = open(filename, 'wb')
+++        if 1:
++             self.serialize(fh)
++ 
++ 
+++        fh.close()
++ class WarningsCollector(object):
++     """Collects warnings from text data.
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/config_status.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/config_status.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/config_status.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/config_status.py	2014-10-24 11:41:35.488880104 -0600
++@@ -6,7 +6,9 @@
++ # drop-in replacement for autoconf 2.13's config.status, with features
++ # borrowed from autoconf > 2.5, and additional features.
++ 
++-from __future__ import print_function
+++import sys
+++def print24(msg, file=sys.stdout, end="\n"):
+++  file.write(msg + end)
++ 
++ import logging
++ import os
++@@ -140,15 +142,20 @@ def config_status(topobjdir='.', topsrcd
++         os.chdir(topobjdir)
++         os.execlp('sh', 'sh', '-c', ' '.join([os.path.join(topsrcdir, 'configure'), env.substs['ac_configure_args'], '--no-create', '--no-recursion']))
++ 
++-    log_level = logging.DEBUG if options.verbose else logging.INFO
+++    log_level = None
+++    if options.verbose:
+++      log_level = logging.DEBUG
+++    else:
+++      log_level = logging.INFO
++     log_manager.add_terminal_logging(level=log_level)
++     log_manager.enable_unstructured()
++ 
++-    print('Reticulating splines...', file=sys.stderr)
+++    print24('Reticulating splines...', file=sys.stderr)
+++    #print definitions
++     summary = the_backend.consume(definitions)
++ 
++     for line in summary.summaries():
++-        print(line, file=sys.stderr)
+++        print24(line, file=sys.stderr)
++ 
++     if options.diff:
++         for path, diff in sorted(summary.file_diffs.items()):
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/controller/building.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/controller/building.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/controller/building.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/controller/building.py	2014-10-24 11:41:35.489880100 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import getpass
++ import json
++@@ -258,9 +258,11 @@ class BuildMonitor(MozbuildObject):
++             if not usage:
++                 return
++ 
++-            with open(self._get_state_filename('build_resources.json'), 'w') as fh:
+++            fh = open(self._get_state_filename('build_resources.json'), 'w')
+++            if 1:
++                 json.dump(usage, fh, indent=2)
++-        except Exception as e:
+++            fh.close()
+++        except Exception, e:
++             self.log(logging.WARNING, 'build_resources_error',
++                 {'msg': str(e)},
++                 'Exception when writing resource usage file: {msg}')
++@@ -451,7 +453,7 @@ class BuildDriver(MozbuildObject):
++ 
++         env = {}
++         if not remove:
++-            env[b'NO_REMOVE'] = b'1'
+++            env[b'NO_REMOVE'] = '1'
++ 
++         self._run_make(target='install-tests', append_env=env, pass_thru=True,
++             print_directory=False)
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/controller/clobber.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/controller/clobber.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/controller/clobber.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/controller/clobber.py	2014-10-24 11:41:35.489880100 -0600
++@@ -2,7 +2,11 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import print_function
+++def print24(msg, file=None, end=""):
+++  if file:
+++    file.write(msg + end)
+++  else:
+++    sys.stdout.write(msg + end)
++ 
++ r'''This module contains code for managing clobbering of the tree.'''
++ 
++@@ -77,10 +81,12 @@ class Clobberer(object):
++         This returns a list of lines describing why the clobber was required.
++         Each line is stripped of leading and trailing whitespace.
++         """
++-        with open(self.src_clobber, 'rt') as fh:
+++        fh = open(self.src_clobber, 'rt')
+++        if 1:
++             lines = [l.strip() for l in fh.readlines()]
++             return [l for l in lines if l and not l.startswith('#')]
++ 
+++        fh.close()
++     def ensure_objdir_state(self):
++         """Ensure the CLOBBER file in the objdir exists.
++ 
++@@ -92,7 +98,8 @@ class Clobberer(object):
++ 
++         if not os.path.exists(self.obj_clobber):
++             # Simply touch the file.
++-            with open(self.obj_clobber, 'a'):
+++            open(self.obj_clobber, 'a')
+++            if 1:
++                 pass
++ 
++     def maybe_do_clobber(self, cwd, allow_auto=False, fh=sys.stderr):
++@@ -113,7 +120,7 @@ class Clobberer(object):
++         cwd = os.path.normpath(cwd)
++ 
++         if not self.clobber_needed():
++-            print('Clobber not needed.', file=fh)
+++            print24('Clobber not needed.', file=fh)
++             self.ensure_objdir_state()
++             return False, False, None
++ 
++@@ -134,7 +141,7 @@ class Clobberer(object):
++             return True, False, self._message(
++                 'Cannot clobber while the shell is inside the object directory.')
++ 
++-        print('Automatically clobbering %s' % self.topobjdir, file=fh)
+++        print24('Automatically clobbering %s' % self.topobjdir, file=fh)
++         try:
++             if cwd == self.topobjdir:
++                 for entry in os.listdir(self.topobjdir):
++@@ -149,9 +156,9 @@ class Clobberer(object):
++                 rmtree(self.topobjdir)
++ 
++             self.ensure_objdir_state()
++-            print('Successfully completed auto clobber.', file=fh)
+++            print24('Successfully completed auto clobber.', file=fh)
++             return True, True, None
++-        except (IOError) as error:
+++        except (IOError), error:
++             return True, False, self._message(
++                 'Error when automatically clobbering: ' + str(error))
++ 
++@@ -164,7 +171,7 @@ class Clobberer(object):
++ 
++ def main(args, env, cwd, fh=sys.stderr):
++     if len(args) != 2:
++-        print('Usage: clobber.py topsrcdir topobjdir', file=fh)
+++        print24('Usage: clobber.py topsrcdir topobjdir', file=fh)
++         return 1
++ 
++     topsrcdir, topobjdir = args
++@@ -175,16 +182,20 @@ def main(args, env, cwd, fh=sys.stderr):
++     if not os.path.isabs(topobjdir):
++         topobjdir = os.path.abspath(topobjdir)
++ 
++-    auto = True if env.get('AUTOCLOBBER', False) else False
+++    auto = None
+++    if env.get('AUTOCLOBBER', False):
+++      auto = True
+++    else:
+++      auto = False
++     clobber = Clobberer(topsrcdir, topobjdir)
++     required, performed, message = clobber.maybe_do_clobber(cwd, auto, fh)
++ 
++     if not required or performed:
++         if performed and env.get('TINDERBOX_OUTPUT'):
++-            print('TinderboxPrint: auto clobber', file=fh)
+++            print24('TinderboxPrint: auto clobber', file=fh)
++         return 0
++ 
++-    print(message, file=fh)
+++    print24(message, file=fh)
++     return 1
++ 
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/data.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/data.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/data.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/data.py	2014-10-24 11:41:35.489880100 -0600
++@@ -15,17 +15,18 @@ contains the code for converting execute
++ structures.
++ """
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import os
++ 
++-from collections import OrderedDict
+++from ordereddict import OrderedDict
+++
++ from mozbuild.util import (
++     shell_quote,
++     StrictOrderingOnAppendList,
++ )
++ import mozpack.path as mozpath
++-from .sandbox_symbols import FinalTargetValue
+++from sandbox_symbols import FinalTargetValue
++ 
++ 
++ class TreeMetadata(object):
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/emitter.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/emitter.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/emitter.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/emitter.py	2014-10-24 11:41:35.490880096 -0600
++@@ -1,10 +1,64 @@
+++# relpath
+++import os, sys
+++# Creates os.path.relpath for Python 2.4
+++
+++if not hasattr(os, "relpath"):
+++    if os.path is sys.modules.get("ntpath"):
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++            if start_list[0].lower() != path_list[0].lower():
+++                unc_path, rest = os.path.splitunc(path)
+++                unc_start, rest = os.path.splitunc(start)
+++                if bool(unc_path) ^ bool(unc_start):
+++                    raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
+++                                                                        % (path, start))
+++                else:
+++                    raise ValueError("path is on drive %s, start on drive %s"
+++                                                        % (path_list[0], start_list[0]))
+++            # Work out how much of the filepath is shared by start and path.
+++            for i in range(min(len(start_list), len(path_list))):
+++                if start_list[i].lower() != path_list[i].lower():
+++                    break
+++            else:
+++                i += 1
+++ 
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++    
+++    else:
+++        # default to posixpath definition
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++        
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++        
+++            # Work out how much of the filepath is shared by start and path.
+++            i = len(os.path.commonprefix([start_list, path_list]))
+++        
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++        
+++    os.path.relpath = relpath
++ # This Source Code Form is subject to the terms of the Mozilla Public
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
++ 
++-import json
+++
+++import simplejson as json
++ import logging
++ import os
++ import traceback
++@@ -16,7 +70,7 @@ from mach.mixin.logging import LoggingMi
++ import mozpack.path as mozpath
++ import manifestparser
++ 
++-from .data import (
+++from data import (
++     ConfigFileSubstitution,
++     Defines,
++     DirectoryTraversal,
++@@ -48,12 +102,12 @@ from .data import (
++     XPIDLFile,
++ )
++ 
++-from .reader import (
+++from reader import (
++     MozbuildSandbox,
++     SandboxValidationError,
++ )
++ 
++-from .gyp_reader import GypSandbox
+++from gyp_reader import GypSandbox
++ 
++ 
++ class TreeMetadataEmitter(LoggingMixin):
++@@ -93,8 +147,8 @@ class TreeMetadataEmitter(LoggingMixin):
++         def emit_objs(objs):
++             for o in objs:
++                 yield o
++-                if not o._ack:
++-                    raise Exception('Unhandled object of type %s' % type(o))
+++                #TEMP if not o._ack:
+++                #    raise Exception('Unhandled object of type %s' % type(o))
++ 
++         for out in output:
++             if isinstance(out, (MozbuildSandbox, GypSandbox)):
++@@ -299,7 +353,12 @@ class TreeMetadataEmitter(LoggingMixin):
++ 
++         no_pgo = sandbox.get('NO_PGO')
++         sources = sandbox.get('SOURCES', [])
++-        no_pgo_sources = [f for f in sources if sources[f].no_pgo]
+++        #print (sources)
+++        #print sources.__class__
+++        #print dir(sources)
+++        no_pgo_sources = []
+++ 
+++        #no_pgo_sources = [f for f in sources if sources[f].no_pgo]
++         if no_pgo:
++             if no_pgo_sources:
++                 raise SandboxValidationError('NO_PGO and SOURCES[...].no_pgo cannot be set at the same time')
++@@ -307,7 +366,15 @@ class TreeMetadataEmitter(LoggingMixin):
++         if no_pgo_sources:
++             passthru.variables['NO_PROFILE_GUIDED_OPTIMIZE'] = no_pgo_sources
++ 
++-        sources_with_flags = [f for f in sources if sources[f].flags]
+++        sources_with_flags = []
+++        #print "NOTLIST", type(sources), 
+++        #print sources, type(sources), sources.index
+++        if not type(sources) == list:
+++          for f in sources:
+++            #print f
+++            #print sources[i], type(sources[i]), sources[i].flags
+++            if sources[f].flags:
+++              sources_with_flags.append(f)
++         for f in sources_with_flags:
++             ext = mozpath.splitext(f)[1]
++             yield PerSourceFlag(sandbox, f, sources[f].flags)
++@@ -458,7 +525,7 @@ class TreeMetadataEmitter(LoggingMixin):
++             sandbox['TOPSRCDIR']))
++         install_prefix = mozpath.join(install_root, install_subdir)
++ 
++-        try:
+++        if 1: #try:
++             m = manifestparser.TestManifest(manifests=[path], strict=True)
++             defaults = m.manifest_defaults[os.path.normpath(path)]
++             if not m.tests and not 'support-files' in defaults:
++@@ -475,8 +542,10 @@ class TreeMetadataEmitter(LoggingMixin):
++             if filter_inactive:
++                 # We return tests that don't exist because we want manifests
++                 # defining tests that don't exist to result in error.
++-                filtered = m.active_tests(exists=False, disabled=False,
++-                    **self.mozinfo)
+++                #print (self.mozinfo)
+++                filtered = []
+++                #FIXME filtered = m.active_tests(exists=False, disabled=False,
+++                #    **self.mozinfo)
++ 
++                 missing = [t['name'] for t in filtered if not os.path.exists(t['path'])]
++                 if missing:
++@@ -586,10 +655,10 @@ class TreeMetadataEmitter(LoggingMixin):
++                 obj.external_installs.add(mozpath.join(out_dir, f))
++ 
++             yield obj
++-        except (AssertionError, Exception):
++-            raise SandboxValidationError('Error processing test '
++-                'manifest file %s: %s' % (path,
++-                    '\n'.join(traceback.format_exception(*sys.exc_info()))))
+++        #except (AssertionError, Exception):
+++        #    raise SandboxValidationError('Error processing test '
+++        #        'manifest file %s: %s' % (path,
+++        #            '\n'.join(traceback.format_exception(*sys.exc_info()))))
++ 
++     def _emit_directory_traversal_from_sandbox(self, sandbox):
++         o = DirectoryTraversal(sandbox)
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/gyp_reader.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/gyp_reader.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/gyp_reader.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/gyp_reader.py	2014-10-24 11:41:35.490880096 -0600
++@@ -1,20 +1,128 @@
+++# relpath
+++import os, sys
+++# Creates os.path.relpath for Python 2.4
+++
+++if not hasattr(os, "relpath"):
+++    if os.path is sys.modules.get("ntpath"):
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++            if start_list[0].lower() != path_list[0].lower():
+++                unc_path, rest = os.path.splitunc(path)
+++                unc_start, rest = os.path.splitunc(start)
+++                if bool(unc_path) ^ bool(unc_start):
+++                    raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
+++                                                                        % (path, start))
+++                else:
+++                    raise ValueError("path is on drive %s, start on drive %s"
+++                                                        % (path_list[0], start_list[0]))
+++            # Work out how much of the filepath is shared by start and path.
+++            for i in range(min(len(start_list), len(path_list))):
+++                if start_list[i].lower() != path_list[i].lower():
+++                    break
+++            else:
+++                i += 1
+++ 
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++    
+++    else:
+++        # default to posixpath definition
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++        
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++        
+++            # Work out how much of the filepath is shared by start and path.
+++            i = len(os.path.commonprefix([start_list, path_list]))
+++        
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++        
+++    os.path.relpath = relpath
+++# relpath
+++import os, sys
+++# Creates os.path.relpath for Python 2.4
+++
+++if not hasattr(os, "relpath"):
+++    if os.path is sys.modules.get("ntpath"):
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++            if start_list[0].lower() != path_list[0].lower():
+++                unc_path, rest = os.path.splitunc(path)
+++                unc_start, rest = os.path.splitunc(start)
+++                if bool(unc_path) ^ bool(unc_start):
+++                    raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
+++                                                                        % (path, start))
+++                else:
+++                    raise ValueError("path is on drive %s, start on drive %s"
+++                                                        % (path_list[0], start_list[0]))
+++            # Work out how much of the filepath is shared by start and path.
+++            for i in range(min(len(start_list), len(path_list))):
+++                if start_list[i].lower() != path_list[i].lower():
+++                    break
+++            else:
+++                i += 1
+++ 
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++    
+++    else:
+++        # default to posixpath definition
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++        
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++        
+++            # Work out how much of the filepath is shared by start and path.
+++            i = len(os.path.commonprefix([start_list, path_list]))
+++        
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++        
+++    os.path.relpath = relpath
++ # This Source Code Form is subject to the terms of the Mozilla Public
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ import gyp
++ import sys
++ import time
++ import os
++ import mozpack.path as mozpath
++ from mozpack.files import FileFinder
++-from .sandbox import (
+++from sandbox import (
++     alphabetical_sorted,
++     GlobalNamespace,
++ )
++-from .sandbox_symbols import VARIABLES
++-from .reader import SandboxValidationError
+++from sandbox_symbols import VARIABLES
+++from reader import SandboxValidationError
++ 
++ # Define this module as gyp.generator.mozbuild so that gyp can use it
++ # as a generator under the name "mozbuild".
++@@ -37,7 +145,7 @@ generator_default_variables = {
++ for dirname in ['INTERMEDIATE_DIR', 'SHARED_INTERMEDIATE_DIR', 'PRODUCT_DIR',
++                 'LIB_DIR', 'SHARED_LIB_DIR']:
++   # Some gyp steps fail if these are empty(!).
++-  generator_default_variables[dirname] = b'dir'
+++  generator_default_variables[dirname] = 'dir'
++ 
++ for unused in ['RULE_INPUT_PATH', 'RULE_INPUT_ROOT', 'RULE_INPUT_NAME',
++                'RULE_INPUT_DIRNAME', 'RULE_INPUT_EXT',
++@@ -45,7 +153,7 @@ for unused in ['RULE_INPUT_PATH', 'RULE_
++                'STATIC_LIB_PREFIX', 'STATIC_LIB_SUFFIX',
++                'SHARED_LIB_PREFIX', 'SHARED_LIB_SUFFIX',
++                'LINKER_SUPPORTS_ICF']:
++-  generator_default_variables[unused] = b''
+++  generator_default_variables[unused] = ''
++ 
++ 
++ class GypSandbox(GlobalNamespace):
++@@ -91,9 +199,9 @@ def read_from_gyp(config, path, output,
++     str_vars = dict((name, encode(value)) for name, value in vars.items())
++ 
++     params = {
++-        b'parallel': False,
++-        b'generator_flags': {},
++-        b'build_files': [path],
+++        'parallel': False,
+++        'generator_flags': {},
+++        'build_files': [path],
++     }
++ 
++     # Files that gyp_chromium always includes
++@@ -104,7 +212,7 @@ def read_from_gyp(config, path, output,
++ 
++     # Read the given gyp file and its dependencies.
++     generator, flat_list, targets, data = \
++-        gyp.Load([path], format=b'mozbuild',
+++        gyp.Load([path], format='mozbuild',
++             default_variables=str_vars,
++             includes=includes,
++             depth=encode(mozpath.dirname(path)),
++@@ -113,7 +221,7 @@ def read_from_gyp(config, path, output,
++     # Process all targets from the given gyp files and its dependencies.
++     # The path given to AllTargets needs to use os.sep, while the frontend code
++     # gives us paths normalized with forward slash separator.
++-    for target in gyp.common.AllTargets(flat_list, targets, path.replace(b'/', os.sep)):
+++    for target in gyp.common.AllTargets(flat_list, targets, path.replace('/', os.sep)):
++         build_file, target_name, toolset = gyp.common.ParseQualifiedTarget(target)
++         # The list of included files returned by gyp are relative to build_file
++         included_files = [mozpath.abspath(mozpath.join(mozpath.dirname(build_file), f))
++@@ -122,7 +230,8 @@ def read_from_gyp(config, path, output,
++         sandbox = GypSandbox(mozpath.abspath(build_file), included_files)
++         sandbox.config = config
++ 
++-        with sandbox.allow_all_writes() as d:
+++        d = sandbox.allow_all_writes()
+++        if 1:
++             topsrcdir = d['TOPSRCDIR'] = config.topsrcdir
++             d['TOPOBJDIR'] = config.topobjdir
++             relsrcdir = d['RELATIVEDIR'] = mozpath.relpath(mozpath.dirname(build_file), config.topsrcdir)
++@@ -143,10 +252,11 @@ def read_from_gyp(config, path, output,
++             d['OBJDIR'] = mozpath.join(output, reldir, subdir)
++             d['IS_GYP_DIR'] = True
++ 
+++        #d.__exit__(0, 0, 0)
++         spec = targets[target]
++ 
++         # Derive which gyp configuration to use based on MOZ_DEBUG.
++-        c = 'Debug' if config.substs['MOZ_DEBUG'] else 'Release'
+++        c = ('Release', 'Debug')[config.substs['MOZ_DEBUG'] == '1']
++         if c not in spec['configurations']:
++             raise RuntimeError('Missing %s gyp configuration for target %s '
++                                'in %s' % (c, target_name, build_file))
++@@ -186,9 +296,11 @@ def read_from_gyp(config, path, output,
++             for include in target_conf.get('include_dirs', []):
++                 sandbox['LOCAL_INCLUDES'] += [include]
++ 
++-            with sandbox.allow_all_writes() as d:
+++            d = sandbox.allow_all_writes()
+++            if 1:
++                 d['EXTRA_ASSEMBLER_FLAGS'] = target_conf.get('asflags_mozilla', [])
++                 d['EXTRA_COMPILE_FLAGS'] = target_conf.get('cflags_mozilla', [])
+++            #d.__exit__(0, 0, 0)
++         else:
++             # Ignore other types than static_library because we don't have
++             # anything using them, and we're not testing them. They can be
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/mach_commands.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/mach_commands.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/mach_commands.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/mach_commands.py	2014-10-24 11:41:35.490880096 -0600
++@@ -2,7 +2,11 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ from mach.decorators import (
++     CommandArgument,
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/reader.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/reader.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/reader.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/reader.py	2014-10-24 11:41:35.491880091 -0600
++@@ -20,8 +20,9 @@ execution.
++ The BuildReader contains basic logic for traversing a tree of mozbuild files.
++ It does this by examining specific variables populated during execution.
++ """
++-
++-from __future__ import print_function, unicode_literals
+++import sys
+++def print24(msg, file=sys.stdout, end='\n'):
+++  file.write(msg + end)
++ 
++ import logging
++ import os
++@@ -30,8 +31,8 @@ import time
++ import traceback
++ import types
++ 
++-from collections import OrderedDict
++-from io import StringIO
+++from mycollections import OrderedDict
+++import StringIO
++ 
++ from mozbuild.util import (
++     ReadOnlyDefaultDict,
++@@ -43,25 +44,25 @@ from mozbuild.backend.configenvironment
++ from mozpack.files import FileFinder
++ import mozpack.path as mozpath
++ 
++-from .data import (
+++from data import (
++     AndroidEclipseProjectData,
++     JavaJarData,
++ )
++ 
++-from .sandbox import (
+++from sandbox import (
++     SandboxError,
++     SandboxExecutionError,
++     SandboxLoadError,
++     Sandbox,
++ )
++ 
++-from .sandbox_symbols import (
+++from sandbox_symbols import (
++     FUNCTIONS,
++     VARIABLES,
++ )
++ 
++-if sys.version_info.major == 2:
++-    text_type = unicode
+++if sys.version_info[0] == 2:
+++    text_type = str
++     type_type = types.TypeType
++ else:
++     text_type = str
++@@ -69,7 +70,9 @@ else:
++ 
++ 
++ def log(logger, level, action, params, formatter):
++-    logger.log(level, formatter, extra={'action': action, 'params': params})
+++    #print(action, formatter)
+++    # logger.log(level, formatter, extra={'action': action, 'params': params})
+++    logger.log(level, formatter, action, params)
++ 
++ 
++ def is_read_allowed(path, config):
++@@ -124,6 +127,7 @@ class MozbuildSandbox(Sandbox):
++         the path of the main mozbuild file that is being executed. It is used
++         to compute encountered relative paths.
++         """
+++        #print path, config
++         Sandbox.__init__(self, allowed_variables=VARIABLES)
++ 
++         self._log = logging.getLogger(__name__)
++@@ -177,7 +181,8 @@ class MozbuildSandbox(Sandbox):
++             config.topobjdir = topobjdir
++             self.config = config
++ 
++-        with self._globals.allow_all_writes() as d:
+++        d = self._globals.allow_all_writes()
+++        if 1:
++             d['TOPSRCDIR'] = topsrcdir
++             d['TOPOBJDIR'] = topobjdir
++             d['RELATIVEDIR'] = reldir
++@@ -282,7 +287,8 @@ class MozbuildSandbox(Sandbox):
++ 
++     def _add_tier_directory(self, tier, reldir, static=False, external=False):
++         """Register a tier directory with the build."""
++-        if isinstance(reldir, text_type):
+++        #if isinstance(reldir, text_type):
+++        if isinstance(reldir, str):
++             reldir = [reldir]
++ 
++         if not tier in self['TIERS']:
++@@ -292,7 +298,13 @@ class MozbuildSandbox(Sandbox):
++                 'external': [],
++             }
++ 
++-        key = 'static' if static else 'external' if external else 'regular'
+++        key = None
+++        if static:
+++          key = 'static'
+++        elif external:
+++          key = 'external'
+++        else:
+++          key = 'regular'
++         if external and static:
++             raise Exception('Only one of external or static can be set at the '
++                 'same time')
++@@ -336,7 +348,7 @@ class MozbuildSandbox(Sandbox):
++ 
++     def _warning(self, message):
++         # FUTURE consider capturing warnings in a variable instead of printing.
++-        print('WARNING: %s' % message, file=sys.stderr)
+++        print24('WARNING: %s' % message, file=sys.stderr)
++ 
++     def _error(self, message):
++         raise SandboxCalledError(self._execution_stack, message)
++@@ -671,13 +683,13 @@ class BuildReader(object):
++         # In the future, we may traverse moz.build files by looking
++         # for DIRS references in the AST, even if a directory is added behind
++         # a conditional. For now, just walk the filesystem.
++-        ignore = {
+++        ignore = (
++             # Ignore fake moz.build files used for testing moz.build.
++             'python/mozbuild/mozbuild/test',
++ 
++             # Ignore object directories.
++             'obj*',
++-        }
+++        )
++ 
++         finder = FileFinder(self.topsrcdir, find_executables=False,
++             ignore=ignore)
++@@ -722,28 +734,28 @@ class BuildReader(object):
++                 descend=descend, metadata=metadata):
++                 yield s
++ 
++-        except BuildReaderError as bre:
++-            raise bre
+++        #except BuildReaderError, bre:
+++        #    raise bre
++ 
++-        except SandboxCalledError as sce:
+++        except SandboxCalledError, sce:
++             raise BuildReaderError(list(self._execution_stack),
++                 sys.exc_info()[2], sandbox_called_error=sce)
++ 
++-        except SandboxExecutionError as se:
++-            raise BuildReaderError(list(self._execution_stack),
++-                sys.exc_info()[2], sandbox_exec_error=se)
++-
++-        except SandboxLoadError as sle:
++-            raise BuildReaderError(list(self._execution_stack),
++-                sys.exc_info()[2], sandbox_load_error=sle)
++-
++-        except SandboxValidationError as ve:
++-            raise BuildReaderError(list(self._execution_stack),
++-                sys.exc_info()[2], validation_error=ve)
++-
++-        except Exception as e:
++-            raise BuildReaderError(list(self._execution_stack),
++-                sys.exc_info()[2], other_error=e)
+++        #except SandboxExecutionError, se:
+++        #    raise BuildReaderError(list(self._execution_stack),
+++        #        sys.exc_info()[2], sandbox_exec_error=se)
+++
+++        #except SandboxLoadError, sle:
+++        #    raise BuildReaderError(list(self._execution_stack),
+++        #        sys.exc_info()[2], sandbox_load_error=sle)
+++
+++        #except SandboxValidationError, ve:
+++        #    raise BuildReaderError(list(self._execution_stack),
+++        #        sys.exc_info()[2], validation_error=ve)
+++
+++        #except Exception, e:
+++        #    raise BuildReaderError(list(self._execution_stack),
+++        #        sys.exc_info()[2], other_error=e)
++ 
++     def _read_mozbuild(self, path, config, read_tiers, filesystem_absolute,
++             descend, metadata):
++@@ -760,8 +772,14 @@ class BuildReader(object):
++ 
++         time_start = time.time()
++         sandbox = MozbuildSandbox(config, path, metadata=metadata)
+++        #print("exec file vvvv %s" % path)
+++        #print(sandbox)
+++        #print(dir(sandbox))
+++ 
++         sandbox.exec_file(path, filesystem_absolute=filesystem_absolute)
++         sandbox.execution_time = time.time() - time_start
+++        #print("exec file ^^^ %s" % path)
+++ 
++ 
++         if self._sandbox_post_eval_cb:
++             self._sandbox_post_eval_cb(sandbox)
++@@ -778,7 +796,7 @@ class BuildReader(object):
++                     'The %s variable%s not allowed in such directories.'
++                     % (sandbox['RELATIVEDIR'], var, metadata['parent'],
++                        ' and '.join(', '.join(matches).rsplit(', ', 1)),
++-                       's are' if len(matches) > 1 else ' is'))
+++                       ('is', 's are')[len(matches) > 1]))
++ 
++         # We first collect directories populated in variables.
++         dir_vars = ['DIRS', 'PARALLEL_DIRS', 'TOOL_DIRS']
++@@ -803,7 +821,7 @@ class BuildReader(object):
++             # We could emit the parent sandbox before processing gyp
++             # configuration, but we need to add the gyp objdirs to that sandbox
++             # first.
++-            from .gyp_reader import read_from_gyp
+++            from gyp_reader import read_from_gyp
++             non_unified_sources = set()
++             for s in gyp_dir.non_unified_sources:
++                 source = mozpath.normpath(mozpath.join(curdir, s))
++@@ -842,6 +860,9 @@ class BuildReader(object):
++         # It's very tempting to use a set here. Unfortunately, the recursive
++         # make backend needs order preserved. Once we autogenerate all backend
++         # files, we should be able to convert this to a set.
+++        #print("traverse")
+++   
+++        #print "DIRS in recurse: %s" % dirs
++         recurse_info = OrderedDict()
++         for var, var_dirs in dirs:
++             for d in var_dirs:
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/sandbox.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/sandbox.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/sandbox.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/sandbox.py	2014-10-24 11:41:35.491880091 -0600
++@@ -20,13 +20,13 @@ KeyError are machine parseable. This mac
++ user-friendly error messages in the case of errors.
++ """
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import copy
++ import os
++ import sys
++ 
++-from contextlib import contextmanager
+++
++ 
++ from mozbuild.util import (
++     ReadOnlyDefaultDict,
++@@ -83,9 +83,11 @@ class GlobalNamespace(dict):
++     arbitrary values. e.g.
++ 
++         ns = GlobalNamespace()
++-        with ns.allow_all_writes():
+++        ns.allow_all_writes().__enter__()
+++        if 1:
++             ns['foo'] = True
++ 
+++        ns.allow_all_writes().__exit__(0, 0, 0)
++         ns['bar'] = True  # KeyError raised.
++     """
++ 
++@@ -128,13 +130,21 @@ class GlobalNamespace(dict):
++         self._allow_one_mutation = set()
++ 
++     def __getitem__(self, name):
+++        import traceback            
++         try:
+++            #print(dir(self))
+++            #traceback.print_stack()
++             return dict.__getitem__(self, name)
++         except KeyError:
+++            #print self
+++            #print "Key error with", name
+++            #print "END OF KEY ERROR"
+++            #traceback.print_stack()
++             pass
++ 
++         # The variable isn't present yet. Fall back to VARIABLES.
++         default = self._allowed_variables.get(name, None)
+++        #print "default ", default
++         if default is None:
++             self.last_name_error = KeyError('global_ns', 'get_unknown', name)
++             raise self.last_name_error
++@@ -143,16 +153,18 @@ class GlobalNamespace(dict):
++         # not a class that can be called), then it is actually a rule to
++         # generate the default that should be used.
++         default = default[0]
+++        #print "default2 ", default
++         if issubclass(default, SandboxDerivedValue):
++             value = default(self)
++         else:
++             value = default()
++-
+++        #print "value", value, value.__class__
++         dict.__setitem__(self, name, value)
++         return dict.__getitem__(self, name)
++ 
++     def __setitem__(self, name, value):
++-        if self._allow_all_writes:
+++        #if self._allow_all_writes:
+++        if 1: #if self._allow_all_writes:
++             dict.__setitem__(self, name, value)
++             self._allow_one_mutation.add(name)
++             return
++@@ -198,7 +210,7 @@ class GlobalNamespace(dict):
++ 
++         dict.__setitem__(self, name, value)
++ 
++-    @contextmanager
+++    #@contextmanager
++     def allow_all_writes(self):
++         """Allow any variable to be written to this instance.
++ 
++@@ -208,8 +220,9 @@ class GlobalNamespace(dict):
++         whitelisted mutations.
++         """
++         self._allow_all_writes = True
++-        yield self
++-        self._allow_all_writes = False
+++        return self
+++        #yield self
+++        #self._allow_all_writes = False
++ 
++     # dict.update doesn't call our __setitem__, so we have to override it.
++     def update(self, other):
++@@ -337,14 +350,23 @@ class Sandbox(object):
++ 
++         source = None
++ 
+++        #try:
++         try:
++-            with open(path, 'rt') as fd:
++-                source = fd.read()
++-        except Exception as e:
+++            fd = open(path, 'rt')
+++            source = fd.read()
+++            fd.close()
+++        except Exception, e:
+++            #print "Cannot read %s" % path
++             raise SandboxLoadError(list(self._execution_stack),
++                 sys.exc_info()[2], read_error=path)
++ 
++         self.exec_source(source, path)
+++        #except Exception, e:
+++        #    pass
+++        #except Exception, e:
+++        #    raise SandboxLoadError(list(self._execution_stack),
+++        #        sys.exc_info()[2], read_error=path)
+++
++ 
++     def exec_source(self, source, path):
++         """Execute Python code within a string.
++@@ -371,10 +393,12 @@ class Sandbox(object):
++             # compile() inherits the __future__ from the module by default. We
++             # do want Unicode literals.
++             code = compile(source, path, 'exec')
+++            #print self._globals
++             exec(code, self._globals, self._locals)
++-        except SandboxError as e:
+++        except SandboxError, e:
+++            self._execution_stack.pop()
++             raise e
++-        except NameError as e:
+++        except NameError, e:
++             # A NameError is raised when a local or global could not be found.
++             # The original KeyError has been dropped by the interpreter.
++             # However, we should have it cached in our namespace instances!
++@@ -389,17 +413,20 @@ class Sandbox(object):
++             elif self._locals.last_name_error is not None:
++                 actual = self._locals.last_name_error
++ 
+++            self._execution_stack.pop()
++             raise SandboxExecutionError(list(self._execution_stack),
++                 type(actual), actual, sys.exc_info()[2])
++ 
++-        except Exception as e:
++-            # Need to copy the stack otherwise we get a reference and that is
++-            # mutated during the finally.
++-            exc = sys.exc_info()
++-            raise SandboxExecutionError(list(self._execution_stack), exc[0],
++-                exc[1], exc[2])
++-        finally:
++-            self._execution_stack.pop()
+++        #except Exception, e:
+++        #    # Need to copy the stack otherwise we get a reference and that is
+++        #    # mutated during the finally.
+++        #    exc = sys.exc_info()
+++        #    l = list(self._execution_stack)
+++        #    self._execution_stack.pop()
+++        #    raise SandboxExecutionError(l, exc[0],
+++        #        exc[1], exc[2])
+++        #finally:
+++        self._execution_stack.pop()
++ 
++     # Dict interface proxies reads to global namespace.
++     def __len__(self):
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/sandbox_symbols.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/sandbox_symbols.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/sandbox_symbols.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/frontend/sandbox_symbols.py	2014-10-24 11:41:35.491880091 -0600
++@@ -15,20 +15,21 @@ If you are looking for the absolute auth
++ the Sandbox consists of, you've come to the right place.
++ """
++ 
++-from __future__ import unicode_literals
++ 
++-from collections import OrderedDict
+++
+++from ordereddict import OrderedDict
++ from mozbuild.util import (
++     HierarchicalStringList,
++     HierarchicalStringListWithFlagsFactory,
++     StrictOrderingOnAppendList,
++     StrictOrderingOnAppendListWithFlagsFactory,
++ )
++-from .sandbox import SandboxDerivedValue
+++from sandbox import SandboxDerivedValue
++ from types import StringTypes
++ 
+++str_type = str
++ 
++-class FinalTargetValue(SandboxDerivedValue, unicode):
+++class FinalTargetValue(SandboxDerivedValue, str_type):
++     def __new__(cls, sandbox, value=""):
++         if not value:
++             value = 'dist/'
++@@ -38,7 +39,7 @@ class FinalTargetValue(SandboxDerivedVal
++                 value += 'bin'
++             if sandbox['DIST_SUBDIR']:
++                 value += '/' + sandbox['DIST_SUBDIR']
++-        return unicode.__new__(cls, value)
+++        return str_type.__new__(cls, value)
++ 
++ 
++ # This defines the set of mutable global variables.
++@@ -217,7 +218,7 @@ VARIABLES = {
++        files will be installed in the ``/components`` directory of the distribution.
++         """, 'libs'),
++ 
++-    'FINAL_LIBRARY': (unicode, unicode,
+++    'FINAL_LIBRARY': (str_type, str_type,
++         """Library in which the objects of the current directory will be linked.
++ 
++         This variable contains the name of a library, defined elsewhere with
++@@ -276,7 +277,7 @@ VARIABLES = {
++         likely go away.
++         """, None),
++ 
++-    'HOST_LIBRARY_NAME': (unicode, unicode,
+++    'HOST_LIBRARY_NAME': (str_type, str_type,
++         """Name of target library generated when cross compiling.
++         """, 'binaries'),
++ 
++@@ -287,7 +288,7 @@ VARIABLES = {
++         populated by calling add_java_jar().
++         """, 'binaries'),
++ 
++-    'JS_MODULES_PATH': (unicode, unicode,
+++    'JS_MODULES_PATH': (str_type, str_type,
++         """Sub-directory of ``$(FINAL_TARGET)`` to install
++         ``EXTRA_JS_MODULES``.
++ 
++@@ -297,7 +298,7 @@ VARIABLES = {
++         ``$(FINAL_TARGET)/modules``.
++         """, None),
++ 
++-    'LIBRARY_NAME': (unicode, unicode,
+++    'LIBRARY_NAME': (str_type, str_type,
++         """The name of the library generated for a directory.
++ 
++         In ``example/components/moz.build``,::
++@@ -335,25 +336,25 @@ VARIABLES = {
++ 
++         This variable contains a list of system libaries to link against.
++         """, None),
++-    'RCFILE': (unicode, unicode,
+++    'RCFILE': (str_type, str_type,
++         """The program .rc file.
++ 
++         This variable can only be used on Windows.
++         """, None),
++ 
++-    'RESFILE': (unicode, unicode,
+++    'RESFILE': (str_type, str_type,
++         """The program .res file.
++ 
++         This variable can only be used on Windows.
++         """, None),
++ 
++-    'RCINCLUDE': (unicode, unicode,
+++    'RCINCLUDE': (str_type, str_type,
++         """The resource script file to be included in the default .res file.
++ 
++         This variable can only be used on Windows.
++         """, None),
++ 
++-    'DEFFILE': (unicode, unicode,
+++    'DEFFILE': (str_type, str_type,
++         """The program .def (module definition) file.
++ 
++         This variable can only be used on Windows.
++@@ -483,7 +484,7 @@ VARIABLES = {
++            EXPORTS.mozilla.dom += ['bar.h']
++         """, None),
++ 
++-    'PROGRAM' : (unicode, unicode,
+++    'PROGRAM' : (str_type, str_type,
++         """Compiled executable name.
++ 
++         If the configuration token ``BIN_SUFFIX`` is set, its value will be
++@@ -491,7 +492,7 @@ VARIABLES = {
++         ``BIN_SUFFIX``, ``PROGRAM`` will remain unchanged.
++         """, 'binaries'),
++ 
++-    'HOST_PROGRAM' : (unicode, unicode,
+++    'HOST_PROGRAM' : (str_type, str_type,
++         """Compiled host executable name.
++ 
++         If the configuration token ``HOST_BIN_SUFFIX`` is set, its value will be
++@@ -523,7 +524,7 @@ VARIABLES = {
++         files.
++         """, 'libs'),
++ 
++-    'XPIDL_MODULE': (unicode, unicode,
+++    'XPIDL_MODULE': (str_type, str_type,
++         """XPCOM Interface Definition Module Name.
++ 
++         This is the name of the ``.xpt`` file that is created by linking
++@@ -618,14 +619,14 @@ VARIABLES = {
++         """, None),
++ 
++     # The following variables are used to control the target of installed files.
++-    'XPI_NAME': (unicode, unicode,
+++    'XPI_NAME': (str_type, str_type,
++         """The name of an extension XPI to generate.
++ 
++         When this variable is present, the results of this directory will end up
++         being packaged into an extension instead of the main dist/bin results.
++         """, 'libs'),
++ 
++-    'DIST_SUBDIR': (unicode, unicode,
+++    'DIST_SUBDIR': (str_type, str_type,
++         """The name of an alternate directory to install files to.
++ 
++         When this variable is present, the results of this directory will end up
++@@ -633,7 +634,7 @@ VARIABLES = {
++         otherwise be placed.
++         """, 'libs'),
++ 
++-    'FINAL_TARGET': (FinalTargetValue, unicode,
+++    'FINAL_TARGET': (FinalTargetValue, str_type,
++         """The name of the directory to install targets to.
++ 
++         The directory is relative to the top of the object directory. The
++@@ -645,7 +646,7 @@ VARIABLES = {
++ 
++     'GYP_DIRS': (StrictOrderingOnAppendListWithFlagsFactory({
++             'variables': dict,
++-            'input': unicode,
+++            'input': str_type,
++             'sandbox_vars': dict,
++             'non_unified_sources': StrictOrderingOnAppendList,
++         }), list,
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/html_build_viewer.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/html_build_viewer.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/html_build_viewer.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/html_build_viewer.py	2014-10-24 11:41:35.491880091 -0600
++@@ -4,7 +4,7 @@
++ 
++ # This module contains code for running an HTTP server to view build info.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import BaseHTTPServer
++ import json
++@@ -36,9 +36,11 @@ class HTTPHandler(BaseHTTPServer.BaseHTT
++             self.send_header('Content-Type', 'application/json; charset=utf-8')
++             self.end_headers()
++ 
++-            with open(s.json_files[key], 'rb') as fh:
+++            fh = open(s.json_files[key], 'rb')
+++            if 1:
++                 self.wfile.write(fh.read())
++ 
+++            fh.close()
++             return
++ 
++         if p == '/':
++@@ -78,10 +80,12 @@ class HTTPHandler(BaseHTTPServer.BaseHTT
++         self.send_header('Content-Type', ct)
++         self.end_headers()
++ 
++-        with open(local_path, 'rb') as fh:
+++        fh = open(local_path, 'rb')
+++        if 1:
++             self.wfile.write(fh.read())
++ 
++ 
+++        fh.close()
++ class BuildViewerServer(object):
++     def __init__(self, address='localhost', port=0):
++         # TODO use pkg_resources to obtain HTML resources.
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/jar.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/jar.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/jar.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/jar.py	2014-10-24 11:41:35.492880087 -0600
++@@ -165,13 +165,14 @@ class JarMaker(object):
++                 'chrome.manifest')
++ 
++         if self.useJarfileManifest:
+++            #print chromebasepath
++             self.updateManifest(jarPath + '.manifest',
++-                                chromebasepath.format(''), register)
+++                                chromebasepath %(''), register)
++             addEntriesToListFile(chromeManifest,
++-                                 ['manifest chrome/{0}.manifest'.format(os.path.basename(jarPath))])
+++                                 ['manifest chrome/%s.manifest' % (os.path.basename(jarPath))])
++         if self.useChromeManifest:
++             self.updateManifest(chromeManifest,
++-                                chromebasepath.format('chrome/'),
+++                                chromebasepath % ('chrome/'),
++                                 register)
++ 
++         # If requested, add a root chrome manifest entry (assumed to be in the parent directory
++@@ -289,7 +290,7 @@ class JarMaker(object):
++         # {0} is getting replaced with chrome/ for chrome.manifest, and with
++         # an empty string for jarfile.manifest
++ 
++-        chromebasepath = '{0}' + os.path.basename(jarfile)
+++        chromebasepath = '%s' + os.path.basename(jarfile)
++         if self.outputFormat == 'jar':
++             chromebasepath = 'jar:' + chromebasepath + '.jar!'
++         chromebasepath += '/'
++@@ -382,7 +383,7 @@ class JarMaker(object):
++         if realsrc is None:
++             if jf is not None:
++                 jf.close()
++-            raise RuntimeError('File "{0}" not found in {1}'.format(src,
+++            raise RuntimeError('File "%s" not found in %s' % (src,
++                                ', '.join(src_base)))
++         if m.group('optPreprocess'):
++             outf = outHelper.getOutput(out)
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/mach_commands.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/mach_commands.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/mach_commands.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/mach_commands.py	2014-10-24 11:41:35.492880087 -0600
++@@ -2,7 +2,11 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, # You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ import itertools
++ import logging
++@@ -183,9 +187,11 @@ class BuildProgressFooter(object):
++ 
++                 write_pieces.append(part)
++                 written += len(part)
++-        with self._t.location():
+++        self._t.location().__enter__()
+++        if 1:
++             self._t.move(self._t.height-1,0)
++             self._fh.write(''.join(write_pieces))
+++        self._t.location().__exit__(0, 0, 0)
++         self._fh.flush()
++ 
++ 
++@@ -286,7 +292,8 @@ class Build(MachCommandBase):
++         monitor = self._spawn(BuildMonitor)
++         monitor.init(warnings_path)
++ 
++-        with BuildOutputManager(self.log_manager, monitor) as output:
+++        output = BuildOutputManager(self.log_manager, monitor).__enter__()
+++        if 1:
++             monitor.start()
++ 
++             if what:
++@@ -326,8 +333,10 @@ class Build(MachCommandBase):
++                                                    add_extra_dependencies)
++                     depfile = os.path.join(self.topsrcdir, 'build',
++                                            'dumbmake-dependencies')
++-                    with open(depfile) as f:
+++                    f = open(depfile)
+++                    if 1:
++                         dm = dependency_map(f.readlines())
+++                    f.close()
++                     new_pairs = list(add_extra_dependencies(target_pairs, dm))
++                     self.log(logging.DEBUG, 'dumbmake',
++                              {'target_pairs': target_pairs,
++@@ -373,6 +382,7 @@ class Build(MachCommandBase):
++ 
++             monitor.finish(record_usage=status==0)
++ 
+++        output.__exit__(0, 0, 0)
++         high_finder, finder_percent = monitor.have_high_finder_usage()
++         if high_finder:
++             print(FINDER_SLOW_MESSAGE % finder_percent)
++@@ -390,7 +400,7 @@ class Build(MachCommandBase):
++                         '-message', 'Build complete'], ensure_exit_code=False)
++             except which.WhichError:
++                 pass
++-            except Exception as e:
+++            except Exception, e:
++                 self.log(logging.WARNING, 'notifier-failed', {'error':
++                     e.message}, 'Notification center failed: {error}')
++ 
++@@ -478,7 +488,7 @@ class Build(MachCommandBase):
++         try:
++             self.remove_objdir()
++             return 0
++-        except OSError as e:
+++        except OSError, e:
++             if sys.platform.startswith('win'):
++                 if isinstance(e, WindowsError) and e.winerror in (5,32):
++                     self.log(logging.ERROR, 'file_access_error', {'error': e},
++@@ -598,13 +608,13 @@ class GTestCommands(MachCommandBase):
++         # https://code.google.com/p/googletest/wiki/AdvancedGuide#Running_Test_Programs:_Advanced_Options
++         gtest_env = {b'GTEST_FILTER': gtest_filter}
++ 
++-        gtest_env[b"MOZ_RUN_GTEST"] = b"True"
+++        gtest_env[b"MOZ_RUN_GTEST"] = "True"
++ 
++         if shuffle:
++-            gtest_env[b"GTEST_SHUFFLE"] = b"True"
+++            gtest_env[b"GTEST_SHUFFLE"] = "True"
++ 
++         if tbpl_parser:
++-            gtest_env[b"MOZ_TBPL_PARSER"] = b"True"
+++            gtest_env[b"MOZ_TBPL_PARSER"] = "True"
++ 
++         if jobs == 1:
++             return self.run_process([app_path, "-unittest"],
++@@ -728,7 +738,7 @@ class RunProgram(MachCommandBase):
++     def run(self, params, remote, background):
++         try:
++             args = [self.get_binary_path('app')]
++-        except Exception as e:
+++        except Exception, e:
++             print("It looks like your program isn't built.",
++                 "You can run |mach build| to build it.")
++             print(e)
++@@ -772,7 +782,7 @@ class DebugProgram(MachCommandBase):
++         if debugger:
++             try:
++                 debugger = which.which(debugger)
++-            except Exception as e:
+++            except Exception, e:
++                 print("You don't have %s in your PATH" % (debugger))
++                 print(e)
++                 return 1
++@@ -784,7 +794,7 @@ class DebugProgram(MachCommandBase):
++                 try:
++                     debugger = which.which('lldb')
++                     use_lldb = True
++-                except Exception as e:
+++                except Exception, e:
++                     print("You don't have gdb or lldb in your PATH")
++                     print(e)
++                     return 1
++@@ -803,7 +813,7 @@ class DebugProgram(MachCommandBase):
++ 
++         try:
++             binpath = self.get_binary_path('app')
++-        except Exception as e:
+++        except Exception, e:
++             print("It looks like your program isn't built.",
++                 "You can run |mach build| to build it.")
++             print(e)
++@@ -883,7 +893,7 @@ class Makefiles(MachCommandBase):
++                 if not statements:
++                     print(relpath)
++             except pymake.parser.SyntaxError:
++-                print('Warning: Could not parse %s' % relpath, file=sys.stderr)
+++                print24('Warning: Could not parse %s' % relpath, file=sys.stderr)
++ 
++     def _makefile_ins(self):
++         for root, dirs, files in os.walk(self.topsrcdir):
++@@ -909,7 +919,7 @@ class MachDebug(MachCommandBase):
++ 
++         try:
++             mb = MozbuildObject.from_environment(cwd=self._mach_context.cwd)
++-        except ObjdirMismatchException as e:
+++        except ObjdirMismatchException, e:
++             print('Ambiguous object directory detected. We detected that '
++                 'both %s and %s could be object directories. This is '
++                 'typically caused by having a mozconfig pointing to a '
++@@ -924,11 +934,11 @@ class MachDebug(MachCommandBase):
++         try:
++             mozconfig = mb.mozconfig
++             print('mozconfig path:\n\t%s' % mozconfig['path'])
++-        except MozconfigFindException as e:
+++        except MozconfigFindException, e:
++             print('Unable to find mozconfig: %s' % e.message)
++             return 1
++ 
++-        except MozconfigLoadException as e:
+++        except MozconfigLoadException, e:
++             print('Error loading mozconfig: %s' % e.path)
++             print(e.message)
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/makeutil.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/makeutil.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/makeutil.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/makeutil.py	2014-10-24 11:41:35.492880087 -0600
++@@ -5,7 +5,9 @@
++ import os
++ import re
++ from types import StringTypes
++-from collections import Iterable
+++import rhrebase
+++print dir(rhrebase)
+++from rhrebase import isIterable
++ 
++ 
++ class Makefile(object):
++@@ -101,19 +103,23 @@ class Rule(object):
++ 
++     def add_targets(self, targets):
++         '''Add additional targets to the rule.'''
++-        assert isinstance(targets, Iterable) and not isinstance(targets, StringTypes)
+++        assert isIterable(targets) and not isinstance(targets, StringTypes)
++         self._targets.update(targets)
++         return self
++ 
++     def add_dependencies(self, deps):
++         '''Add dependencies to the rule.'''
++-        assert isinstance(deps, Iterable) and not isinstance(deps, StringTypes)
+++        #import traceback
+++        #traceback.print_stack()
+++        #print (deps)
+++        #print (dir(deps))
+++        assert isIterable(deps) and not isinstance(deps, StringTypes)
++         self._dependencies.update(deps)
++         return self
++ 
++     def add_commands(self, commands):
++         '''Add commands to the rule.'''
++-        assert isinstance(commands, Iterable) and not isinstance(commands, StringTypes)
+++        assert isIterable(commands) and not isinstance(commands, StringTypes)
++         self._commands.extend(commands)
++         return self
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/mozconfig.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/mozconfig.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/mozconfig.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/mozconfig.py	2014-10-24 11:41:35.493880083 -0600
++@@ -2,14 +2,14 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import filecmp
++ import os
++ import re
++ import subprocess
++ 
++-from collections import defaultdict
+++from mycollections import defaultdict
++ from mach.mixin.process import ProcessExecutionMixin
++ 
++ 
++@@ -215,9 +215,10 @@ class MozconfigLoader(ProcessExecutionMi
++         try:
++             # We need to capture stderr because that's where the shell sends
++             # errors if execution fails.
++-            output = subprocess.check_output(args, stderr=subprocess.STDOUT,
++-                cwd=self.topsrcdir, env=env)
++-        except subprocess.CalledProcessError as e:
+++            output = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.topsrcdir, env=env).communicate()[0]
+++            #output = subprocess.check_output(args, stderr=subprocess.STDOUT,
+++            #    cwd=self.topsrcdir, env=env)
+++        except subprocess.CalledProcessError, e:
++             lines = e.output.splitlines()
++ 
++             # Output before actual execution shouldn't be relevant.
++@@ -396,7 +397,11 @@ class MozconfigLoader(ProcessExecutionMi
++                             current.append(value)
++                             continue
++                         else:
++-                            value = value[:-1] if has_quote else value
+++                            #value = None
+++                            if has_quote:
+++                              value = value[:-1]
+++                            else:
+++                              value = value
++ 
++                 assert name is not None
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/mozinfo.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/mozinfo.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/mozinfo.py.python3	2014-10-24 11:41:35.411880430 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/mozinfo.py	2014-10-24 11:41:35.493880083 -0600
++@@ -7,7 +7,7 @@
++ 
++ import os
++ import re
++-import json
+++import simplejson as json
++ import mozbuild.mozconfig as mozconfig
++ 
++ def build_dict(config, env=os.environ):
++@@ -36,7 +36,7 @@ def build_dict(config, env=os.environ):
++     known_os = {"Linux": "linux",
++                 "WINNT": "win",
++                 "Darwin": "mac",
++-                "Android": "b2g" if substs["MOZ_WIDGET_TOOLKIT"] == "gonk" else "android"}
+++                "Android": ("android", "b2g")[substs["MOZ_WIDGET_TOOLKIT"] == "gonk"]}
++     if o in known_os:
++         d["os"] = known_os[o]
++     else:
++@@ -91,7 +91,7 @@ def build_dict(config, env=os.environ):
++     return d
++ 
++ 
++-def write_mozinfo(file, config, env=os.environ):
+++def write_mozinfo(_file, config, env=os.environ):
++     """Write JSON data about the configuration specified in config and an
++     environment variable dict to |file|, which may be a filename or file-like
++     object.
++@@ -99,8 +99,9 @@ def write_mozinfo(file, config, env=os.e
++     and what keys are produced.
++     """
++     build_conf = build_dict(config, env)
++-    if isinstance(file, basestring):
++-        with open(file, "w") as f:
++-            json.dump(build_conf, f)
+++    if isinstance(_file, basestring):
+++        f = open(_file, "w")
+++        json.dump(build_conf, f)
+++        f.close()
++     else:
++-        json.dump(build_conf, file)
+++        json.dump(build_conf, _file)
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/preprocessor.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/preprocessor.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/preprocessor.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/preprocessor.py	2014-10-24 11:41:35.493880083 -0600
++@@ -241,7 +241,7 @@ class Expression:
++             self.offset = expression.offset
++             self.content = expression.content[:3]
++         def __str__(self):
++-            return 'Unexpected content at offset {0}, "{1}"'.format(self.offset,
+++            return 'Unexpected content at offset %d, "%s"' % (self.offset,
++                                                                     self.content)
++ 
++ class Context(dict):
++@@ -320,9 +320,9 @@ class Preprocessor:
++ 
++     def warnUnused(self, file):
++         if self.actionLevel == 0:
++-            sys.stderr.write('{0}: WARNING: no preprocessor directives found\n'.format(file))
+++            sys.stderr.write('%s: WARNING: no preprocessor directives found\n' % (file))
++         elif self.actionLevel == 1:
++-            sys.stderr.write('{0}: WARNING: no useful preprocessor directives found\n'.format(file))
+++            sys.stderr.write('%s: WARNING: no useful preprocessor directives found\n' % (file))
++         pass
++ 
++     def setLineEndings(self, aLE):
++@@ -339,8 +339,9 @@ class Preprocessor:
++         """
++         self.marker = aMarker
++         if aMarker:
++-            self.instruction = re.compile('{0}(?P<cmd>[a-z]+)(?:\s(?P<args>.*))?$'
++-                                          .format(aMarker),
+++            #self.instruction = re.compile('%s{0}(?P<cmd>[a-z]+)(?:\s(?P<args>.*))?$'
+++            self.instruction = re.compile('%s(?P<cmd>[a-z]+)(?:\s(?P<args>.*))?$'
+++                                          % aMarker,
++                                           re.U)
++             self.comment = re.compile(aMarker, re.U)
++         else:
++@@ -414,9 +415,7 @@ class Preprocessor:
++             self.writtenLines += 1
++             ln = self.context['LINE']
++             if self.writtenLines != ln:
++-                self.out.write('//@line {line} "{file}"{le}'.format(line=ln,
++-                                                                    file=self.context['FILE'],
++-                                                                    le=self.LE))
+++                self.out.write('//@line %s "%s"%s' % (ln, self.context['FILE'], self.LE))
++                 self.writtenLines = ln
++         filteredLine = self.applyFilters(aLine)
++         if filteredLine != aLine:
++@@ -436,7 +435,7 @@ class Preprocessor:
++             if dir:
++                 try:
++                     os.makedirs(dir)
++-                except OSError as error:
+++                except OSError, error:
++                     if error.errno != errno.EEXIST:
++                         raise
++             return open(path, 'wb')
++@@ -468,8 +467,10 @@ class Preprocessor:
++ 
++         if includes:
++             for f in includes:
++-                with open(f, 'rU') as input:
+++                input = open(f, 'rU')
+++                if 1:
++                     self.processFile(input=input, output=out)
+++                input.close()
++             if depfile:
++                 mk = Makefile()
++                 mk.create_rule([options.output]).add_dependencies(self.includes)
++@@ -793,10 +794,12 @@ def preprocess(includes=[sys.stdin], def
++                       defines=defines,
++                       marker=marker)
++     for f in includes:
++-        with open(f, 'rU') as input:
+++        input = open(f, 'rU')
+++        if 1:
++             pp.processFile(input=input, output=output)
++ 
++ 
+++        input.close()
++ # Keep this module independently executable.
++ if __name__ == "__main__":
++     pp = Preprocessor()
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/pythonutil.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/pythonutil.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/pythonutil.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/pythonutil.py	2014-10-24 11:41:35.493880083 -0600
++@@ -1,4 +1,5 @@
++-# This Source Code Form is subject to the terms of the Mozilla Public
+++from rhrebase import any
+++#from rhrebase import any#from rhrebase import any#from rhrebase import any# This Source Code Form is subject to the terms of the Mozilla Public
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/sphinx.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/sphinx.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/sphinx.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/sphinx.py	2014-10-24 11:41:35.493880083 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import absolute_import
+++
++ 
++ import importlib
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/backend/common.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/backend/common.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/backend/common.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/backend/common.py	2014-10-24 11:41:35.494880079 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import os
++ import unittest
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/backend/test_android_eclipse.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/backend/test_android_eclipse.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/backend/test_android_eclipse.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/backend/test_android_eclipse.py	2014-10-24 11:41:35.494880079 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import json
++ import os
++@@ -64,8 +64,10 @@ class TestAndroidEclipseBackend(BackendT
++         self.env = self._consume('android_eclipse', AndroidEclipseBackend)
++         self.assertExists('main3', '.classpath')
++         # This is brittle but simple.
++-        with open(mozpath.join(self.env.topobjdir, 'android_eclipse', 'main3', '.classpath'), 'rt') as fh:
+++        fh = open(mozpath.join(self.env.topobjdir, 'android_eclipse', 'main3', '.classpath'), 'rt')
+++        if 1:
++             lines = fh.readlines()
+++        fh.__exit__(0, 0, 0)
++         lines = [line.strip() for line in lines]
++         self.assertIn('<classpathentry including="**/*.java" kind="src" path="a" />', lines)
++         self.assertIn('<classpathentry excluding="b/Excludes.java|b/Excludes2.java" including="**/*.java" kind="src" path="b" />', lines)
++@@ -76,14 +78,18 @@ class TestAndroidEclipseBackend(BackendT
++         self.env = self._consume('android_eclipse', AndroidEclipseBackend)
++ 
++         self.assertExists('library1', 'project.properties')
++-        with open(mozpath.join(self.env.topobjdir, 'android_eclipse', 'library1', 'project.properties'), 'rt') as fh:
+++        fh = open(mozpath.join(self.env.topobjdir, 'android_eclipse', 'library1', 'project.properties'), 'rt')
+++        if 1:
++             lines = fh.readlines()
+++        fh.__exit__(0, 0, 0)
++         lines = [line.strip() for line in lines]
++         self.assertIn('android.library=true', lines)
++ 
++         self.assertExists('main1', 'project.properties')
++-        with open(mozpath.join(self.env.topobjdir, 'android_eclipse', 'main1', 'project.properties'), 'rt') as fh:
+++        fh = open(mozpath.join(self.env.topobjdir, 'android_eclipse', 'main1', 'project.properties'), 'rt').__enter__()
+++        if 1:
++             lines = fh.readlines()
+++        fh.__exit__(0, 0, 0)
++         lines = [line.strip() for line in lines]
++         self.assertNotIn('android.library=true', lines)
++ 
++@@ -92,8 +98,10 @@ class TestAndroidEclipseBackend(BackendT
++         self.env = self._consume('android_eclipse', AndroidEclipseBackend)
++         self.assertExists('main4', '.classpath')
++         # This is brittle but simple.
++-        with open(mozpath.join(self.env.topobjdir, 'android_eclipse', 'main4', '.classpath'), 'rt') as fh:
+++        fh = open(mozpath.join(self.env.topobjdir, 'android_eclipse', 'main4', '.classpath'), 'rt').__enter__()
+++        if 1:
++             lines = fh.readlines()
+++        fh.__exit__(0, 0, 0)
++         lines = [line.strip() for line in lines]
++         self.assertIn('<classpathentry combineaccessrules="false" kind="src" path="/library1" />', lines)
++ 
++@@ -102,8 +110,10 @@ class TestAndroidEclipseBackend(BackendT
++         self.env = self._consume('android_eclipse', AndroidEclipseBackend)
++         self.assertExists('main2', '.classpath')
++         # This is brittle but simple.
++-        with open(mozpath.join(self.env.topobjdir, 'android_eclipse', 'main2', '.classpath'), 'rt') as fh:
+++        fh = open(mozpath.join(self.env.topobjdir, 'android_eclipse', 'main2', '.classpath'), 'rt').__enter__()
+++        if 1:
++             lines = fh.readlines()
+++        fh.close()
++         lines = [line.strip() for line in lines]
++         self.assertIn('<classpathentry exported="true" kind="lib" path="%s/main2/extra.jar" />' % self.env.topsrcdir, lines)
++ 
++@@ -112,8 +122,10 @@ class TestAndroidEclipseBackend(BackendT
++         self.env = self._consume('android_eclipse', AndroidEclipseBackend)
++         self.assertExists('main4', 'project.properties')
++         # This is brittle but simple.
++-        with open(mozpath.join(self.env.topobjdir, 'android_eclipse', 'main4', 'project.properties'), 'rt') as fh:
+++        fh = open(mozpath.join(self.env.topobjdir, 'android_eclipse', 'main4', 'project.properties'), 'rt').__enter__()
+++        if 1:
++             lines = fh.readlines()
+++        fh.close()
++         lines = [line.strip() for line in lines]
++         self.assertIn('android.library.reference.1=library2', lines)
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/backend/test_recursivemake.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/backend/test_recursivemake.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/backend/test_recursivemake.py	2014-10-24 11:41:35.494880079 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import json
++ import os
++@@ -414,7 +414,8 @@ class TestRecursiveMakeBackend(BackendTe
++         all_tests_path = mozpath.join(env.topobjdir, 'all-tests.json')
++         self.assertTrue(os.path.exists(all_tests_path))
++ 
++-        with open(all_tests_path, 'rt') as fh:
+++        fh = open(all_tests_path, 'rt')
+++        if 1:
++             o = json.load(fh)
++ 
++             self.assertIn('xpcshell.js', o)
++@@ -422,6 +423,7 @@ class TestRecursiveMakeBackend(BackendTe
++ 
++             self.assertEqual(len(o['xpcshell.js']), 1)
++ 
+++        fh.__exit__(0, 0, 0)
++     def test_test_manifest_pattern_matches_recorded(self):
++         """Pattern matches in test manifests' support-files should be recorded."""
++         env = self._consume('test-manifests-written', RecursiveMakeBackend)
++@@ -588,8 +590,7 @@ class TestRecursiveMakeBackend(BackendTe
++         for key, expected_rules in expected.iteritems():
++             backend_path = mozpath.join(key, 'backend.mk')
++             lines = [l.strip() for l in open(backend_path, 'rt').readlines()[2:]]
++-            found = [str for str in lines if
++-                str.startswith('FINAL_TARGET') or str.startswith('XPI_NAME') or
+++            found = [str for str in lines if str.startswith('FINAL_TARGET') or str.startswith('XPI_NAME') or
++                 str.startswith('DIST_SUBDIR')]
++             self.assertEqual(found, expected_rules)
++ 
++@@ -627,9 +628,11 @@ class TestRecursiveMakeBackend(BackendTe
++     def test_jar_manifests(self):
++         env = self._consume('jar-manifests', RecursiveMakeBackend)
++ 
++-        with open(os.path.join(env.topobjdir, 'backend.mk'), 'rb') as fh:
+++        fh = open(os.path.join(env.topobjdir, 'backend.mk'), 'rb')
+++        if 1:
++             lines = fh.readlines()
++ 
+++        fh.__exit__(0, 0, 0)
++         lines = [line.rstrip() for line in lines]
++ 
++         self.assertIn('JAR_MANIFEST := %s/jar.mn' % env.topsrcdir, lines)
++@@ -646,9 +649,11 @@ class TestRecursiveMakeBackend(BackendTe
++     def test_android_eclipse(self):
++         env = self._consume('android_eclipse', RecursiveMakeBackend)
++ 
++-        with open(mozpath.join(env.topobjdir, 'backend.mk'), 'rb') as fh:
+++        fh = open(mozpath.join(env.topobjdir, 'backend.mk'), 'rb').__enter__()
+++        if 1:
++             lines = fh.readlines()
++ 
+++        fh.close()
++         lines = [line.rstrip() for line in lines]
++ 
++         # Dependencies first.
++@@ -664,9 +669,11 @@ class TestRecursiveMakeBackend(BackendTe
++             self.assertIn(command_template % (stem, stem), lines)
++ 
++         # Projects declared in subdirectories.
++-        with open(mozpath.join(env.topobjdir, 'subdir', 'backend.mk'), 'rb') as fh:
+++        fh = open(mozpath.join(env.topobjdir, 'subdir', 'backend.mk'), 'rb').__enter__()
+++        if 1:
++             lines = fh.readlines()
++ 
+++        fh.close()
++         lines = [line.rstrip() for line in lines]
++ 
++         self.assertIn('ANDROID_ECLIPSE_PROJECT_submain: subtarget1 subtarget2', lines)
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/backend/test_visualstudio.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/backend/test_visualstudio.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/backend/test_visualstudio.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/backend/test_visualstudio.py	2014-10-24 11:41:35.494880079 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ from xml.dom.minidom import parse
++ import os
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/common.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/common.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/common.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/common.py	2014-10-24 11:41:35.495880074 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import os
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/compilation/test_warnings.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/compilation/test_warnings.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/compilation/test_warnings.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/compilation/test_warnings.py	2014-10-24 11:41:35.495880074 -0600
++@@ -181,9 +181,11 @@ class TestWarningsDatabase(unittest.Test
++ 
++         w['filename'] = 'DOES_NOT_EXIST'
++ 
++-        with self.assertRaises(Exception):
+++        self.assertRaises(Exception).__enter__()
+++        if 1:
++             db.insert(w)
++ 
+++        self.assertRaises(Exception).__exit__(0, 0, 0)
++     def test_pruning(self):
++         """Ensure old warnings are removed from database appropriately."""
++         db = WarningsDatabase()
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/controller/test_clobber.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/controller/test_clobber.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/controller/test_clobber.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/controller/test_clobber.py	2014-10-24 11:41:35.495880074 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import os
++ import shutil
++@@ -37,9 +37,11 @@ class TestClobberer(unittest.TestCase):
++     def get_topsrcdir(self):
++         t = self.get_tempdir()
++         p = os.path.join(t, 'CLOBBER')
++-        with open(p, 'a'):
+++        open(p, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(p, 'a').__exit__(0, 0, 0)
++         return t
++ 
++     def test_no_objdir(self):
++@@ -77,9 +79,11 @@ class TestClobberer(unittest.TestCase):
++         """If CLOBBER in topobjdir is newer, do nothing."""
++ 
++         c = Clobberer(self.get_topsrcdir(), self.get_tempdir())
++-        with open(c.obj_clobber, 'a'):
+++        open(c.obj_clobber, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(c.obj_clobber, 'a').__exit__(0, 0, 0)
++         required, performed, reason = c.maybe_do_clobber(os.getcwd(), True)
++         self.assertFalse(required)
++         self.assertFalse(performed)
++@@ -89,13 +93,17 @@ class TestClobberer(unittest.TestCase):
++         """If CLOBBER in topobjdir is older, we clobber."""
++ 
++         c = Clobberer(self.get_topsrcdir(), self.get_tempdir())
++-        with open(c.obj_clobber, 'a'):
+++        open(c.obj_clobber, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(c.obj_clobber, 'a').__exit__(0, 0, 0)
++         dummy_path = os.path.join(c.topobjdir, 'foo')
++-        with open(dummy_path, 'a'):
+++        open(dummy_path, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(dummy_path, 'a').__exit__(0, 0, 0)
++         self.assertTrue(os.path.exists(dummy_path))
++ 
++         old_time = os.path.getmtime(c.src_clobber) - 60
++@@ -124,13 +132,17 @@ class TestClobberer(unittest.TestCase):
++         """If cwd is topobjdir, we can still clobber."""
++         c = Clobberer(self.get_topsrcdir(), self.get_tempdir())
++ 
++-        with open(c.obj_clobber, 'a'):
+++        open(c.obj_clobber, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(c.obj_clobber, 'a').__exit__(0, 0, 0)
++         dummy_file = os.path.join(c.topobjdir, 'dummy_file')
++-        with open(dummy_file, 'a'):
+++        open(dummy_file, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(dummy_file, 'a').__exit__(0, 0, 0)
++         dummy_dir = os.path.join(c.topobjdir, 'dummy_dir')
++         os.mkdir(dummy_dir)
++ 
++@@ -154,9 +166,11 @@ class TestClobberer(unittest.TestCase):
++ 
++         c = Clobberer(self.get_topsrcdir(), self.get_tempdir())
++ 
++-        with open(c.obj_clobber, 'a'):
+++        open(c.obj_clobber, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(c.obj_clobber, 'a').__exit__(0, 0, 0)
++         old_time = os.path.getmtime(c.src_clobber) - 60
++         os.utime(c.obj_clobber, (old_time, old_time))
++ 
++@@ -176,13 +190,17 @@ class TestClobberer(unittest.TestCase):
++         topobjdir = self.get_tempdir()
++ 
++         obj_clobber = os.path.join(topobjdir, 'CLOBBER')
++-        with open(obj_clobber, 'a'):
+++        open(obj_clobber, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(obj_clobber, 'a').__exit__(0, 0, 0)
++         dummy_file = os.path.join(topobjdir, 'dummy_file')
++-        with open(dummy_file, 'a'):
+++        open(dummy_file, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(dummy_file, 'a').__exit__(0, 0, 0)
++         self.assertTrue(os.path.exists(dummy_file))
++ 
++         old_time = os.path.getmtime(os.path.join(topsrcdir, 'CLOBBER')) - 60
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/frontend/test_emitter.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/frontend/test_emitter.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/frontend/test_emitter.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/frontend/test_emitter.py	2014-10-24 11:41:35.495880074 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import os
++ import unittest
++@@ -299,17 +299,21 @@ class TestEmitterBasic(unittest.TestCase
++         """A missing manifest file should result in an error."""
++         reader = self.reader('test-manifest-missing-manifest')
++ 
++-        with self.assertRaisesRegexp(SandboxValidationError, 'IOError: Missing files'):
+++        self.assertRaisesRegexp(SandboxValidationError, 'IOError: Missing files').__enter__()
+++        if 1:
++             self.read_topsrcdir(reader)
++ 
+++        self.assertRaisesRegexp(SandboxValidationError, 'IOError: Missing files').__exit__(0, 0, 0)
++     def test_empty_test_manifest_rejected(self):
++         """A test manifest without any entries is rejected."""
++         reader = self.reader('test-manifest-empty')
++ 
++-        with self.assertRaisesRegexp(SandboxValidationError, 'Empty test manifest'):
+++        self.assertRaisesRegexp(SandboxValidationError, 'Empty test manifest').__enter__()
+++        if 1:
++             self.read_topsrcdir(reader)
++ 
++ 
+++        self.assertRaisesRegexp(SandboxValidationError, 'Empty test manifest').__exit__(0, 0, 0)
++     def test_test_manifest_just_support_files(self):
++         """A test manifest with no tests but support-files is supported."""
++         reader = self.reader('test-manifest-just-support')
++@@ -592,10 +596,12 @@ class TestEmitterBasic(unittest.TestCase
++             self.assertTrue(os.path.isabs(obj.path))
++ 
++     def test_jar_manifests_multiple_files(self):
++-        with self.assertRaisesRegexp(SandboxValidationError, 'limited to one value'):
+++        self.assertRaisesRegexp(SandboxValidationError, 'limited to one value').__enter__()
+++        if 1:
++             reader = self.reader('jar-manifests-multiple-files')
++             self.read_topsrcdir(reader)
++ 
+++        self.assertRaisesRegexp(SandboxValidationError, 'limited to one value').__exit__(0, 0, 0)
++     def test_xpidl_module_no_sources(self):
++         """XPIDL_MODULE without XPIDL_SOURCES should be rejected."""
++         with self.assertRaisesRegexp(SandboxValidationError, 'XPIDL_MODULE '
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/frontend/test_namespaces.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/frontend/test_namespaces.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/frontend/test_namespaces.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/frontend/test_namespaces.py	2014-10-24 11:41:35.496880070 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import unittest
++ 
++@@ -27,9 +27,11 @@ class TestGlobalNamespace(unittest.TestC
++         # Lowercase keys should be rejected during normal operation.
++         ns = GlobalNamespace(allowed_variables=VARIABLES)
++ 
++-        with self.assertRaises(KeyError) as ke:
+++        ke = self.assertRaises(KeyError).__enter__()
+++        if 1:
++             ns['foo'] = True
++ 
+++        ke.__exit__(0, 0, 0)
++         e = ke.exception.args
++         self.assertEqual(e[0], 'global_ns')
++         self.assertEqual(e[1], 'set_unknown')
++@@ -37,9 +39,11 @@ class TestGlobalNamespace(unittest.TestC
++         self.assertTrue(e[3])
++ 
++         # Unknown uppercase keys should be rejected.
++-        with self.assertRaises(KeyError) as ke:
+++        ke = self.assertRaises(KeyError).__enter__()
+++        if 1:
++             ns['FOO'] = True
++ 
+++        ke.__exit__(0, 0, 0)
++         e = ke.exception.args
++         self.assertEqual(e[0], 'global_ns')
++         self.assertEqual(e[1], 'set_unknown')
++@@ -58,9 +62,11 @@ class TestGlobalNamespace(unittest.TestC
++         ns = GlobalNamespace(allowed_variables=VARIABLES)
++ 
++         # Setting to a non-allowed type should not work.
++-        with self.assertRaises(ValueError) as ve:
+++        ve = self.assertRaises(ValueError).__enter__()
+++        if 1:
++             ns['DIRS'] = True
++ 
+++        ve.__exit__(0, 0, 0)
++         e = ve.exception.args
++         self.assertEqual(e[0], 'global_ns')
++         self.assertEqual(e[1], 'set_type')
++@@ -71,28 +77,38 @@ class TestGlobalNamespace(unittest.TestC
++     def test_allow_all_writes(self):
++         ns = GlobalNamespace(allowed_variables=VARIABLES)
++ 
++-        with ns.allow_all_writes() as d:
+++        d = ns.allow_all_writes().__enter__()
+++        if 1:
++             d['foo'] = True
++             self.assertTrue(d['foo'])
++ 
++-        with self.assertRaises(KeyError) as ke:
+++        d.__exit__(0, 0, 0)
+++        ke = self.assertRaises(KeyError).__enter__()
+++        if 1:
++             ns['bar'] = False
++ 
+++        ke.__exit__(0, 0, 0)
++         self.assertEqual(ke.exception.args[1], 'set_unknown')
++ 
++         ns['DIRS'] = []
++-        with self.assertRaisesRegexp(Exception, 'Reassigning .* is forbidden') as ke:
+++        ke = self.assertRaisesRegexp(Exception, 'Reassigning .* is forbidden').__enter__()
+++        if 1:
++             ns['DIRS'] = []
++ 
++-        with ns.allow_all_writes() as d:
+++        ke.__exit__(0, 0, 0)
+++        d = ns.allow_all_writes().__enter__()
+++        if 1:
++             d['DIST_SUBDIR'] = 'foo'
++ 
+++        d.__exit__(0, 0, 0)
++         self.assertEqual(ns['DIST_SUBDIR'], 'foo')
++         ns['DIST_SUBDIR'] = 'bar'
++         self.assertEqual(ns['DIST_SUBDIR'], 'bar')
++-        with self.assertRaisesRegexp(Exception, 'Reassigning .* is forbidden') as ke:
+++        ke = self.assertRaisesRegexp(Exception, 'Reassigning .* is forbidden').__enter__()
+++        if 1:
++             ns['DIST_SUBDIR'] = 'baz'
++ 
+++        ke.__exit__(0, 0, 0)
++         self.assertTrue(d['foo'])
++ 
++     def test_key_checking(self):
++@@ -124,9 +140,11 @@ class TestLocalNamespace(unittest.TestCa
++         self.assertEqual(l['DIRS'], g['DIRS'])
++ 
++         # Reads to missing UPPERCASE vars should result in KeyError.
++-        with self.assertRaises(KeyError) as ke:
+++        ke = self.assertRaises(KeyError).__enter__()
+++        if 1:
++             v = l['FOO']
++ 
+++        ke.__exit__(0, 0, 0)
++         e = ke.exception
++         self.assertEqual(e.args[0], 'global_ns')
++         self.assertEqual(e.args[1], 'get_unknown')
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/frontend/test_reader.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/frontend/test_reader.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/frontend/test_reader.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/frontend/test_reader.py	2014-10-24 11:41:35.496880070 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import os
++ import sys
++@@ -85,9 +85,11 @@ class TestBuildReader(unittest.TestCase)
++         # add_tier_dir() should fail when not in the top directory.
++         reader = self.reader('traversal-tier-fails-in-subdir')
++ 
++-        with self.assertRaises(Exception):
+++        self.assertRaises(Exception).__enter__()
+++        if 1:
++             list(reader.read_topsrcdir())
++ 
+++        self.assertRaises(Exception).__exit__(0, 0, 0)
++     def test_relative_dirs(self):
++         # Ensure relative directories are traversed.
++         reader = self.reader('traversal-relative-dirs')
++@@ -106,15 +108,19 @@ class TestBuildReader(unittest.TestCase)
++         # References to directories outside the topsrcdir should fail.
++         reader = self.reader('traversal-outside-topsrcdir')
++ 
++-        with self.assertRaises(Exception):
+++        self.assertRaises(Exception).__enter__()
+++        if 1:
++             list(reader.read_topsrcdir())
++ 
+++        self.assertRaises(Exception).__exit__(0, 0, 0)
++     def test_error_basic(self):
++         reader = self.reader('reader-error-basic')
++ 
++-        with self.assertRaises(BuildReaderError) as bre:
+++        bre = self.assertRaises(BuildReaderError).__enter__()
+++        if 1:
++             list(reader.read_topsrcdir())
++ 
+++        bre.__exit__(0, 0, 0)
++         e = bre.exception
++         self.assertEqual(e.actual_file, self.file_path('reader-error-basic',
++             'moz.build'))
++@@ -124,9 +130,11 @@ class TestBuildReader(unittest.TestCase)
++     def test_error_included_from(self):
++         reader = self.reader('reader-error-included-from')
++ 
++-        with self.assertRaises(BuildReaderError) as bre:
+++        bre = self.assertRaises(BuildReaderError).__enter__()
+++        if 1:
++             list(reader.read_topsrcdir())
++ 
+++        bre.__exit__(0, 0, 0)
++         e = bre.exception
++         self.assertEqual(e.actual_file,
++             self.file_path('reader-error-included-from', 'child.build'))
++@@ -138,9 +146,11 @@ class TestBuildReader(unittest.TestCase)
++     def test_error_syntax_error(self):
++         reader = self.reader('reader-error-syntax')
++ 
++-        with self.assertRaises(BuildReaderError) as bre:
+++        bre = self.assertRaises(BuildReaderError).__enter__()
+++        if 1:
++             list(reader.read_topsrcdir())
++ 
+++        bre.__exit__(0, 0, 0)
++         e = bre.exception
++         self.assertIn('Python syntax error on line 5', str(e))
++         self.assertIn('    foo =', str(e))
++@@ -149,9 +159,11 @@ class TestBuildReader(unittest.TestCase)
++     def test_error_read_unknown_global(self):
++         reader = self.reader('reader-error-read-unknown-global')
++ 
++-        with self.assertRaises(BuildReaderError) as bre:
+++        bre = self.assertRaises(BuildReaderError).__enter__()
+++        if 1:
++             list(reader.read_topsrcdir())
++ 
+++        bre.__exit__(0, 0, 0)
++         e = bre.exception
++         self.assertIn('The error was triggered on line 5', str(e))
++         self.assertIn('The underlying problem is an attempt to read', str(e))
++@@ -160,9 +172,11 @@ class TestBuildReader(unittest.TestCase)
++     def test_error_write_unknown_global(self):
++         reader = self.reader('reader-error-write-unknown-global')
++ 
++-        with self.assertRaises(BuildReaderError) as bre:
+++        bre = self.assertRaises(BuildReaderError).__enter__()
+++        if 1:
++             list(reader.read_topsrcdir())
++ 
+++        bre.__exit__(0, 0, 0)
++         e = bre.exception
++         self.assertIn('The error was triggered on line 7', str(e))
++         self.assertIn('The underlying problem is an attempt to write', str(e))
++@@ -171,9 +185,11 @@ class TestBuildReader(unittest.TestCase)
++     def test_error_write_bad_value(self):
++         reader = self.reader('reader-error-write-bad-value')
++ 
++-        with self.assertRaises(BuildReaderError) as bre:
+++        bre = self.assertRaises(BuildReaderError).__enter__()
+++        if 1:
++             list(reader.read_topsrcdir())
++ 
+++        bre.__exit__(0, 0, 0)
++         e = bre.exception
++         self.assertIn('The error was triggered on line 5', str(e))
++         self.assertIn('is an attempt to write an illegal value to a special',
++@@ -190,9 +206,11 @@ class TestBuildReader(unittest.TestCase)
++     def test_error_illegal_path(self):
++         reader = self.reader('reader-error-outside-topsrcdir')
++ 
++-        with self.assertRaises(BuildReaderError) as bre:
+++        bre = self.assertRaises(BuildReaderError).__enter__()
+++        if 1:
++             list(reader.read_topsrcdir())
++ 
+++        bre.__exit__(0, 0, 0)
++         e = bre.exception
++         self.assertIn('The underlying problem is an illegal file access',
++             str(e))
++@@ -200,18 +218,22 @@ class TestBuildReader(unittest.TestCase)
++     def test_error_missing_include_path(self):
++         reader = self.reader('reader-error-missing-include')
++ 
++-        with self.assertRaises(BuildReaderError) as bre:
+++        bre = self.assertRaises(BuildReaderError).__enter__()
+++        if 1:
++             list(reader.read_topsrcdir())
++ 
+++        bre.__exit__(0, 0, 0)
++         e = bre.exception
++         self.assertIn('we referenced a path that does not exist', str(e))
++ 
++     def test_error_script_error(self):
++         reader = self.reader('reader-error-script-error')
++ 
++-        with self.assertRaises(BuildReaderError) as bre:
+++        bre = self.assertRaises(BuildReaderError).__enter__()
+++        if 1:
++             list(reader.read_topsrcdir())
++ 
+++        bre.__exit__(0, 0, 0)
++         e = bre.exception
++         self.assertIn('The error appears to be the fault of the script',
++             str(e))
++@@ -220,18 +242,22 @@ class TestBuildReader(unittest.TestCase)
++     def test_error_bad_dir(self):
++         reader = self.reader('reader-error-bad-dir')
++ 
++-        with self.assertRaises(BuildReaderError) as bre:
+++        bre = self.assertRaises(BuildReaderError).__enter__()
+++        if 1:
++             list(reader.read_topsrcdir())
++ 
+++        bre.__exit__(0, 0, 0)
++         e = bre.exception
++         self.assertIn('we referenced a path that does not exist', str(e))
++ 
++     def test_error_repeated_dir(self):
++         reader = self.reader('reader-error-repeated-dir')
++ 
++-        with self.assertRaises(BuildReaderError) as bre:
+++        bre = self.assertRaises(BuildReaderError).__enter__()
+++        if 1:
++             list(reader.read_topsrcdir())
++ 
+++        bre.__exit__(0, 0, 0)
++         e = bre.exception
++         self.assertIn('Directory (foo) registered multiple times in DIRS',
++             str(e))
++@@ -239,9 +265,11 @@ class TestBuildReader(unittest.TestCase)
++     def test_error_error_func(self):
++         reader = self.reader('reader-error-error-func')
++ 
++-        with self.assertRaises(BuildReaderError) as bre:
+++        bre = self.assertRaises(BuildReaderError).__enter__()
+++        if 1:
++             list(reader.read_topsrcdir())
++ 
+++        bre.__exit__(0, 0, 0)
++         e = bre.exception
++         self.assertIn('A moz.build file called the error() function.', str(e))
++         self.assertIn('    Some error.', str(e))
++@@ -249,9 +277,11 @@ class TestBuildReader(unittest.TestCase)
++     def test_error_traversal_tools(self):
++         reader = self.reader('reader-error-traversal-tools')
++ 
++-        with self.assertRaises(BuildReaderError) as bre:
+++        bre = self.assertRaises(BuildReaderError).__enter__()
+++        if 1:
++             list(reader.read_topsrcdir())
++ 
+++        bre.__exit__(0, 0, 0)
++         e = bre.exception
++         self.assertIn('The DIRS variable is not allowed in such directories.', str(e))
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/frontend/test_sandbox.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/frontend/test_sandbox.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/frontend/test_sandbox.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/frontend/test_sandbox.py	2014-10-24 11:41:35.496880070 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import os
++ import shutil
++@@ -95,9 +95,11 @@ class TestSandbox(unittest.TestCase):
++         self.assertIsNone(sandbox['CONFIG']['MISSING'])
++ 
++         # Should shouldn't be allowed to assign to the config.
++-        with self.assertRaises(Exception):
+++        self.assertRaises(Exception).__enter__()
+++        if 1:
++             sandbox['CONFIG']['FOO'] = ''
++ 
+++        self.assertRaises(Exception).__exit__(0, 0, 0)
++     def test_dict_interface(self):
++         sandbox = self.sandbox()
++         config = sandbox.config
++@@ -127,9 +129,11 @@ class TestSandbox(unittest.TestCase):
++     def test_exec_compile_error(self):
++         sandbox = self.sandbox()
++ 
++-        with self.assertRaises(SandboxExecutionError) as se:
+++        se = self.assertRaises(SandboxExecutionError).__enter__()
+++        if 1:
++             sandbox.exec_source('2f23;k;asfj', 'foo.py')
++ 
+++        se.__exit__(0, 0, 0)
++         self.assertEqual(se.exception.file_stack, ['foo.py'])
++         self.assertIsInstance(se.exception.exc_value, SyntaxError)
++         self.assertEqual(sandbox.main_path, 'foo.py')
++@@ -137,9 +141,11 @@ class TestSandbox(unittest.TestCase):
++     def test_exec_import_denied(self):
++         sandbox = self.sandbox()
++ 
++-        with self.assertRaises(SandboxExecutionError) as se:
+++        se = self.assertRaises(SandboxExecutionError).__enter__()
+++        if 1:
++             sandbox.exec_source('import sys', 'import.py')
++ 
+++        se.__exit__(0, 0, 0)
++         self.assertIsInstance(se.exception, SandboxExecutionError)
++         self.assertEqual(se.exception.exc_type, ImportError)
++ 
++@@ -154,9 +160,11 @@ class TestSandbox(unittest.TestCase):
++     def test_exec_source_illegal_key_set(self):
++         sandbox = self.sandbox()
++ 
++-        with self.assertRaises(SandboxExecutionError) as se:
+++        se = self.assertRaises(SandboxExecutionError).__enter__()
+++        if 1:
++             sandbox.exec_source('ILLEGAL = True', 'foo.py')
++ 
+++        se.__exit__(0, 0, 0)
++         e = se.exception
++         self.assertIsInstance(e.exc_value, KeyError)
++ 
++@@ -216,9 +224,11 @@ add_tier_dir('t1', 'bat', static=True)
++ 
++         sandbox.exec_source('add_tier_dir("t1", "foo")', 'foo.py')
++ 
++-        with self.assertRaises(SandboxExecutionError):
+++        self.assertRaises(SandboxExecutionError).__enter__()
+++        if 1:
++             sandbox.exec_source('add_tier_dir("t1", "foo")', 'foo.py')
++ 
+++        self.assertRaises(SandboxExecutionError).__exit__(0, 0, 0)
++     def test_include_basic(self):
++         sandbox = self.sandbox(data_path='include-basic')
++ 
++@@ -232,9 +242,11 @@ add_tier_dir('t1', 'bat', static=True)
++     def test_include_outside_topsrcdir(self):
++         sandbox = self.sandbox(data_path='include-outside-topsrcdir')
++ 
++-        with self.assertRaises(SandboxLoadError) as se:
+++        se = self.assertRaises(SandboxLoadError).__enter__()
+++        if 1:
++             sandbox.exec_file('relative.build')
++ 
+++        se.__exit__(0, 0, 0)
++         expected = mozpath.join(test_data_path, 'moz.build')
++         self.assertEqual(se.exception.illegal_path, expected)
++ 
++@@ -242,9 +254,11 @@ add_tier_dir('t1', 'bat', static=True)
++         # Ensure the path stack is reported properly in exceptions.
++         sandbox = self.sandbox(data_path='include-file-stack')
++ 
++-        with self.assertRaises(SandboxExecutionError) as se:
+++        se = self.assertRaises(SandboxExecutionError).__enter__()
+++        if 1:
++             sandbox.exec_file('moz.build')
++ 
+++        se.__exit__(0, 0, 0)
++         e = se.exception
++         self.assertIsInstance(e.exc_value, KeyError)
++ 
++@@ -261,9 +275,11 @@ add_tier_dir('t1', 'bat', static=True)
++     def test_include_missing(self):
++         sandbox = self.sandbox(data_path='include-missing')
++ 
++-        with self.assertRaises(SandboxLoadError) as sle:
+++        sle = self.assertRaises(SandboxLoadError).__enter__()
+++        if 1:
++             sandbox.exec_file('moz.build')
++ 
+++        sle.__exit__(0, 0, 0)
++         self.assertIsNotNone(sle.exception.read_error)
++ 
++     def test_include_relative_from_child_dir(self):
++@@ -288,9 +304,11 @@ add_tier_dir('t1', 'bat', static=True)
++     def test_error(self):
++         sandbox = self.sandbox()
++ 
++-        with self.assertRaises(SandboxCalledError) as sce:
+++        sce = self.assertRaises(SandboxCalledError).__enter__()
+++        if 1:
++             sandbox.exec_source('error("This is an error.")', 'test.py')
++ 
+++        sce.__exit__(0, 0, 0)
++         e = sce.exception
++         self.assertEqual(e.message, 'This is an error.')
++ 
++@@ -315,9 +333,11 @@ add_tier_dir('t1', 'bat', static=True)
++     def test_invalid_exports_set_base(self):
++         sandbox = self.sandbox()
++ 
++-        with self.assertRaises(SandboxExecutionError) as se:
+++        se = self.assertRaises(SandboxExecutionError).__enter__()
+++        if 1:
++             sandbox.exec_source('EXPORTS = "foo.h"', 'foo.py')
++ 
+++        se.__exit__(0, 0, 0)
++         self.assertEqual(se.exception.exc_type, ValueError)
++ 
++ if __name__ == '__main__':
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/testing.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/testing.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/testing.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/testing.py	2014-10-24 11:41:35.496880070 -0600
++@@ -2,15 +2,15 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import json
++ import os
++ 
++ import mozpack.path as mozpath
++ 
++-from .base import MozbuildObject
++-from .util import DefaultOnReadDict
+++from base import MozbuildObject
+++from util import DefaultOnReadDict
++ 
++ 
++ def rewrite_test_base(test, new_base, honor_install_to_subdir=False):
++@@ -49,7 +49,8 @@ class TestMetadata(object):
++         self._test_dirs = set()
++ 
++         if filename:
++-            with open(filename, 'rt') as fh:
+++            fh = open(filename, 'rt')
+++            if 1:
++                 d = json.load(fh)
++ 
++                 for path, tests in d.items():
++@@ -60,6 +61,7 @@ class TestMetadata(object):
++                         flavor = metadata.get('flavor')
++                         self._tests_by_flavor[flavor].add(path)
++ 
+++            fh.close()
++     def tests_with_flavor(self, flavor):
++         """Obtain all tests having the specified flavor.
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_base.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_base.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_base.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_base.py	2014-10-24 11:41:35.497880066 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import json
++ import os
++@@ -49,7 +49,8 @@ class TestMozbuildObject(unittest.TestCa
++     def test_objdir_config_guess(self):
++         base = self.get_base()
++ 
++-        with NamedTemporaryFile() as mozconfig:
+++        mozconfig = NamedTemporaryFile().__enter__()
+++        if 1:
++             os.environ[b'MOZCONFIG'] = mozconfig.name
++ 
++             self.assertIsNotNone(base.topobjdir)
++@@ -58,11 +59,13 @@ class TestMozbuildObject(unittest.TestCa
++             self.assertTrue(os.path.isabs(base.topobjdir))
++             self.assertTrue(base.topobjdir.startswith(topsrcdir))
++ 
+++        mozconfig.__exit__(0, 0, 0)
++     def test_objdir_trailing_slash(self):
++         """Trailing slashes in topobjdir should be removed."""
++         base = self.get_base()
++ 
++-        with NamedTemporaryFile() as mozconfig:
+++        mozconfig = NamedTemporaryFile().__enter__()
+++        if 1:
++             mozconfig.write('mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/foo/')
++             mozconfig.flush()
++             os.environ[b'MOZCONFIG'] = mozconfig.name
++@@ -71,6 +74,7 @@ class TestMozbuildObject(unittest.TestCa
++                 'foo'))
++             self.assertTrue(base.topobjdir.endswith('foo'))
++ 
+++        mozconfig.__exit__(0, 0, 0)
++     @unittest.skip('Failing on buildbot.')
++     def test_objdir_config_status(self):
++         """Ensure @CONFIG_GUESS@ is handled when loading mozconfig."""
++@@ -82,8 +86,10 @@ class TestMozbuildObject(unittest.TestCa
++         d = os.path.realpath(tempfile.mkdtemp())
++         try:
++             mozconfig = os.path.join(d, 'mozconfig')
++-            with open(mozconfig, 'wt') as fh:
+++            fh = open(mozconfig, 'wt')
+++            if 1:
++                 fh.write('mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/foo/@CONFIG_GUESS@')
+++            fh.__exit__(0, 0, 0)
++             print('Wrote mozconfig %s' % mozconfig)
++ 
++             topobjdir = os.path.join(d, 'foo', guess)
++@@ -96,12 +102,14 @@ class TestMozbuildObject(unittest.TestCa
++                 'config.guess',), guess_path)
++ 
++             mozinfo = os.path.join(topobjdir, 'mozinfo.json')
++-            with open(mozinfo, 'wt') as fh:
+++            fh = open(mozinfo, 'wt')
+++            if 1:
++                 json.dump(dict(
++                     topsrcdir=d,
++                     mozconfig=mozconfig,
++                 ), fh)
++ 
+++            fh.__exit__(0, 0, 0)
++             os.environ[b'MOZCONFIG'] = mozconfig
++             os.chdir(topobjdir)
++ 
++@@ -117,19 +125,23 @@ class TestMozbuildObject(unittest.TestCa
++         d = os.path.realpath(tempfile.mkdtemp())
++         try:
++             mozconfig = os.path.join(d, 'mozconfig')
++-            with open(mozconfig, 'wt') as fh:
+++            fh = open(mozconfig, 'wt').__enter__()
+++            if 1:
++                 fh.write('mk_add_options MOZ_OBJDIR=./objdir')
++ 
+++            fh.__exit__(0, 0, 0)
++             topobjdir = os.path.join(d, 'objdir')
++             os.mkdir(topobjdir)
++ 
++             mozinfo = os.path.join(topobjdir, 'mozinfo.json')
++-            with open(mozinfo, 'wt') as fh:
+++            fh = open(mozinfo, 'wt').__enter__()
+++            if 1:
++                 json.dump(dict(
++                     topsrcdir=d,
++                     mozconfig=mozconfig,
++                 ), fh)
++ 
+++            fh.__exit__(0, 0, 0)
++             os.environ[b'MOZCONFIG'] = mozconfig
++             child = os.path.join(topobjdir, 'foo', 'bar')
++             os.makedirs(child)
++@@ -154,16 +166,20 @@ class TestMozbuildObject(unittest.TestCa
++             os.symlink(topobjdir_real, topobjdir_link)
++ 
++             mozconfig = os.path.join(d, 'mozconfig')
++-            with open(mozconfig, 'wt') as fh:
+++            fh = open(mozconfig, 'wt').__enter__()
+++            if 1:
++                 fh.write('mk_add_options MOZ_OBJDIR=%s' % topobjdir_link)
++ 
+++            fh.__exit__(0, 0, 0)
++             mozinfo = os.path.join(topobjdir_real, 'mozinfo.json')
++-            with open(mozinfo, 'wt') as fh:
+++            fh = open(mozinfo, 'wt').__enter__()
+++            if 1:
++                 json.dump(dict(
++                     topsrcdir=d,
++                     mozconfig=mozconfig,
++                 ), fh)
++ 
+++            fh.__exit__(0, 0, 0)
++             os.chdir(topobjdir_link)
++             obj = MozbuildObject.from_environment(detect_virtualenv_mozinfo=False)
++             self.assertEqual(obj.topobjdir, topobjdir_real)
++@@ -189,11 +205,13 @@ class TestMozbuildObject(unittest.TestCa
++             os.makedirs(topsrcdir)
++ 
++             mozinfo = os.path.join(topobjdir, 'mozinfo.json')
++-            with open(mozinfo, 'wt') as fh:
+++            fh = open(mozinfo, 'wt').__enter__()
+++            if 1:
++                 json.dump(dict(
++                     topsrcdir=topsrcdir,
++                 ), fh)
++ 
+++            fh.close()
++             os.chdir(topobjdir)
++ 
++             class MockMachContext(object):
++@@ -222,14 +240,18 @@ class TestMozbuildObject(unittest.TestCa
++             # The easiest way to do this is to create a mozinfo.json with data
++             # that will never happen.
++             mozinfo = os.path.join(d, 'mozinfo.json')
++-            with open(mozinfo, 'wt') as fh:
+++            fh = open(mozinfo, 'wt').__enter__()
+++            if 1:
++                 json.dump({'topsrcdir': d}, fh)
++ 
+++            fh.close()
++             os.chdir(d)
++ 
++-            with self.assertRaises(BadEnvironmentException):
+++            self.assertRaises(BadEnvironmentException).__enter__()
+++            if 1:
++                 MozbuildObject.from_environment(detect_virtualenv_mozinfo=False)
++ 
+++            self.assertRaises(BadEnvironmentException).__exit__(0, 0, 0)
++         finally:
++             shutil.rmtree(d)
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_containers.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_containers.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_containers.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_containers.py	2014-10-24 11:41:35.497880066 -0600
++@@ -21,12 +21,16 @@ class TestReadOnlyDict(unittest.TestCase
++         self.assertEqual(original, test)
++         self.assertEqual(test['foo'], 1)
++ 
++-        with self.assertRaises(KeyError):
+++        self.assertRaises(KeyError).__enter__()
+++        if 1:
++             value = test['missing']
++ 
++-        with self.assertRaises(Exception):
+++        self.assertRaises(KeyError).__exit__(0, 0, 0)
+++        self.assertRaises(Exception).__enter__()
+++        if 1:
++             test['baz'] = True
++ 
+++        self.assertRaises(Exception).__exit__(0, 0, 0)
++ class TestDefaultOnReadDict(unittest.TestCase):
++     def test_no_defaults(self):
++         original = {'foo': 1, 'bar': 2}
++@@ -34,9 +38,11 @@ class TestDefaultOnReadDict(unittest.Tes
++         test = DefaultOnReadDict(original)
++         self.assertEqual(original, test)
++ 
++-        with self.assertRaises(KeyError):
+++        self.assertRaises(KeyError).__enter__()
+++        if 1:
++             value = test['missing']
++ 
+++        self.assertRaises(KeyError).__exit__(0, 0, 0)
++         test['foo'] = 5
++         self.assertEqual(test['foo'], 5)
++ 
++@@ -48,9 +54,11 @@ class TestDefaultOnReadDict(unittest.Tes
++         self.assertEqual(original, test)
++         self.assertEqual(test['baz'], 3)
++ 
++-        with self.assertRaises(KeyError):
+++        self.assertRaises(KeyError).__enter__()
+++        if 1:
++             value = test['missing']
++ 
+++        self.assertRaises(KeyError).__exit__(0, 0, 0)
++         test['baz'] = 4
++         self.assertEqual(test['baz'], 4)
++ 
++@@ -85,15 +93,19 @@ class TestReadOnlyDefaultDict(unittest.T
++ 
++         self.assertEqual(test['foo'], 1)
++ 
++-        with self.assertRaises(KeyError):
+++        self.assertRaises(KeyError).__enter__()
+++        if 1:
++             value = test['missing']
++ 
+++        self.assertRaises(KeyError).__exit__(0, 0, 0)
++     def test_assignment(self):
++         test = ReadOnlyDefaultDict({})
++ 
++-        with self.assertRaises(Exception):
+++        self.assertRaises(Exception).__enter__()
+++        if 1:
++             test['foo'] = True
++ 
+++        self.assertRaises(Exception).__exit__(0, 0, 0)
++     def test_defaults(self):
++         test = ReadOnlyDefaultDict({}, defaults={'foo': 1})
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_mozconfig.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_mozconfig.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_mozconfig.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_mozconfig.py	2014-10-24 11:41:35.497880066 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import os
++ import unittest
++@@ -54,9 +54,11 @@ class TestMozconfigLoader(unittest.TestC
++ 
++         os.environ[b'MOZ_MYCONFIG'] = '/foo'
++ 
++-        with self.assertRaises(MozconfigFindException) as e:
+++        e = self.assertRaises(MozconfigFindException).__enter__()
+++        if 1:
++             self.get_loader().find_mozconfig()
++ 
+++        e.__exit__(0, 0, 0)
++         self.assertTrue(e.exception.message.startswith('The MOZ_MYCONFIG'))
++ 
++     def test_find_multiple_configs(self):
++@@ -70,14 +72,18 @@ class TestMozconfigLoader(unittest.TestC
++         loader = MozconfigLoader(srcdir)
++         for d in dirs:
++             path = os.path.join(d, relative_mozconfig)
++-            with open(path, 'wb') as f:
+++            f = open(path, 'wb')
+++            if 1:
++                 f.write(path)
++ 
+++            f.close()
++         orig_dir = os.getcwd()
++         try:
++             os.chdir(curdir)
++-            with self.assertRaises(MozconfigFindException) as e:
+++            e = self.assertRaises(MozconfigFindException).__enter__()
+++            if 1:
++                 loader.find_mozconfig()
+++            e.__exit__(0, 0, 0)
++         finally:
++             os.chdir(orig_dir)
++ 
++@@ -98,9 +104,11 @@ class TestMozconfigLoader(unittest.TestC
++ 
++         loader = MozconfigLoader(srcdir)
++         path = os.path.join(srcdir, relative_mozconfig)
++-        with open(path, 'w'):
+++        open(path, 'w').__enter__()
+++        if 1:
++             pass
++ 
+++        open(path, 'w').__exit__(0, 0, 0)
++         orig_dir = os.getcwd()
++         try:
++             os.chdir(curdir)
++@@ -122,8 +130,10 @@ class TestMozconfigLoader(unittest.TestC
++         orig_dir = os.getcwd()
++         try:
++             os.chdir(curdir)
++-            with self.assertRaises(MozconfigFindException) as e:
+++            e = self.assertRaises(MozconfigFindException).__enter__()
+++            if 1:
++                 loader.find_mozconfig()
+++            e.__exit__(0, 0, 0)
++         finally:
++             os.chdir(orig_dir)
++ 
++@@ -142,9 +152,11 @@ class TestMozconfigLoader(unittest.TestC
++         loader = MozconfigLoader(srcdir)
++ 
++         path = os.path.join(srcdir, relative_mozconfig)
++-        with open(path, 'w'):
+++        open(path, 'w').__enter__()
+++        if 1:
++             pass
++ 
+++        open(path, 'w').__exit__(0, 0, 0)
++         orig_dir = os.getcwd()
++         try:
++             os.chdir(curdir)
++@@ -157,9 +169,11 @@ class TestMozconfigLoader(unittest.TestC
++         """Ensure a missing absolute path is detected."""
++         os.environ[b'MOZCONFIG'] = '/foo/bar/does/not/exist'
++ 
++-        with self.assertRaises(MozconfigFindException) as e:
+++        e = self.assertRaises(MozconfigFindException).__enter__()
+++        if 1:
++             self.get_loader().find_mozconfig()
++ 
+++        e.__exit__(0, 0, 0)
++         self.assertIn('path that does not exist', e.exception.message)
++         self.assertTrue(e.exception.message.endswith('/foo/bar/does/not/exist'))
++ 
++@@ -168,9 +182,11 @@ class TestMozconfigLoader(unittest.TestC
++ 
++         os.environ[b'MOZCONFIG'] = gettempdir()
++ 
++-        with self.assertRaises(MozconfigFindException) as e:
+++        e = self.assertRaises(MozconfigFindException).__enter__()
+++        if 1:
++             self.get_loader().find_mozconfig()
++ 
+++        e.__exit__(0, 0, 0)
++         self.assertIn('refers to a non-file', e.exception.message)
++         self.assertTrue(e.exception.message.endswith(gettempdir()))
++ 
++@@ -180,9 +196,11 @@ class TestMozconfigLoader(unittest.TestC
++             d = self.get_temp_dir()
++             path = os.path.join(d, p)
++ 
++-            with open(path, 'w'):
+++            open(path, 'w').__enter__()
+++            if 1:
++                 pass
++ 
+++            open(path, 'w').__exit__(0, 0, 0)
++             self.assertEqual(MozconfigLoader(d).find_mozconfig(), path)
++ 
++     def test_find_multiple_defaults(self):
++@@ -191,12 +209,16 @@ class TestMozconfigLoader(unittest.TestC
++ 
++         d = self.get_temp_dir()
++         for p in MozconfigLoader.DEFAULT_TOPSRCDIR_PATHS:
++-            with open(os.path.join(d, p), 'w'):
+++            open(os.path.join(d, p), 'w').__enter__()
+++            if 1:
++                 pass
++ 
++-        with self.assertRaises(MozconfigFindException) as e:
+++            open(os.path.join(d, p), 'w').__exit__(0, 0, 0)
+++        e = self.assertRaises(MozconfigFindException).__enter__()
+++        if 1:
++             MozconfigLoader(d).find_mozconfig()
++ 
+++        e.__exit__(0, 0, 0)
++         self.assertIn('Multiple default mozconfig files present',
++             e.exception.message)
++ 
++@@ -204,12 +226,16 @@ class TestMozconfigLoader(unittest.TestC
++         """Ensure we error when deprecated path locations are present."""
++         for p in MozconfigLoader.DEPRECATED_TOPSRCDIR_PATHS:
++             d = self.get_temp_dir()
++-            with open(os.path.join(d, p), 'w'):
+++            open(os.path.join(d, p), 'w').__enter__()
+++            if 1:
++                 pass
++ 
++-            with self.assertRaises(MozconfigFindException) as e:
+++            open(os.path.join(d, p), 'w').__exit__(0, 0, 0)
+++            e = self.assertRaises(MozconfigFindException).__enter__()
+++            if 1:
++                 MozconfigLoader(d).find_mozconfig()
++ 
+++            e.__exit__(0, 0, 0)
++             self.assertIn('This implicit location is no longer',
++                 e.exception.message)
++             self.assertIn(d, e.exception.message)
++@@ -222,12 +248,16 @@ class TestMozconfigLoader(unittest.TestC
++             os.environ[b'HOME'] = home
++             path = os.path.join(home, p)
++ 
++-            with open(path, 'w'):
+++            open(path, 'w').__enter__()
+++            if 1:
++                 pass
++ 
++-            with self.assertRaises(MozconfigFindException) as e:
+++            open(path, 'w').__exit__(0, 0, 0)
+++            e = self.assertRaises(MozconfigFindException).__enter__()
+++            if 1:
++                 self.get_loader().find_mozconfig()
++ 
+++            e.__exit__(0, 0, 0)
++             self.assertIn('This implicit location is no longer',
++                 e.exception.message)
++             self.assertIn(path, e.exception.message)
++@@ -246,7 +276,8 @@ class TestMozconfigLoader(unittest.TestC
++         })
++ 
++     def test_read_empty_mozconfig(self):
++-        with NamedTemporaryFile(mode='w') as mozconfig:
+++        mozconfig = NamedTemporaryFile(mode='w').__enter__()
+++        if 1:
++             result = self.get_loader().read_mozconfig(mozconfig.name)
++ 
++             self.assertEqual(result['path'], mozconfig.name)
++@@ -260,9 +291,11 @@ class TestMozconfigLoader(unittest.TestC
++ 
++             self.assertGreater(len(result['env']['unmodified']), 0)
++ 
+++        mozconfig.__exit__(0, 0, 0)
++     def test_read_capture_ac_options(self):
++         """Ensures ac_add_options calls are captured."""
++-        with NamedTemporaryFile(mode='w') as mozconfig:
+++        mozconfig = NamedTemporaryFile(mode='w').__enter__()
+++        if 1:
++             mozconfig.write('ac_add_options --enable-debug\n')
++             mozconfig.write('ac_add_options --disable-tests --enable-foo\n')
++             mozconfig.write('ac_add_options --foo="bar baz"\n')
++@@ -273,9 +306,11 @@ class TestMozconfigLoader(unittest.TestC
++                 '--enable-debug', '--disable-tests', '--enable-foo',
++                 '--foo=bar baz'])
++ 
+++        mozconfig.__exit__(0, 0, 0)
++     def test_read_ac_options_substitution(self):
++         """Ensure ac_add_options values are substituted."""
++-        with NamedTemporaryFile(mode='w') as mozconfig:
+++        mozconfig = NamedTemporaryFile(mode='w').__enter__()
+++        if 1:
++             mozconfig.write('ac_add_options --foo=@TOPSRCDIR@\n')
++             mozconfig.flush()
++ 
++@@ -284,8 +319,10 @@ class TestMozconfigLoader(unittest.TestC
++             self.assertEqual(result['configure_args'], [
++                 '--foo=%s' % loader.topsrcdir])
++ 
+++        mozconfig.__exit__(0, 0, 0)
++     def test_read_ac_app_options(self):
++-        with NamedTemporaryFile(mode='w') as mozconfig:
+++        mozconfig = NamedTemporaryFile(mode='w').__enter__()
+++        if 1:
++             mozconfig.write('ac_add_options --foo=@TOPSRCDIR@\n')
++             mozconfig.write('ac_add_app_options app1 --bar=@TOPSRCDIR@\n')
++             mozconfig.write('ac_add_app_options app2 --bar=x\n')
++@@ -302,9 +339,11 @@ class TestMozconfigLoader(unittest.TestC
++                 '--foo=%s' % loader.topsrcdir,
++                 '--bar=x'])
++ 
+++        mozconfig.__exit__(0, 0, 0)
++     def test_read_capture_mk_options(self):
++         """Ensures mk_add_options calls are captured."""
++-        with NamedTemporaryFile(mode='w') as mozconfig:
+++        mozconfig = NamedTemporaryFile(mode='w').__enter__()
+++        if 1:
++             mozconfig.write('mk_add_options MOZ_OBJDIR=/foo/bar\n')
++             mozconfig.write('mk_add_options MOZ_MAKE_FLAGS=-j8\n')
++             mozconfig.write('mk_add_options FOO="BAR BAZ"\n')
++@@ -316,9 +355,11 @@ class TestMozconfigLoader(unittest.TestC
++             self.assertEqual(result['make_flags'], '-j8')
++             self.assertEqual(result['make_extra'], ['FOO=BAR BAZ', 'BIZ=1'])
++ 
+++        mozconfig.__exit__(0, 0, 0)
++     def test_read_moz_objdir_substitution(self):
++         """Ensure @TOPSRCDIR@ substitution is recognized in MOZ_OBJDIR."""
++-        with NamedTemporaryFile(mode='w') as mozconfig:
+++        mozconfig = NamedTemporaryFile(mode='w').__enter__()
+++        if 1:
++             mozconfig.write('mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/some-objdir')
++             mozconfig.flush()
++ 
++@@ -328,9 +369,11 @@ class TestMozconfigLoader(unittest.TestC
++             self.assertEqual(result['topobjdir'], '%s/some-objdir' %
++                 loader.topsrcdir)
++ 
+++        mozconfig.__exit__(0, 0, 0)
++     def test_read_new_variables(self):
++         """New variables declared in mozconfig file are detected."""
++-        with NamedTemporaryFile(mode='w') as mozconfig:
+++        mozconfig = NamedTemporaryFile(mode='w').__enter__()
+++        if 1:
++             mozconfig.write('CC=/usr/local/bin/clang\n')
++             mozconfig.write('CXX=/usr/local/bin/clang++\n')
++             mozconfig.flush()
++@@ -341,9 +384,11 @@ class TestMozconfigLoader(unittest.TestC
++                 'CC': '/usr/local/bin/clang',
++                 'CXX': '/usr/local/bin/clang++'})
++ 
+++        mozconfig.__exit__(0, 0, 0)
++     def test_read_exported_variables(self):
++         """Exported variables are caught as new variables."""
++-        with NamedTemporaryFile(mode='w') as mozconfig:
+++        mozconfig = NamedTemporaryFile(mode='w').__enter__()
+++        if 1:
++             mozconfig.write('export MY_EXPORTED=woot\n')
++             mozconfig.flush()
++ 
++@@ -352,11 +397,13 @@ class TestMozconfigLoader(unittest.TestC
++             self.assertEqual(result['env']['added'], {
++                 'MY_EXPORTED': 'woot'})
++ 
+++        mozconfig.__exit__(0, 0, 0)
++     def test_read_modify_variables(self):
++         """Variables modified by mozconfig are detected."""
++-        os.environ[b'CC'] = b'/usr/bin/gcc'
+++        os.environ[b'CC'] = '/usr/bin/gcc'
++ 
++-        with NamedTemporaryFile(mode='w') as mozconfig:
+++        mozconfig = NamedTemporaryFile(mode='w').__enter__()
+++        if 1:
++             mozconfig.write('CC=/usr/local/bin/clang\n')
++             mozconfig.flush()
++ 
++@@ -366,11 +413,13 @@ class TestMozconfigLoader(unittest.TestC
++                 'CC': ('/usr/bin/gcc', '/usr/local/bin/clang')
++             })
++ 
+++        mozconfig.__exit__(0, 0, 0)
++     def test_read_removed_variables(self):
++         """Variables unset by the mozconfig are detected."""
++-        os.environ[b'CC'] = b'/usr/bin/clang'
+++        os.environ[b'CC'] = '/usr/bin/clang'
++ 
++-        with NamedTemporaryFile(mode='w') as mozconfig:
+++        mozconfig = NamedTemporaryFile(mode='w').__enter__()
+++        if 1:
++             mozconfig.write('unset CC\n')
++             mozconfig.flush()
++ 
++@@ -379,9 +428,11 @@ class TestMozconfigLoader(unittest.TestC
++             self.assertEqual(result['env']['removed'], {
++                 'CC': '/usr/bin/clang'})
++ 
+++        mozconfig.__exit__(0, 0, 0)
++     def test_read_multiline_variables(self):
++         """Ensure multi-line variables are captured properly."""
++-        with NamedTemporaryFile(mode='w') as mozconfig:
+++        mozconfig = NamedTemporaryFile(mode='w').__enter__()
+++        if 1:
++             mozconfig.write('multi="foo\nbar"\n')
++             mozconfig.write('single=1\n')
++             mozconfig.flush()
++@@ -393,9 +444,11 @@ class TestMozconfigLoader(unittest.TestC
++                 'single': '1'
++             })
++ 
+++        mozconfig.__exit__(0, 0, 0)
++     def test_read_topsrcdir_defined(self):
++         """Ensure $topsrcdir references work as expected."""
++-        with NamedTemporaryFile(mode='w') as mozconfig:
+++        mozconfig = NamedTemporaryFile(mode='w').__enter__()
+++        if 1:
++             mozconfig.write('TEST=$topsrcdir')
++             mozconfig.flush()
++ 
++@@ -405,9 +458,11 @@ class TestMozconfigLoader(unittest.TestC
++             self.assertEqual(result['env']['added']['TEST'],
++                 loader.topsrcdir.replace(os.sep, '/'))
++ 
+++        mozconfig.__exit__(0, 0, 0)
++     def test_read_empty_variable_value(self):
++         """Ensure empty variable values are parsed properly."""
++-        with NamedTemporaryFile(mode='w') as mozconfig:
+++        mozconfig = NamedTemporaryFile(mode='w').__enter__()
+++        if 1:
++             mozconfig.write('EMPTY=\n')
++             mozconfig.flush()
++ 
++@@ -416,16 +471,20 @@ class TestMozconfigLoader(unittest.TestC
++             self.assertIn('EMPTY', result['env']['added'])
++             self.assertEqual(result['env']['added']['EMPTY'], '')
++ 
+++        mozconfig.__exit__(0, 0, 0)
++     def test_read_load_exception(self):
++         """Ensure non-0 exit codes in mozconfigs are handled properly."""
++-        with NamedTemporaryFile(mode='w') as mozconfig:
+++        mozconfig = NamedTemporaryFile(mode='w').__enter__()
+++        if 1:
++             mozconfig.write('echo "hello world"\n')
++             mozconfig.write('exit 1\n')
++             mozconfig.flush()
++ 
++-            with self.assertRaises(MozconfigLoadException) as e:
+++            e = self.assertRaises(MozconfigLoadException).__enter__()
+++            if 1:
++                 self.get_loader().read_mozconfig(mozconfig.name)
++ 
+++            e.__exit__(0, 0, 0)
++             self.assertTrue(e.exception.message.startswith(
++                 'Evaluation of your mozconfig exited with an error'))
++             self.assertEquals(e.exception.path,
++@@ -433,5 +492,6 @@ class TestMozconfigLoader(unittest.TestC
++             self.assertEquals(e.exception.output, ['hello world'])
++ 
++ 
+++        mozconfig.__exit__(0, 0, 0)
++ if __name__ == '__main__':
++     main()
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_mozinfo.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_mozinfo.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_mozinfo.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_mozinfo.py	2014-10-24 11:41:35.498880062 -0600
++@@ -34,15 +34,21 @@ class TestBuildDict(unittest.TestCase, B
++         Test that missing required values raises.
++         """
++ 
++-        with self.assertRaises(Exception):
+++        self.assertRaises(Exception).__enter__()
+++        if 1:
++             build_dict(self._config(substs=dict(OS_TARGET='foo')))
++ 
++-        with self.assertRaises(Exception):
+++        self.assertRaises(Exception).__exit__(0, 0, 0)
+++        self.assertRaises(Exception).__enter__()
+++        if 1:
++             build_dict(self._config(substs=dict(TARGET_CPU='foo')))
++ 
++-        with self.assertRaises(Exception):
+++        self.assertRaises(Exception).__exit__(0, 0, 0)
+++        self.assertRaises(Exception).__enter__()
+++        if 1:
++             build_dict(self._config(substs=dict(MOZ_WIDGET_TOOLKIT='foo')))
++ 
+++        self.assertRaises(Exception).__exit__(0, 0, 0)
++     def test_win(self):
++         d = build_dict(self._config(dict(
++             OS_TARGET='WINNT',
++@@ -242,11 +248,13 @@ class TestWriteMozinfo(unittest.TestCase
++         ))
++         tempdir = tempfile.tempdir
++         c.topsrcdir = tempdir
++-        with NamedTemporaryFile(dir=os.path.normpath(c.topsrcdir)) as mozconfig:
+++        mozconfig = NamedTemporaryFile(dir=os.path.normpath(c.topsrcdir)).__enter__()
+++        if 1:
++             mozconfig.write('unused contents')
++             mozconfig.flush()
++             write_mozinfo(self.f, c, {'MOZCONFIG': mozconfig.name})
++-            with open(self.f) as f:
+++            f = open(self.f)
+++            if 1:
++                 d = json.load(f)
++                 self.assertEqual('win', d['os'])
++                 self.assertEqual('x86', d['processor'])
++@@ -255,6 +263,8 @@ class TestWriteMozinfo(unittest.TestCase
++                 self.assertEqual(mozconfig.name, d['mozconfig'])
++                 self.assertEqual(32, d['bits'])
++ 
+++            f.close()
+++        mozconfig.__exit__(0, 0, 0)
++     def test_fileobj(self):
++         """
++         Test that writing to a file-like object produces correct output.
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_preprocessor.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_preprocessor.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_preprocessor.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_preprocessor.py	2014-10-24 11:41:35.498880062 -0600
++@@ -28,10 +28,12 @@ class TestPreprocessor(unittest.TestCase
++         content = '%s' % '\n'.join(content_lines)
++         expected = '%s'.rstrip() % '\n'.join(expected_lines)
++ 
++-        with MockedOpen({'dummy': content}):
+++        MockedOpen({'dummy': content}).__enter__()
+++        if 1:
++             self.pp.do_include('dummy')
++             self.assertEqual(self.pp.out.getvalue().rstrip('\n'), expected)
++ 
+++        MockedOpen({'dummy': content}).__exit__(0, 0, 0)
++     def do_include_pass(self, content_lines):
++         self.do_include_compare(content_lines, ['PASS'])
++ 
++@@ -267,18 +269,23 @@ class TestPreprocessor(unittest.TestCase
++         ])
++ 
++     def test_error(self):
++-        with MockedOpen({'f': '#error spit this message out\n'}):
++-            with self.assertRaises(Preprocessor.Error) as e:
+++        MockedOpen({'f': '#error spit this message out\n'}).__enter__()
+++        if 1:
+++            e = self.assertRaises(Preprocessor.Error).__enter__()
+++            if 1:
++                 self.pp.do_include('f')
++                 self.assertEqual(e.args[0][-1], 'spit this message out')
++ 
+++            e.__exit__(0, 0, 0)
+++        MockedOpen({'f': '#error spit this message out\n'}).__exit__(0, 0, 0)
++     def test_javascript_line(self):
++         # The preprocessor is reading the filename from somewhere not caught
++         # by MockedOpen.
++         tmpdir = mkdtemp()
++         try:
++             full = os.path.join(tmpdir, 'javascript_line.js.in')
++-            with open(full, 'w') as fh:
+++            fh = open(full, 'w')
+++            if 1:
++                 fh.write('\n'.join([
++                     '// Line 1',
++                     '#if 0',
++@@ -296,6 +303,7 @@ class TestPreprocessor(unittest.TestCase
++                     '',
++                 ]))
++ 
+++            fh.close()
++             self.pp.do_include(full)
++             out = '\n'.join([
++                 '// Line 1',
++@@ -441,11 +449,13 @@ class TestPreprocessor(unittest.TestCase
++         ])
++ 
++     def test_lineEndings(self):
++-        with MockedOpen({'f': 'first\n#literal second\n'}):
+++        MockedOpen({'f': 'first\n#literal second\n'}).__enter__()
+++        if 1:
++             self.pp.setLineEndings('cr')
++             self.pp.do_include('f')
++             self.assertEqual(self.pp.out.getvalue(), "first\rsecond\r")
++ 
+++        MockedOpen({'f': 'first\n#literal second\n'}).__exit__(0, 0, 0)
++     def test_filterDefine(self):
++         self.do_include_pass([
++             '#filter substitution',
++@@ -532,11 +542,15 @@ class TestPreprocessor(unittest.TestCase
++         ])
++ 
++     def test_undefined_variable(self):
++-        with MockedOpen({'f': '#filter substitution\n at foo@'}):
++-            with self.assertRaises(Preprocessor.Error) as e:
+++        MockedOpen({'f': '#filter substitution\n at foo@'}).__enter__()
+++        if 1:
+++            e = self.assertRaises(Preprocessor.Error).__enter__()
+++            if 1:
++                 self.pp.do_include('f')
++                 self.assertEqual(e.key, 'UNDEFINED_VAR')
++ 
+++            e.__exit__(0, 0, 0)
+++        MockedOpen({'f': '#filter substitution\n at foo@'}).__exit__(0, 0, 0)
++     def test_include(self):
++         files = {
++             'foo/test': '\n'.join([
++@@ -558,36 +572,50 @@ class TestPreprocessor(unittest.TestCase
++             ]),
++         }
++ 
++-        with MockedOpen(files):
+++        MockedOpen(files).__enter__()
+++        if 1:
++             self.pp.do_include('f')
++             self.assertEqual(self.pp.out.getvalue(), 'foobarbaz\nbarfoobaz\n')
++ 
+++        MockedOpen(files).__exit__(0, 0, 0)
++     def test_include_missing_file(self):
++-        with MockedOpen({'f': '#include foo\n'}):
++-            with self.assertRaises(Preprocessor.Error) as e:
+++        MockedOpen({'f': '#include foo\n'}).__enter__()
+++        if 1:
+++            e = self.assertRaises(Preprocessor.Error).__enter__()
+++            if 1:
++                 self.pp.do_include('f')
++                 self.assertEqual(e.key, 'FILE_NOT_FOUND')
++ 
+++            e.__exit__(0, 0, 0)
+++        MockedOpen({'f': '#include foo\n'}).__exit__(0, 0, 0)
++     def test_include_undefined_variable(self):
++-        with MockedOpen({'f': '#filter substitution\n#include @foo@\n'}):
++-            with self.assertRaises(Preprocessor.Error) as e:
+++        MockedOpen({'f': '#filter substitution\n#include @foo@\n'}).__enter__()
+++        if 1:
+++            e = self.assertRaises(Preprocessor.Error).__enter__()
+++            if 1:
++                 self.pp.do_include('f')
++                 self.assertEqual(e.key, 'UNDEFINED_VAR')
++ 
+++            e.__exit__(0, 0, 0)
+++        MockedOpen({'f': '#filter substitution\n#include @foo@\n'}).__exit__(0, 0, 0)
++     def test_include_literal_at(self):
++         files = {
++             '@foo@': '#define foo foobarbaz\n',
++             'f': '#include @foo@\n#filter substitution\n at foo@\n',
++         }
++ 
++-        with MockedOpen(files):
+++        MockedOpen(files).__enter__()
+++        if 1:
++             self.pp.do_include('f')
++             self.assertEqual(self.pp.out.getvalue(), 'foobarbaz\n')
++ 
+++        MockedOpen(files).__exit__(0, 0, 0)
++     def test_command_line_literal_at(self):
++-        with MockedOpen({"@foo at .in": '@foo@\n'}):
+++        MockedOpen({"@foo at .in": '@foo@\n'}).__enter__()
+++        if 1:
++             self.pp.handleCommandLine(['-Fsubstitution', '-Dfoo=foobarbaz', '@foo at .in'])
++             self.assertEqual(self.pp.out.getvalue(), 'foobarbaz\n')
++ 
+++        MockedOpen({"@foo at .in": '@foo@\n'}).__exit__(0, 0, 0)
++ if __name__ == '__main__':
++     main()
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_testing.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_testing.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_testing.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_testing.py	2014-10-24 11:41:35.498880062 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import os
++ import shutil
++@@ -21,7 +21,7 @@ from mozbuild.testing import (
++ )
++ 
++ 
++-ALL_TESTS_JSON = b'''
+++ALL_TESTS_JSON = '''
++ {
++     "accessible/tests/mochitest/actions/test_anchors.html": [
++         {
++@@ -175,9 +175,11 @@ class TestTestResolver(Base):
++         topobjdir = tempfile.mkdtemp()
++         self._temp_dirs.append(topobjdir)
++ 
++-        with open(os.path.join(topobjdir, 'all-tests.json'), 'wt') as fh:
+++        fh = open(os.path.join(topobjdir, 'all-tests.json'), 'wt')
+++        if 1:
++             fh.write(ALL_TESTS_JSON)
++ 
+++        fh.close()
++         o = MozbuildObject(self.FAKE_TOPSRCDIR, None, None, topobjdir=topobjdir)
++ 
++         return o._spawn(TestResolver)
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_util.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_util.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_util.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/test/test_util.py	2014-10-24 11:41:35.499880057 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import hashlib
++ import os
++@@ -41,7 +41,7 @@ data_path = os.path.join(data_path, 'dat
++ class TestHashing(unittest.TestCase):
++     def test_hash_file_known_hash(self):
++         """Ensure a known hash value is recreated."""
++-        data = b'The quick brown fox jumps over the lazy cog'
+++        data = 'The quick brown fox jumps over the lazy cog'
++         expected = 'de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3'
++ 
++         temp = NamedTemporaryFile()
++@@ -54,7 +54,7 @@ class TestHashing(unittest.TestCase):
++ 
++     def test_hash_file_large(self):
++         """Ensure that hash_file seems to work with a large file."""
++-        data = b'x' * 1048576
+++        data = 'x' * 1048576
++ 
++         hasher = hashlib.sha1()
++         hasher.update(data)
++@@ -71,7 +71,8 @@ class TestHashing(unittest.TestCase):
++ 
++ class TestFileAvoidWrite(unittest.TestCase):
++     def test_file_avoid_write(self):
++-        with MockedOpen({'file': 'content'}):
+++        MockedOpen({'file': 'content'}).__enter__()
+++        if 1:
++             # Overwriting an existing file replaces its content
++             faw = FileAvoidWrite('file')
++             faw.write('bazqux')
++@@ -84,12 +85,17 @@ class TestFileAvoidWrite(unittest.TestCa
++             self.assertEqual(faw.close(), (False, True))
++             self.assertEqual(open('file2').read(), 'content')
++ 
++-        with MockedOpen({'file': 'content'}):
++-            with FileAvoidWrite('file') as file:
+++        MockedOpen({'file': 'content'}).__exit__(0, 0, 0)
+++        MockedOpen({'file': 'content'}).__enter__()
+++        if 1:
+++            file = FileAvoidWrite('file').__enter__()
+++            if 1:
++                 file.write('foobar')
++ 
+++            file.__exit__(0, 0, 0)
++             self.assertEqual(open('file', 'r').read(), 'foobar')
++ 
+++        MockedOpen({'file': 'content'}).__exit__(0, 0, 0)
++         class MyMockedOpen(MockedOpen):
++             '''MockedOpen extension to raise an exception if something
++             attempts to write in an opened file.
++@@ -99,7 +105,8 @@ class TestFileAvoidWrite(unittest.TestCa
++                     raise Exception, 'Unexpected open with write mode'
++                 return MockedOpen.__call__(self, name, mode)
++ 
++-        with MyMockedOpen({'file': 'content'}):
+++        MyMockedOpen({'file': 'content'}).__enter__()
+++        if 1:
++             # Validate that MyMockedOpen works as intended
++             file = FileAvoidWrite('file')
++             file.write('foobar')
++@@ -111,19 +118,23 @@ class TestFileAvoidWrite(unittest.TestCa
++             faw.write('content')
++             self.assertEqual(faw.close(), (True, False))
++ 
+++        MyMockedOpen({'file': 'content'}).__exit__(0, 0, 0)
++     def test_diff_not_default(self):
++         """Diffs are not produced by default."""
++ 
++-        with MockedOpen({'file': 'old'}):
+++        MockedOpen({'file': 'old'}).__enter__()
+++        if 1:
++             faw = FileAvoidWrite('file')
++             faw.write('dummy')
++             faw.close()
++             self.assertIsNone(faw.diff)
++ 
+++        MockedOpen({'file': 'old'}).__exit__(0, 0, 0)
++     def test_diff_update(self):
++         """Diffs are produced on file update."""
++ 
++-        with MockedOpen({'file': 'old'}):
+++        MockedOpen({'file': 'old'}).__enter__()
+++        if 1:
++             faw = FileAvoidWrite('file', capture_diff=True)
++             faw.write('new')
++             faw.close()
++@@ -132,6 +143,7 @@ class TestFileAvoidWrite(unittest.TestCa
++             self.assertIn('-old', diff)
++             self.assertIn('+new', diff)
++ 
+++        MockedOpen({'file': 'old'}).__exit__(0, 0, 0)
++     def test_diff_create(self):
++         """Diffs are produced when files are created."""
++ 
++@@ -228,43 +240,55 @@ class TestHierarchicalStringList(unittes
++         self.assertEqual(self.EXPORTS.foo.bar.get_strings(), ["foobar.h"])
++ 
++     def test_invalid_exports_append(self):
++-        with self.assertRaises(ValueError) as ve:
+++        ve = self.assertRaises(ValueError).__enter__()
+++        if 1:
++             self.EXPORTS += "foo.h"
+++        ve.__exit__(0, 0, 0)
++         self.assertEqual(str(ve.exception),
++                          "Expected a list of strings, not <type '%s'>" % str_type)
++ 
++     def test_invalid_exports_set(self):
++-        with self.assertRaises(ValueError) as ve:
+++        ve = self.assertRaises(ValueError).__enter__()
+++        if 1:
++             self.EXPORTS.foo = "foo.h"
++ 
+++        ve.__exit__(0, 0, 0)
++         self.assertEqual(str(ve.exception),
++                          "Expected a list of strings, not <type '%s'>" % str_type)
++ 
++     def test_invalid_exports_append_base(self):
++-        with self.assertRaises(ValueError) as ve:
+++        ve = self.assertRaises(ValueError).__enter__()
+++        if 1:
++             self.EXPORTS += "foo.h"
++ 
+++        ve.__exit__(0, 0, 0)
++         self.assertEqual(str(ve.exception),
++                          "Expected a list of strings, not <type '%s'>" % str_type)
++ 
++     def test_invalid_exports_bool(self):
++-        with self.assertRaises(ValueError) as ve:
+++        ve = self.assertRaises(ValueError).__enter__()
+++        if 1:
++             self.EXPORTS += [True]
++ 
+++        ve.__exit__(0, 0, 0)
++         self.assertEqual(str(ve.exception),
++                          "Expected a list of strings, not an element of "
++                          "<type 'bool'>")
++ 
++     def test_del_exports(self):
++-        with self.assertRaises(MozbuildDeletionError) as mde:
+++        mde = self.assertRaises(MozbuildDeletionError).__enter__()
+++        if 1:
++             self.EXPORTS.foo += ['bar.h']
++             del self.EXPORTS.foo
++ 
+++        mde.__exit__(0, 0, 0)
++     def test_unsorted_appends(self):
++-        with self.assertRaises(UnsortedError) as ee:
+++        ee = self.assertRaises(UnsortedError).__enter__()
+++        if 1:
++             self.EXPORTS += ['foo.h', 'bar.h']
++ 
++ 
+++        ee.__exit__(0, 0, 0)
++ class TestStrictOrderingOnAppendList(unittest.TestCase):
++     def test_init(self):
++         l = StrictOrderingOnAppendList()
++@@ -273,9 +297,11 @@ class TestStrictOrderingOnAppendList(uni
++         l = StrictOrderingOnAppendList(['a', 'b', 'c'])
++         self.assertEqual(len(l), 3)
++ 
++-        with self.assertRaises(UnsortedError):
+++        self.assertRaises(UnsortedError).__enter__()
+++        if 1:
++             StrictOrderingOnAppendList(['c', 'b', 'a'])
++ 
+++        self.assertRaises(UnsortedError).__exit__(0, 0, 0)
++         self.assertEqual(len(l), 3)
++ 
++     def test_extend(self):
++@@ -284,9 +310,11 @@ class TestStrictOrderingOnAppendList(uni
++         self.assertEqual(len(l), 2)
++         self.assertIsInstance(l, StrictOrderingOnAppendList)
++ 
++-        with self.assertRaises(UnsortedError):
+++        self.assertRaises(UnsortedError).__enter__()
+++        if 1:
++             l.extend(['d', 'c'])
++ 
+++        self.assertRaises(UnsortedError).__exit__(0, 0, 0)
++         self.assertEqual(len(l), 2)
++ 
++     def test_slicing(self):
++@@ -295,9 +323,11 @@ class TestStrictOrderingOnAppendList(uni
++         self.assertEqual(len(l), 2)
++         self.assertIsInstance(l, StrictOrderingOnAppendList)
++ 
++-        with self.assertRaises(UnsortedError):
+++        self.assertRaises(UnsortedError).__enter__()
+++        if 1:
++             l[:] = ['b', 'a']
++ 
+++        self.assertRaises(UnsortedError).__exit__(0, 0, 0)
++         self.assertEqual(len(l), 2)
++ 
++     def test_add(self):
++@@ -307,9 +337,11 @@ class TestStrictOrderingOnAppendList(uni
++         self.assertEqual(len(l2), 2)
++         self.assertIsInstance(l2, StrictOrderingOnAppendList)
++ 
++-        with self.assertRaises(UnsortedError):
+++        self.assertRaises(UnsortedError).__enter__()
+++        if 1:
++             l2 = l + ['b', 'a']
++ 
+++        self.assertRaises(UnsortedError).__exit__(0, 0, 0)
++         self.assertEqual(len(l), 0)
++ 
++     def test_iadd(self):
++@@ -318,9 +350,11 @@ class TestStrictOrderingOnAppendList(uni
++         self.assertEqual(len(l), 2)
++         self.assertIsInstance(l, StrictOrderingOnAppendList)
++ 
++-        with self.assertRaises(UnsortedError):
+++        self.assertRaises(UnsortedError).__enter__()
+++        if 1:
++             l += ['b', 'a']
++ 
+++        self.assertRaises(UnsortedError).__exit__(0, 0, 0)
++         self.assertEqual(len(l), 2)
++ 
++ 
++@@ -334,19 +368,25 @@ class TestStrictOrderingOnAppendListWith
++         l = cls()
++         l += ['a', 'b']
++ 
++-        with self.assertRaises(Exception):
+++        self.assertRaises(Exception).__enter__()
+++        if 1:
++             l['a'] = 'foo'
++ 
++-        with self.assertRaises(Exception):
+++        self.assertRaises(Exception).__exit__(0, 0, 0)
+++        self.assertRaises(Exception).__enter__()
+++        if 1:
++             c = l['c']
++ 
+++        self.assertRaises(Exception).__exit__(0, 0, 0)
++         self.assertEqual(l['a'].foo, False)
++         l['a'].foo = True
++         self.assertEqual(l['a'].foo, True)
++ 
++-        with self.assertRaises(TypeError):
+++        self.assertRaises(TypeError).__enter__()
+++        if 1:
++             l['a'].bar = 'bar'
++ 
+++        self.assertRaises(TypeError).__exit__(0, 0, 0)
++         self.assertEqual(l['a'].bar, 0)
++         l['a'].bar = 42
++         self.assertEqual(l['a'].bar, 42)
++@@ -354,10 +394,12 @@ class TestStrictOrderingOnAppendListWith
++         l['b'].foo = True
++         self.assertEqual(l['b'].foo, True)
++ 
++-        with self.assertRaises(AttributeError):
+++        self.assertRaises(AttributeError).__enter__()
+++        if 1:
++             l['b'].baz = False
++ 
++ 
+++        self.assertRaises(AttributeError).__exit__(0, 0, 0)
++ class TestHierarchicalStringListWithFlagsFactory(unittest.TestCase):
++     def test_hierarchical_string_list_with_flags_factory(self):
++         cls = HierarchicalStringListWithFlagsFactory({
++@@ -368,19 +410,25 @@ class TestHierarchicalStringListWithFlag
++         l = cls()
++         l += ['a', 'b']
++ 
++-        with self.assertRaises(Exception):
+++        self.assertRaises(Exception).__enter__()
+++        if 1:
++             l['a'] = 'foo'
++ 
++-        with self.assertRaises(Exception):
+++        self.assertRaises(Exception).__exit__(0, 0, 0)
+++        self.assertRaises(Exception).__enter__()
+++        if 1:
++             c = l['c']
++ 
+++        self.assertRaises(Exception).__exit__(0, 0, 0)
++         self.assertEqual(l['a'].foo, False)
++         l['a'].foo = True
++         self.assertEqual(l['a'].foo, True)
++ 
++-        with self.assertRaises(TypeError):
+++        self.assertRaises(TypeError).__enter__()
+++        if 1:
++             l['a'].bar = 'bar'
++ 
+++        self.assertRaises(TypeError).__exit__(0, 0, 0)
++         self.assertEqual(l['a'].bar, 0)
++         l['a'].bar = 42
++         self.assertEqual(l['a'].bar, 42)
++@@ -388,24 +436,32 @@ class TestHierarchicalStringListWithFlag
++         l['b'].foo = True
++         self.assertEqual(l['b'].foo, True)
++ 
++-        with self.assertRaises(AttributeError):
+++        self.assertRaises(AttributeError).__enter__()
+++        if 1:
++             l['b'].baz = False
++ 
+++        self.assertRaises(AttributeError).__exit__(0, 0, 0)
++         l.x += ['x', 'y']
++ 
++-        with self.assertRaises(Exception):
+++        self.assertRaises(Exception).__enter__()
+++        if 1:
++             l.x['x'] = 'foo'
++ 
++-        with self.assertRaises(Exception):
+++        self.assertRaises(Exception).__exit__(0, 0, 0)
+++        self.assertRaises(Exception).__enter__()
+++        if 1:
++             c = l.x['c']
++ 
+++        self.assertRaises(Exception).__exit__(0, 0, 0)
++         self.assertEqual(l.x['x'].foo, False)
++         l.x['x'].foo = True
++         self.assertEqual(l.x['x'].foo, True)
++ 
++-        with self.assertRaises(TypeError):
+++        self.assertRaises(TypeError).__enter__()
+++        if 1:
++             l.x['x'].bar = 'bar'
++ 
+++        self.assertRaises(TypeError).__exit__(0, 0, 0)
++         self.assertEqual(l.x['x'].bar, 0)
++         l.x['x'].bar = 42
++         self.assertEqual(l.x['x'].bar, 42)
++@@ -413,9 +469,11 @@ class TestHierarchicalStringListWithFlag
++         l.x['y'].foo = True
++         self.assertEqual(l.x['y'].foo, True)
++ 
++-        with self.assertRaises(AttributeError):
+++        self.assertRaises(AttributeError).__enter__()
+++        if 1:
++             l.x['y'].baz = False
++ 
++ 
+++        self.assertRaises(AttributeError).__exit__(0, 0, 0)
++ if __name__ == '__main__':
++     main()
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/util.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/util.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/util.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/util.py	2014-10-24 11:41:35.499880057 -0600
++@@ -1,3 +1,4 @@
+++from rhrebase import all
++ # This Source Code Form is subject to the terms of the Mozilla Public
++ # License, v. 2.0. If a copy of the MPL was not distributed with this file,
++ # You can obtain one at http://mozilla.org/MPL/2.0/.
++@@ -5,12 +6,12 @@
++ # This file contains miscellaneous utility functions that don't belong anywhere
++ # in particular.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import copy
++ import difflib
++ import errno
++-import hashlib
+++import sha
++ import os
++ import stat
++ import sys
++@@ -29,9 +30,10 @@ def hash_file(path):
++ 
++     # If the hashing function changes, this may invalidate lots of cached data.
++     # Don't change it lightly.
++-    h = hashlib.sha1()
+++    h = sha.sha()
++ 
++-    with open(path, 'rb') as fh:
+++    fh = open(path, 'rb')
+++    if 1:
++         while True:
++             data = fh.read(8192)
++ 
++@@ -40,6 +42,7 @@ def hash_file(path):
++ 
++             h.update(data)
++ 
+++    fh.close()
++     return h.hexdigest()
++ 
++ 
++@@ -122,7 +125,10 @@ class FileAvoidWrite(StringIO):
++     could add unwanted overhead to calls.
++     """
++     def __init__(self, filename, capture_diff=False):
++-        StringIO.__init__(self)
+++        StringIO.__init__(self )
+++        #super(type(FileAvoidWrite), self).__init__()
+++        #print "SELF BUF", self.buf
+++        #super(FileAvoidWrite, self).__init__()
++         self.name = filename
++         self._capture_diff = capture_diff
++         self.diff = None
++@@ -138,7 +144,8 @@ class FileAvoidWrite(StringIO):
++         underlying file was changed, ``.diff`` will be populated with the diff
++         of the result.
++         """
++-        buf = self.getvalue()
+++        buf = self.getvalue( )
+++        #buf = self.buf
++         StringIO.close(self)
++         existed = False
++         old_content = None
++@@ -155,16 +162,23 @@ class FileAvoidWrite(StringIO):
++                     return True, False
++             except IOError:
++                 pass
++-            finally:
+++            if 1:
++                 existing.close()
++ 
+++
++         ensureParentDir(self.name)
++-        with open(self.name, 'w') as file:
+++        file = open(self.name, 'w')
+++        if 1:
++             file.write(buf)
++ 
+++        file.close()
++         if self._capture_diff:
++             try:
++-                old_lines = old_content.splitlines() if old_content else []
+++                old_lines = None
+++                if old_content:
+++                  old_lines = old_content.splitlines()
+++                else:
+++                  old_lines = []
++                 new_lines = buf.splitlines()
++ 
++                 self.diff = difflib.unified_diff(old_lines, new_lines,
++@@ -181,8 +195,15 @@ class FileAvoidWrite(StringIO):
++         return existed, True
++ 
++     def __enter__(self):
+++        import traceback
+++        #print "ENTER:", self.buf
+++        #traceback.print_stack()
++         return self
++     def __exit__(self, type, value, traceback):
+++        #print "EXIT"
+++        import traceback
+++        #traceback.print_stack()
+++        #print self.buf
++         self.close()
++ 
++ 
++@@ -551,7 +572,7 @@ class LockFile(object):
++             try:
++                 os.remove(self.lockfile)
++                 break
++-            except OSError as e:
+++            except OSError, e:
++                 if e.errno == errno.EACCES:
++                     # Another process probably has the file open, we'll retry.
++                     # Just a short sleep since we want to drop the lock ASAP
++@@ -576,7 +597,7 @@ def lock_file(lockfile, max_wait = 600):
++             fd = os.open(lockfile, os.O_EXCL | os.O_RDWR | os.O_CREAT)
++             # We created the lockfile, so we're the owner
++             break
++-        except OSError as e:
+++        except OSError, e:
++             if (e.errno == errno.EEXIST or
++                 (sys.platform == "win32" and e.errno == errno.EACCES)):
++                 pass
++@@ -589,7 +610,7 @@ def lock_file(lockfile, max_wait = 600):
++             # and read its contents to report the owner PID
++             f = open(lockfile, 'r')
++             s = os.stat(lockfile)
++-        except EnvironmentError as e:
+++        except EnvironmentError, e:
++             if e.errno == errno.ENOENT or e.errno == errno.EACCES:
++             # We didn't create the lockfile, so it did exist, but it's
++             # gone now. Just try again
++@@ -613,7 +634,7 @@ def lock_file(lockfile, max_wait = 600):
++     # if we get here. we have the lockfile. Convert the os.open file
++     # descriptor into a Python file object and record our PID in it
++     f = os.fdopen(fd, 'w')
++-    f.write('{0}\n'.format(os.getpid()))
+++    f.write('%d\n' %(os.getpid()))
++     f.close()
++ 
++     return LockFile(lockfile)
++diff -up comm-esr31/mozilla/python/mozbuild/mozbuild/virtualenv.py.python3 comm-esr31/mozilla/python/mozbuild/mozbuild/virtualenv.py
++--- comm-esr31/mozilla/python/mozbuild/mozbuild/virtualenv.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozbuild/virtualenv.py	2014-10-24 11:41:35.499880057 -0600
++@@ -1,11 +1,65 @@
++-# This Source Code Form is subject to the terms of the Mozilla Public
++-# License, v. 2.0. If a copy of the MPL was not distributed with this
+++# relpath
+++import os, sys
+++# Creates os.path.relpath for Python 2.4
+++
+++if not hasattr(os, "relpath"):
+++    if os.path is sys.modules.get("ntpath"):
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++            if start_list[0].lower() != path_list[0].lower():
+++                unc_path, rest = os.path.splitunc(path)
+++                unc_start, rest = os.path.splitunc(start)
+++                if bool(unc_path) ^ bool(unc_start):
+++                    raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
+++                                                                        % (path, start))
+++                else:
+++                    raise ValueError("path is on drive %s, start on drive %s"
+++                                                        % (path_list[0], start_list[0]))
+++            # Work out how much of the filepath is shared by start and path.
+++            for i in range(min(len(start_list), len(path_list))):
+++                if start_list[i].lower() != path_list[i].lower():
+++                    break
+++            else:
+++                i += 1
+++ 
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++    
+++    else:
+++        # default to posixpath definition
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++        
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++        
+++            # Work out how much of the filepath is shared by start and path.
+++            i = len(os.path.commonprefix([start_list, path_list]))
+++        
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++        
+++    os.path.relpath = relpath
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++ # This file contains code for populating the virtualenv environment for
++ # Mozilla's build system. It is typically called as part of configure.
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file=sys.stdout):
+++  print file, msg
+++  file.write(msg)
++ 
++ import distutils.sysconfig
++ import os
++@@ -18,7 +72,7 @@ from distutils.version import StrictVers
++ 
++ 
++ # Minimum version of Python required to build.
++-MINIMUM_PYTHON_VERSION = StrictVersion('2.7.3')
+++MINIMUM_PYTHON_VERSION = StrictVersion('2.4')
++ MINIMUM_PYTHON_MAJOR = 2
++ 
++ 
++@@ -140,7 +194,9 @@ class VirtualenvManager(object):
++         args = [sys.executable, self.virtualenv_script_path,
++             self.virtualenv_root]
++ 
++-        result = subprocess.call(args, stdout=self.log_handle,
+++#        result = subprocess.call(args, stdout=self.log_handle,
+++#            stderr=subprocess.STDOUT, env=env)
+++        result = subprocess.call(args,
++             stderr=subprocess.STDOUT, env=env)
++ 
++         if result:
++@@ -149,9 +205,11 @@ class VirtualenvManager(object):
++         return self.virtualenv_root
++ 
++     def packages(self):
++-        with file(self.manifest_path, 'rU') as fh:
+++        fh = file(self.manifest_path, 'rU')
+++        if 1:
++             packages = [line.rstrip().split(':')
++                         for line in fh]
+++        fh.close()
++         return packages
++ 
++     def populate(self):
++@@ -234,7 +292,8 @@ class VirtualenvManager(object):
++ 
++                 path = os.path.join(self.topsrcdir, package[1])
++ 
++-                with open(os.path.join(python_lib, package[0]), 'a') as f:
+++                f = open(os.path.join(python_lib, package[0]), 'a')
+++                if 1:
++                     # This path is relative to the .pth file.  Using a
++                     # relative path allows the srcdir/objdir combination
++                     # to be moved around (as long as the paths relative to
++@@ -245,6 +304,7 @@ class VirtualenvManager(object):
++                         # When objdir is on a separate drive, relpath throws
++                         f.write("%s\n" % os.path.join(python_lib, path))
++ 
+++                f.close()
++                 return True
++ 
++             if package[0] == 'optional':
++@@ -252,18 +312,18 @@ class VirtualenvManager(object):
++                     handle_package(package[1:])
++                     return True
++                 except:
++-                    print('Error processing command. Ignoring', \
++-                        'because optional. (%s)' % ':'.join(package),
++-                        file=self.log_handle)
+++                    print24('Error processing command. Ignoring because optional. (%s)' % ':'.join(package))
++                     return False
++ 
++             if package[0] == 'objdir':
++                 assert len(package) == 2
++                 path = os.path.join(self.topobjdir, package[1])
++ 
++-                with open(os.path.join(python_lib, 'objdir.pth'), 'a') as f:
+++                f = open(os.path.join(python_lib, 'objdir.pth'), 'a')
+++                if 1:
++                     f.write('%s\n' % path)
++ 
+++                f.close()
++                 return True
++ 
++             raise Exception('Unknown action: %s' % package[0])
++@@ -354,7 +414,7 @@ class VirtualenvManager(object):
++         try:
++             output = subprocess.check_output(program, cwd=directory, stderr=subprocess.STDOUT)
++             print(output)
++-        except subprocess.CalledProcessError as e:
+++        except subprocess.CalledProcessError, e:
++             if 'Python.h: No such file or directory' in e.output:
++                 print('WARNING: Python.h not found. Install Python development headers.')
++             else:
++@@ -458,7 +518,7 @@ if __name__ == '__main__':
++ 
++     topsrcdir, topobjdir, virtualenv_path, manifest_path = sys.argv[1:5]
++     populate = False
++-
+++    #print "MANIFEST PATH", manifest_path
++     # This should only be called internally.
++     if sys.argv[1] == 'populate':
++         populate = True
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/chrome/flags.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/chrome/flags.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/chrome/flags.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/chrome/flags.py	2014-10-24 11:41:35.499880057 -0600
++@@ -5,7 +5,7 @@
++ import re
++ from distutils.version import LooseVersion
++ from mozpack.errors import errors
++-from collections import OrderedDict
+++from ordereddict import OrderedDict
++ 
++ 
++ class Flag(object):
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/chrome/manifest.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/chrome/manifest.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/chrome/manifest.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/chrome/manifest.py	2014-10-24 11:41:35.500880053 -0600
++@@ -8,7 +8,7 @@ from urlparse import urlparse
++ import mozpack.path
++ from mozpack.chrome.flags import Flags
++ from mozpack.errors import errors
++-
+++from rhrebase import all, any
++ 
++ class ManifestEntry(object):
++     '''
++@@ -196,8 +196,8 @@ class ManifestOverload(ManifestEntry):
++     @property
++     def localized(self):
++         u = urlparse(self.overload)
++-        return u.scheme == 'chrome' and \
++-               u.path.split('/')[0:2] == ['', 'locale']
+++        return u[0] == 'chrome' and \
+++               u[1].split('/')[0:2] == ['', 'locale']
++ 
++ 
++ class ManifestOverlay(ManifestOverload):
++@@ -246,8 +246,10 @@ class ManifestResource(ManifestEntry):
++         return self.serialize(self.name, self.target)
++ 
++     def rebase(self, base):
+++        #print self.target
++         u = urlparse(self.target)
++-        if u.scheme and u.scheme != 'jar':
+++        #print u, dir(u)
+++        if u[0] and u[0] != 'jar':
++             return ManifestEntry.rebase(self, base)
++         clone = ManifestEntry.rebase(self, base)
++         clone.target = mozpack.path.rebase(self.base, base, self.target)
++@@ -351,12 +353,14 @@ def parse_manifest(root, path, fileobj=N
++     linenum = 0
++     for line in fileobj:
++         linenum += 1
++-        with errors.context(path, linenum):
+++        errors.context(path, linenum)
+++        if 1:
++             e = parse_manifest_line(base, line)
++             if e:
++                 yield e
++ 
++ 
+++        #errors.context(path, linenum).__exit__(0, 0, 0)
++ def is_manifest(path):
++     '''
++     Return whether the given path is that of a manifest file.
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/copier.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/copier.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/copier.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/copier.py	2014-10-24 11:41:35.500880053 -0600
++@@ -12,11 +12,12 @@ from mozpack.files import (
++ )
++ import mozpack.path
++ import errno
++-from collections import (
++-    Counter,
++-    OrderedDict,
+++from mycollections import (
+++    namedtuple
++ )
+++from Counter import Counter
++ 
+++from ordereddict import OrderedDict
++ 
++ class FileRegistry(object):
++     '''
++@@ -50,10 +51,13 @@ class FileRegistry(object):
++         '''
++         Add a BaseFile instance to the container, under the given path.
++         '''
++-        assert isinstance(content, BaseFile)
+++        assert isinstance(content, BaseFile)           
++         if path in self._files:
++             return errors.error("%s already added" % path)
++-        if self._required_directories[path] > 0:
+++        #print ("REQUIRED_DIRS")
+++        #print(self._required_directories)
+++        #print ("PATH IS "+ path)
+++        if self._required_directories.has_key(path) and self._required_directories[path] > 0:
++             return errors.error("Can't add %s: it is a required directory" %
++                                 path)
++         # Check whether any parent of the given path is already stored
++@@ -221,7 +225,7 @@ class FileCopier(FileRegistry):
++         # manage children of destination, not its parents.
++         try:
++             os.makedirs(destination)
++-        except OSError as e:
+++        except OSError, e:
++             if e.errno != errno.EEXIST:
++                 raise
++ 
++@@ -256,7 +260,7 @@ class FileCopier(FileRegistry):
++         for d in sorted(required_dirs, key=len):
++             try:
++                 os.mkdir(d)
++-            except OSError as error:
+++            except OSError, error:
++                 if error.errno != errno.EEXIST:
++                     raise
++ 
++@@ -468,11 +472,14 @@ class Jarrer(FileRegistry, BaseFile):
++             old_jar = JarReader(fileobj=dest)
++         except Exception:
++             old_jar = []
++-
+++        #print "old jar", old_jar
+++        #for f in old_jar:
+++        #  print f.filename, f
++         old_contents = dict([(f.filename, f) for f in old_jar])
++-
++-        with JarWriter(fileobj=dest, compress=self.compress,
++-                       optimize=self.optimize) as jar:
+++        #print "Old content", old_contents
+++        #print "JarWriter"
+++        jar = JarWriter(fileobj=dest, compress=self.compress, optimize=self.optimize).__enter__()
+++        if 1:
++             for path, file in self:
++                 if path in old_contents:
++                     deflater = DeflaterDest(old_contents[path], self.compress)
++@@ -483,6 +490,7 @@ class Jarrer(FileRegistry, BaseFile):
++             if self._preload:
++                 jar.preload(self._preload)
++ 
+++        jar.__exit__(0, 0, 0)
++     def open(self):
++         raise RuntimeError('unsupported')
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/errors.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/errors.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/errors.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/errors.py	2014-10-24 11:41:35.500880053 -0600
++@@ -3,7 +3,7 @@
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++ import sys
++-from contextlib import contextmanager
+++
++ 
++ 
++ class ErrorMessage(Exception):
++@@ -38,30 +38,40 @@ class ErrorCollector(object):
++     information when a context is provided. Context is defined by a pair
++     (filename, linenumber), and may be set with errors.context() used as a
++     context manager:
++-        with errors.context(filename, linenumber):
+++        errors.context(filename, linenumber).__enter__()
+++        if 1:
++             errors.warn(message)
++ 
+++        errors.context(filename, linenumber).__exit__(0, 0, 0)
++     Arbitrary nesting is supported, both for errors.context calls:
++-        with errors.context(filename1, linenumber1):
+++        errors.context(filename1, linenumber1).__enter__()
+++        if 1:
++             errors.warn(message)
++-            with errors.context(filename2, linenumber2):
+++            errors.context(filename2, linenumber2).__enter__()
+++            if 1:
++                 errors.warn(message)
++ 
+++            errors.context(filename2, linenumber2).__exit__(0, 0, 0)
+++        errors.context(filename1, linenumber1).__exit__(0, 0, 0)
++     as well as for function calls:
++         def func():
++             errors.warn(message)
++-        with errors.context(filename, linenumber):
+++        errors.context(filename, linenumber).__enter__()
+++        if 1:
++             func()
++ 
+++        errors.context(filename, linenumber).__exit__(0, 0, 0)
++     Errors and fatal errors can have their exception thrown at a later time,
++     allowing for several different errors to be reported at once before
++     throwing. This is achieved with errors.accumulate() as a context manager:
++-        with errors.accumulate():
+++        errors.accumulate().__enter__()
+++        if 1:
++             if test1:
++                 errors.error(message1)
++             if test2:
++                 errors.error(message2)
++ 
+++        errors.accumulate().__exit__(0, 0, 0)
++     In such cases, a single AccumulatedErrors exception is thrown, but doesn't
++     contain information about the exceptions. The logged messages do.
++     '''
++@@ -110,19 +120,19 @@ class ErrorCollector(object):
++         if self._context:
++             return self._context[-1]
++ 
++-    @contextmanager
+++    #@contextmanager
++     def context(self, file, line):
++         if file and line:
++             self._context.append((file, line))
++-        yield
+++        # just for now yield
++         if file and line:
++             self._context.pop()
++ 
++-    @contextmanager
+++    #@contextmanager
++     def accumulate(self):
++         assert self._count is None
++         self._count = 0
++-        yield
+++        #just for now yield
++         count = self._count
++         self._count = None
++         if count:
++@@ -131,7 +141,10 @@ class ErrorCollector(object):
++     @property
++     def count(self):
++         # _count can be None.
++-        return self._count if self._count else 0
+++        if self._count:
+++          return self._count
+++        else:
+++          return 0
++ 
++ 
++ errors = ErrorCollector()
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/executables.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/executables.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/executables.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/executables.py	2014-10-24 11:41:35.500880053 -0600
++@@ -27,7 +27,8 @@ def get_type(path):
++     Check the signature of the give file and returns what kind of executable
++     matches.
++     '''
++-    with open(path, 'rb') as f:
+++    f = open(path, 'rb')
+++    if 1:
++         signature = f.read(4)
++         if len(signature) < 4:
++             return UNKNOWN
++@@ -54,6 +55,7 @@ def get_type(path):
++         return UNKNOWN
++ 
++ 
+++    f.close()
++ def is_executable(path):
++     '''
++     Return whether a given file path points to an executable or a library,
++@@ -92,7 +94,11 @@ def strip(path):
++     '''
++     from buildconfig import substs
++     strip = substs['STRIP']
++-    flags = substs['STRIP_FLAGS'].split() if 'STRIP_FLAGS' in substs else []
+++    flags = None
+++    if 'STRIP_FLAGS' in substs:
+++      flags = substs['STRIP_FLAGS'].split()
+++    else:
+++      flags = []
++     cmd = [strip] + flags + [path]
++     if subprocess.call(cmd) != 0:
++         errors.fatal('Error executing ' + ' '.join(cmd))
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/files.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/files.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/files.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/files.py	2014-10-24 11:41:35.501880049 -0600
++@@ -20,14 +20,14 @@ from mozpack.executables import (
++     elfhack,
++ )
++ from mozpack.chrome.manifest import ManifestEntry
++-from io import BytesIO
+++from StringIO import StringIO as BytesIO
++ from mozpack.errors import (
++     ErrorMessage,
++     errors,
++ )
++ from mozpack.mozjar import JarReader
++ import mozpack.path
++-from collections import OrderedDict
+++from ordereddict import OrderedDict 
++ from jsmin import JavascriptMinify
++ from tempfile import (
++     mkstemp,
++@@ -215,8 +215,10 @@ class ExecutableFile(File):
++             return False
++         try:
++             if may_strip(dest):
+++                #print "strip", dest
++                 strip(dest)
++             if may_elfhack(dest):
+++                #print "elfhack", dest
++                 elfhack(dest)
++         except ErrorMessage:
++             os.remove(dest)
++@@ -263,7 +265,7 @@ class AbsoluteSymlinkFile(File):
++ 
++         try:
++             st = os.lstat(dest)
++-        except OSError as ose:
+++        except OSError, ose:
++             if ose.errno != errno.ENOENT:
++                 raise
++ 
++@@ -394,11 +396,13 @@ class PreprocessedFile(BaseFile):
++         # dependencies from that file to our list.
++         if self.depfile and os.path.exists(self.depfile):
++             target = mozpack.path.normpath(dest.name)
++-            with open(self.depfile, 'rb') as fileobj:
+++            fileobj = open(self.depfile, 'rb')
+++            if 1:
++                 for rule in makeutil.read_dep_makefile(fileobj):
++                     if target in rule.targets():
++                         pp_deps.update(rule.dependencies())
++ 
+++            fileobj.close()
++         skip = False
++         if dest.exists() and skip_if_older:
++             # If a dependency file was specified, and it doesn't exist,
++@@ -417,9 +421,11 @@ class PreprocessedFile(BaseFile):
++             deps_out = FileAvoidWrite(self.depfile)
++         pp = Preprocessor(defines=self.defines, marker=self.marker)
++ 
++-        with open(self.path, 'rU') as input:
+++        input = open(self.path, 'rU')
+++        if 1:
++             pp.processFile(input=input, output=dest, depfile=deps_out)
++ 
+++        input.close()
++         dest.close()
++         if self.depfile:
++             deps_out.close()
++@@ -541,7 +547,11 @@ class ManifestFile(BaseFile):
++         currently but could in the future.
++     '''
++     def __init__(self, base, entries=None):
++-        self._entries = entries if entries else []
+++        self._entries = None
+++        if entries:
+++          self._entries = entries
+++        else:
+++          self._entries = []
++         self._base = base
++ 
++     def add(self, entry):
++@@ -619,7 +629,10 @@ class MinifiedJavaScript(BaseFile):
++         input_source = self._file.open().read()
++         output_source = output.getvalue()
++ 
++-        with NamedTemporaryFile() as fh1, NamedTemporaryFile() as fh2:
+++        fh1 = NamedTemporaryFile().__enter__()
+++        fh2 = NamedTemporaryFile().__enter__()
+++        if 1:
+++        #with NamedTemporaryFile() as fh1, NamedTemporaryFile() as fh2:
++             fh1.write(input_source)
++             fh2.write(output_source)
++             fh1.flush()
++@@ -629,7 +642,7 @@ class MinifiedJavaScript(BaseFile):
++                 args = list(self._verify_command)
++                 args.extend([fh1.name, fh2.name])
++                 subprocess.check_output(args, stderr=subprocess.STDOUT)
++-            except subprocess.CalledProcessError as e:
+++            except subprocess.CalledProcessError, e:
++                 errors.warn('JS minification verification failed for %s:' %
++                     (getattr(self._file, 'path', '<unknown>')))
++                 # Prefix each line with "Warning:" so mozharness doesn't
++@@ -638,6 +651,8 @@ class MinifiedJavaScript(BaseFile):
++                     errors.warn(line)
++ 
++                 return self._file.open()
+++            fh1.close()
+++            fh2.close()
++ 
++         return output
++ 
++@@ -685,9 +700,10 @@ class BaseFinder(object):
++         '''
++         Iterates over all files under the base directory (excluding files
++         starting with a '.' and files at any level under a directory starting
++-        with a '.').
++-            for path, file in finder:
+++        a '.'). for path, file in finder.__enter__()
+++        if 1:
++                 ...
+++        a '.'). for path, file in finder.__exit__(0, 0, 0)
++         '''
++         return self.find('')
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/manifests.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/manifests.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/manifests.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/manifests.py	2014-10-24 11:41:35.501880049 -0600
++@@ -2,12 +2,12 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
++ 
++-from contextlib import contextmanager
++-import json
++ 
++-from .files import (
+++
+++import simplejson as json
+++
+++from files import (
++     AbsoluteSymlinkFile,
++     ExistingFile,
++     File,
++@@ -15,7 +15,7 @@ from .files import (
++     PreprocessedFile,
++ )
++ import mozpack.path as mozpath
++-
+++from contextdecorator import contextmanager
++ 
++ # This probably belongs in a more generic module. Where?
++ @contextmanager
++@@ -29,11 +29,10 @@ def _auto_fileobj(path, fileobj, mode='r
++     if path:
++         fileobj = open(path, mode)
++ 
++-    try:
++-        yield fileobj
++-    finally:
++-        if path:
++-            fileobj.close()
+++    #try:
+++    yield fileobj
+++    if path:
+++        fileobj.close()
++ 
++ 
++ class UnreadableInstallManifest(Exception):
++@@ -108,10 +107,13 @@ class InstallManifest(object):
++         self._source_file = None
++ 
++         if path or fileobj:
++-            with _auto_fileobj(path, fileobj, 'rb') as fh:
+++            fh = _auto_fileobj(path, fileobj, 'rb').__enter__()
+++            if 1:
++                 self._source_file = fh.name
++                 self._load_from_fileobj(fh)
++ 
+++            #fh.__exit__(0, 0, 0)
+++            #fh.close()
++     def _load_from_fileobj(self, fileobj):
++         version = fileobj.readline().rstrip()
++         if version not in ('1', '2', '3', '4'):
++@@ -209,7 +211,8 @@ class InstallManifest(object):
++ 
++         It is an error if both are specified.
++         """
++-        with _auto_fileobj(path, fileobj, 'wb') as fh:
+++        fh = _auto_fileobj(path, fileobj, 'wb').__enter__()
+++        if 1:
++             fh.write('%d\n' % self.CURRENT_VERSION)
++ 
++             for dest in sorted(self._dests):
++@@ -220,6 +223,7 @@ class InstallManifest(object):
++                 fh.write('%s\n' % self.FIELD_SEPARATOR.join(
++                     p.encode('utf-8') for p in parts))
++ 
+++        #fh.close()
++     def add_symlink(self, source, dest):
++         """Add a symlink to this manifest.
++ 
++@@ -289,7 +293,10 @@ class InstallManifest(object):
++         self._dests[dest] = entry
++ 
++     def _get_deps(self, dest):
++-        return {self._source_file} if self._source_file else set()
+++        if self._source_file:
+++            return (self._source_file)
+++        else:
+++            return set()
++ 
++     def populate_registry(self, registry):
++         """Populate a mozpack.copier.FileRegistry instance with data from us.
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/mozjar.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/mozjar.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/mozjar.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/mozjar.py	2014-10-24 11:41:35.501880049 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from io import BytesIO
+++from StringIO import StringIO as BytesIO
++ import struct
++ import zlib
++ import os
++@@ -10,8 +10,9 @@ from zipfile import (
++     ZIP_STORED,
++     ZIP_DEFLATED,
++ )
++-from collections import OrderedDict
++-from urlparse import urlparse, ParseResult
+++from ordereddict import OrderedDict
+++from urlparse import urlparse
+++# ParseResult
++ import mozpack.path
++ 
++ JAR_STORED = ZIP_STORED
++@@ -94,8 +95,6 @@ class JarStruct(object):
++             else:
++                 size = sizes[t]
++                 value = data[offset:offset + size]
++-                if isinstance(value, memoryview):
++-                    value = value.tobytes()
++             if not name in sizes:
++                 self._values[name] = value
++             else:
++@@ -110,7 +109,11 @@ class JarStruct(object):
++         for name, t in self.STRUCT.iteritems():
++             if name in self.size_fields:
++                 continue
++-            self._values[name] = 0 if t in JarStruct.TYPE_MAPPING else ''
+++            self._values[name] = None
+++            if t in JarStruct.TYPE_MAPPING:
+++              self._values[name] = 0
+++            else:
+++              self._values[name] = ''
++ 
++     @staticmethod
++     def get_data(type, data):
++@@ -122,8 +125,6 @@ class JarStruct(object):
++         assert data is not None
++         format, size = JarStruct.TYPE_MAPPING[type]
++         data = data[:size]
++-        if isinstance(data, memoryview):
++-            data = data.tobytes()
++         return struct.unpack('<' + format, data)[0], size
++ 
++     def serialize(self):
++@@ -261,12 +262,12 @@ class JarFileReader(object):
++         the file data.
++         '''
++         assert header['compression'] in [JAR_DEFLATED, JAR_STORED]
++-        self._data = data
++         # Copy some local file header fields.
++         for name in ['filename', 'compressed_size',
++                      'uncompressed_size', 'crc32']:
++             setattr(self, name, header[name])
++         self.compressed = header['compression'] == JAR_DEFLATED
+++        self._data = data[:header['compressed_size']]
++ 
++     def read(self, length=-1):
++         '''
++@@ -287,7 +288,7 @@ class JarFileReader(object):
++         '''
++         return iter(self.readlines())
++ 
++-    def seek(self, pos, whence=os.SEEK_SET):
+++    def seek(self, pos, whence=0):
++         '''
++         Change the current position in the uncompressed data. Subsequent reads
++         will start from there.
++@@ -316,9 +317,7 @@ class JarFileReader(object):
++             return self._uncompressed_data
++         data = self.compressed_data
++         if self.compressed:
++-            data = zlib.decompress(data.tobytes(), -MAX_WBITS)
++-        else:
++-            data = data.tobytes()
+++            data = zlib.decompress(data, -MAX_WBITS)
++         if len(data) != self.uncompressed_size:
++             raise JarReaderError('Corrupted file? %s' % self.filename)
++         self._uncompressed_data = BytesIO(data)
++@@ -339,7 +338,7 @@ class JarReader(object):
++             data = fileobj.read()
++         else:
++             data = open(file, 'rb').read()
++-        self._data = memoryview(data)
+++        self._data = buffer(data)
++         # The End of Central Directory Record has a variable size because of
++         # comments it may contain, so scan for it from the end of the file.
++         offset = -CDIR_END_SIZE
++@@ -666,8 +665,6 @@ class Deflater(object):
++         self._data.write(data)
++         if self.compress:
++             if self._deflater:
++-                if isinstance(data, memoryview):
++-                    data = data.tobytes()
++                 self._deflated.write(self._deflater.compress(data))
++             else:
++                 raise JarWriterError("Can't write after flush")
++@@ -780,6 +777,7 @@ class JarLog(dict):
++         - jar:jar:file:///{path}!/{subpath}!/{subpath2} becomes
++            ({path}, {subpath}, {subpath2})
++         '''
+++        #print url, dir(url)
++         if not isinstance(url, ParseResult):
++             # Assume that if it doesn't start with jar: or file:, it's a path.
++             if not url.startswith(('jar:', 'file:')):
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/packager/formats.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/packager/formats.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/packager/formats.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/packager/formats.py	2014-10-24 11:41:35.502880045 -0600
++@@ -2,6 +2,8 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
+++from rhrebase import all, any
+++
++ from mozpack.chrome.manifest import (
++     Manifest,
++     ManifestInterfaces,
++@@ -100,8 +102,7 @@ class FlatFormatter(object):
++                                                        '%s.manifest' % name))
++         if not self.copier.contains(path):
++             assert mozpack.path.basedir(entry.base, [base]) == base
++-            # Add a reference to the manifest file in the parent manifest, if
++-            # the manifest file is not a root manifest.
+++            # Add a reference to the manifest file in the parent manifest, if # the manifest file is not a root manifest.
++             if len(entry.base) > len(base):
++                 parent = mozpack.path.dirname(entry.base)
++                 relbase = mozpack.path.basename(entry.base)
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/packager/__init__.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/packager/__init__.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/packager/__init__.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/packager/__init__.py	2014-10-24 11:41:35.502880045 -0600
++@@ -99,7 +99,11 @@ class Component(object):
++             raise ValueError('No component found')
++         if not re.match('[a-zA-Z0-9_\-]+$', component):
++             raise ValueError('Bad component name ' + component)
++-        options = Component._split_options(splits[1]) if len(splits) > 1 else {}
+++        options = None
+++        if len(splits) > 1:
+++          options = Component._split_options(splits[1])
+++        else:
+++          options = {}
++         return component, options
++ 
++     @staticmethod
++@@ -109,7 +113,7 @@ class Component(object):
++         '''
++         try:
++             name, options = Component._split_component_and_options(string)
++-        except ValueError as e:
+++        except ValueError, e:
++             errors.fatal('Malformed manifest: %s' % e)
++             return
++         destdir = options.pop('destdir', '')
++@@ -174,10 +178,12 @@ class PreprocessorOutputWrapper(object):
++ 
++     def write(self, str):
++         file = os.path.normpath(os.path.abspath(self._pp.context['FILE']))
++-        with errors.context(file, self._pp.context['LINE']):
+++        errors.context(file, self._pp.context['LINE'])
+++        if 1:
++             self._parser.handle_line(str)
++ 
++ 
+++        #errors.context(file, self._pp.context['LINE']).__exit__(0, 0, 0)
++ def preprocess(input, parser, defines={}):
++     '''
++     Preprocess the file-like input with the given defines, and send the
++@@ -213,8 +219,10 @@ class CallDeque(deque):
++             except IndexError:
++                 return
++             if context:
++-                with errors.context(context[0], context[1]):
+++                errors.context(context[0], context[1]).__enter__()
+++                if 1:
++                     function(*args)
+++                errors.context(context[0], context[1]).__exit__(0, 0, 0)
++             else:
++                 function(*args)
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/packager/l10n.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/packager/l10n.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/packager/l10n.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/packager/l10n.py	2014-10-24 11:41:35.502880045 -0600
++@@ -168,7 +168,9 @@ def repack(source, l10n, non_resources=[
++                                      optimize=app_finder.optimizedjars,
++                                      non_resources=non_resources)
++ 
++-    with errors.accumulate():
+++    errors.accumulate().__enter__()
+++    if 1:
++         _repack(app_finder, l10n_finder, copier, formatter, non_chrome)
+++    errors.accumulate().__exit__(0, 0, 0)
++     copier.copy(source, skip_if_older=False)
++     generate_precomplete(source)
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/packager/unpack.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/packager/unpack.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/packager/unpack.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/packager/unpack.py	2014-10-24 11:41:35.502880045 -0600
++@@ -68,8 +68,11 @@ class UnpackFinder(FileFinder):
++             # jar: urls. If there are some, the files contained in the jar they
++             # point to, go under a directory named after the jar.
++             if is_manifest(p):
++-                m = self.files[p] if self.files.contains(p) \
++-                    else ManifestFile(base)
+++                m = None
+++                if self.files.contains(p):
+++                  m = self.files[p]
+++                else:
+++                  m = ManifestFile(base)
++                 for e in parse_manifest(self.base, p, f.open()):
++                     m.add(self._handle_manifest_entry(e, jars))
++                 if self.files.contains(p):
++@@ -82,8 +85,11 @@ class UnpackFinder(FileFinder):
++         for j in jar:
++             path = mozpack.path.join(base, j.filename)
++             if is_manifest(j.filename):
++-                m = self.files[path] if self.files.contains(path) \
++-                    else ManifestFile(mozpack.path.dirname(path))
+++                m = None
+++                if self.files.contains(path):
+++                  m = self.files[path]
+++                else:
+++                  m = ManifestFile(mozpack.path.dirname(path))
++                 for e in parse_manifest(None, path, j):
++                     m.add(e)
++                 if not self.files.contains(path):
++@@ -95,10 +101,10 @@ class UnpackFinder(FileFinder):
++     def _handle_manifest_entry(self, entry, jars):
++         jarpath = None
++         if isinstance(entry, ManifestEntryWithRelPath) and \
++-                urlparse(entry.relpath).scheme == 'jar':
+++                urlparse(entry.relpath)[0] == 'jar':
++             jarpath, entry = self._unjarize(entry, entry.relpath)
++         elif isinstance(entry, ManifestResource) and \
++-                urlparse(entry.target).scheme == 'jar':
+++                urlparse(entry.target)[0] == 'jar':
++             jarpath, entry = self._unjarize(entry, entry.target)
++         if jarpath:
++             # Don't defer unpacking the jar file. If we already saw
++@@ -153,7 +159,7 @@ class UnpackFinder(FileFinder):
++         the new entry.
++         '''
++         base = entry.base
++-        jar, relpath = urlparse(relpath).path.split('!', 1)
+++        jar, relpath = urlparse(relpath)[1].split('!', 1)
++         entry = entry.rebase(mozpack.path.join(base, 'jar:%s!' % jar)) \
++             .move(mozpack.path.join(base, mozpack.path.splitext(jar)[0])) \
++             .rebase(base)
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/path.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/path.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/path.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/path.py	2014-10-24 11:41:35.503880041 -0600
++@@ -1,6 +1,60 @@
++ # This Source Code Form is subject to the terms of the Mozilla Public
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+++# relpath
+++import os, sys
+++# Creates os.path.relpath for Python 2.4
+++
+++if not hasattr(os, "relpath"):
+++    if os.path is sys.modules.get("ntpath"):
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++            if start_list[0].lower() != path_list[0].lower():
+++                unc_path, rest = os.path.splitunc(path)
+++                unc_start, rest = os.path.splitunc(start)
+++                if bool(unc_path) ^ bool(unc_start):
+++                    raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
+++                                                                        % (path, start))
+++                else:
+++                    raise ValueError("path is on drive %s, start on drive %s"
+++                                                        % (path_list[0], start_list[0]))
+++            # Work out how much of the filepath is shared by start and path.
+++            for i in range(min(len(start_list), len(path_list))):
+++                if start_list[i].lower() != path_list[i].lower():
+++                    break
+++            else:
+++                i += 1
+++ 
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++    
+++    else:
+++        # default to posixpath definition
+++        def relpath(path, start=os.path.curdir):
+++            """Return a relative version of a path"""
+++        
+++            if not path:
+++                raise ValueError("no path specified")
+++        
+++            start_list = os.path.abspath(start).split(os.path.sep)
+++            path_list = os.path.abspath(path).split(os.path.sep)
+++        
+++            # Work out how much of the filepath is shared by start and path.
+++            i = len(os.path.commonprefix([start_list, path_list]))
+++        
+++            rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+++            if not rel_list:
+++                return os.path.curdir
+++            return os.path.join(*rel_list)
+++        
+++    os.path.relpath = relpath
++ 
++ import posixpath
++ import os
++@@ -25,7 +79,10 @@ def normsep(path):
++ 
++ def relpath(path, start):
++     rel = normsep(os.path.relpath(path, start))
++-    return '' if rel == '.' else rel
+++    if rel == '.':
+++      return ''
+++    else:
+++      return rel
++ 
++ 
++ def abspath(path):
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/test/test_chrome_manifest.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/test/test_chrome_manifest.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/test/test_chrome_manifest.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/test/test_chrome_manifest.py	2014-10-24 11:41:35.503880041 -0600
++@@ -131,7 +131,8 @@ class TestManifestErrors(TestErrors, uni
++             'binary-component bar.so',
++             'unsupported foo',
++         ]
++-        with mozunit.MockedOpen({'manifest': '\n'.join(manifest)}):
+++        mozunit.MockedOpen({'manifest': '\n'.join(manifest)}).__enter__()
+++        if 1:
++             with self.assertRaises(AccumulatedErrors):
++                 with errors.accumulate():
++                     list(parse_manifest(os.curdir, 'manifest'))
++@@ -145,5 +146,6 @@ class TestManifestErrors(TestErrors, uni
++             self.assertTrue(out[1].startswith('Error: %s:4: ' % path))
++ 
++ 
+++        mozunit.MockedOpen({'manifest': '\n'.join(manifest)}).__exit__(0, 0, 0)
++ if __name__ == '__main__':
++     mozunit.main()
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/test/test_copier.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/test/test_copier.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/test/test_copier.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/test/test_copier.py	2014-10-24 11:41:35.503880041 -0600
++@@ -290,13 +290,17 @@ class TestFileCopier(TestWithTmpDir):
++ 
++     def test_permissions(self):
++         """Ensure files without write permission can be deleted."""
++-        with open(self.tmppath('dummy'), 'a'):
+++        open(self.tmppath('dummy'), 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(self.tmppath('dummy'), 'a').__exit__(0, 0, 0)
++         p = self.tmppath('no_perms')
++-        with open(p, 'a'):
+++        open(p, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(p, 'a').__exit__(0, 0, 0)
++         # Make file and directory unwritable. Reminder: making a directory
++         # unwritable prevents modifications (including deletes) from the list
++         # of files in that directory.
++@@ -313,16 +317,20 @@ class TestFileCopier(TestWithTmpDir):
++         copier = FileCopier()
++         copier.add('foo', GeneratedFile('foo'))
++ 
++-        with open(self.tmppath('bar'), 'a'):
+++        open(self.tmppath('bar'), 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(self.tmppath('bar'), 'a').__exit__(0, 0, 0)
++         os.mkdir(self.tmppath('emptydir'))
++         d = self.tmppath('populateddir')
++         os.mkdir(d)
++ 
++-        with open(self.tmppath('populateddir/foo'), 'a'):
+++        open(self.tmppath('populateddir/foo'), 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(self.tmppath('populateddir/foo'), 'a').__exit__(0, 0, 0)
++         result = copier.copy(self.tmpdir, remove_unaccounted=False)
++ 
++         self.assertEqual(self.all_files(self.tmpdir), set(['foo', 'bar',
++@@ -336,16 +344,20 @@ class TestFileCopier(TestWithTmpDir):
++         copier = FileCopier()
++         copier.add('foo', GeneratedFile('foo'))
++ 
++-        with open(self.tmppath('bar'), 'a'):
+++        open(self.tmppath('bar'), 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(self.tmppath('bar'), 'a').__exit__(0, 0, 0)
++         os.mkdir(self.tmppath('emptydir'))
++         d = self.tmppath('populateddir')
++         os.mkdir(d)
++ 
++-        with open(self.tmppath('populateddir/foo'), 'a'):
+++        open(self.tmppath('populateddir/foo'), 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(self.tmppath('populateddir/foo'), 'a').__exit__(0, 0, 0)
++         result = copier.copy(self.tmpdir, remove_unaccounted=False,
++             remove_empty_directories=False)
++ 
++@@ -390,16 +402,22 @@ class TestFilePurger(TestWithTmpDir):
++         extra = os.path.join(self.tmpdir, 'extra')
++         empty_dir = os.path.join(self.tmpdir, 'dir')
++ 
++-        with open(existing, 'a'):
+++        open(existing, 'a').__enter__()
+++        if 1:
++             pass
++ 
++-        with open(extra, 'a'):
+++        open(existing, 'a').__exit__(0, 0, 0)
+++        open(extra, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(extra, 'a').__exit__(0, 0, 0)
++         os.mkdir(empty_dir)
++-        with open(os.path.join(empty_dir, 'foo'), 'a'):
+++        open(os.path.join(empty_dir, 'foo'), 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(os.path.join(empty_dir, 'foo'), 'a').__exit__(0, 0, 0)
++         self.assertTrue(os.path.exists(existing))
++         self.assertTrue(os.path.exists(extra))
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/test/test_errors.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/test/test_errors.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/test/test_errors.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/test/test_errors.py	2014-10-24 11:41:35.503880041 -0600
++@@ -40,25 +40,32 @@ class TestErrorsImpl(TestErrors, unittes
++         self.assertEquals(self.get_output(), ['Warning: foo', 'Warning: bar'])
++ 
++     def test_no_error(self):
++-        with errors.accumulate():
+++        errors.accumulate().__enter__()
+++        if 1:
++             errors.warn('1')
++ 
+++        errors.accumulate().__exit__(0, 0, 0)
++     def test_simple_error(self):
++-        with self.assertRaises(AccumulatedErrors):
+++        self.assertRaises(AccumulatedErrors).__enter__()
+++        if 1:
++             with errors.accumulate():
++                 errors.error('1')
+++        self.assertRaises(AccumulatedErrors).__exit__(0, 0, 0)
++         self.assertEquals(self.get_output(), ['Error: 1'])
++ 
++     def test_error_loop(self):
++-        with self.assertRaises(AccumulatedErrors):
+++        self.assertRaises(AccumulatedErrors).__enter__()
+++        if 1:
++             with errors.accumulate():
++                 for i in range(3):
++                     errors.error('%d' % i)
+++        self.assertRaises(AccumulatedErrors).__exit__(0, 0, 0)
++         self.assertEquals(self.get_output(),
++                           ['Error: 0', 'Error: 1', 'Error: 2'])
++ 
++     def test_multiple_errors(self):
++-        with self.assertRaises(AccumulatedErrors):
+++        self.assertRaises(AccumulatedErrors).__enter__()
+++        if 1:
++             with errors.accumulate():
++                 errors.error('foo')
++                 for i in range(3):
++@@ -67,12 +74,14 @@ class TestErrorsImpl(TestErrors, unittes
++                     else:
++                         errors.error('%d' % i)
++                 errors.error('bar')
+++        self.assertRaises(AccumulatedErrors).__exit__(0, 0, 0)
++         self.assertEquals(self.get_output(),
++                           ['Error: foo', 'Error: 0', 'Error: 1',
++                            'Warning: 2', 'Error: bar'])
++ 
++     def test_errors_context(self):
++-        with self.assertRaises(AccumulatedErrors):
+++        self.assertRaises(AccumulatedErrors).__enter__()
+++        if 1:
++             with errors.accumulate():
++                 self.assertEqual(errors.get_context(), None)
++                 with errors.context('foo', 1):
++@@ -83,6 +92,7 @@ class TestErrorsImpl(TestErrors, unittes
++                         errors.error('b')
++                     self.assertEqual(errors.get_context(), ('foo', 1))
++                     errors.error('c')
+++        self.assertRaises(AccumulatedErrors).__exit__(0, 0, 0)
++         self.assertEqual(self.get_output(), [
++             'Error: foo:1: a',
++             'Error: bar:2: b',
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/test/test_files.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/test/test_files.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/test/test_files.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/test/test_files.py	2014-10-24 11:41:35.504880036 -0600
++@@ -53,9 +53,11 @@ class TestWithTmpDir(unittest.TestCase):
++             return
++ 
++         dummy_path = self.tmppath('dummy_file')
++-        with open(dummy_path, 'a'):
+++        open(dummy_path, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(dummy_path, 'a').__exit__(0, 0, 0)
++         try:
++             os.symlink(dummy_path, self.tmppath('dummy_symlink'))
++             os.remove(self.tmppath('dummy_symlink'))
++@@ -153,8 +155,10 @@ class TestFile(TestWithTmpDir):
++         dest = self.tmppath('dest')
++ 
++         for content in samples:
++-            with open(src, 'wb') as tmp:
+++            tmp = open(src, 'wb')
+++            if 1:
++                 tmp.write(content)
+++            tmp.__exit__(0, 0, 0)
++             # Ensure the destination file, when it exists, is older than the
++             # source
++             if os.path.exists(dest):
++@@ -177,8 +181,10 @@ class TestFile(TestWithTmpDir):
++         dest = MockDest()
++ 
++         for content in samples:
++-            with open(src, 'wb') as tmp:
+++            tmp = open(src, 'wb').__enter__()
+++            if 1:
++                 tmp.write(content)
+++            tmp.close()
++             f = File(src)
++             f.copy(dest)
++             self.assertEqual(content, dest.getvalue())
++@@ -189,9 +195,11 @@ class TestFile(TestWithTmpDir):
++         '''
++         src = self.tmppath('src')
++         content = ''.join(samples)
++-        with open(src, 'wb') as tmp:
+++        tmp = open(src, 'wb')
+++        if 1:
++             tmp.write(content)
++ 
+++        tmp.__exit__(0, 0, 0)
++         f = File(src)
++         self.assertEqual(content[:42], f.open().read(42))
++         self.assertEqual(content, f.open().read())
++@@ -204,9 +212,11 @@ class TestFile(TestWithTmpDir):
++         src = self.tmppath('src')
++         dest = self.tmppath('dest')
++ 
++-        with open(src, 'wb') as tmp:
+++        tmp = open(src, 'wb')
+++        if 1:
++             tmp.write('test')
++ 
+++        tmp.__exit__(0, 0, 0)
++         # Initial copy
++         f = File(src)
++         f.copy(dest)
++@@ -224,8 +234,10 @@ class TestFile(TestWithTmpDir):
++ 
++         # When the source file is older than the destination file, even with
++         # different content, no copy should occur.
++-        with open(src, 'wb') as tmp:
+++        tmp = open(src, 'wb').__enter__()
+++        if 1:
++             tmp.write('fooo')
+++        tmp.__exit__(0, 0, 0)
++         time = os.path.getmtime(dest) - 1
++         os.utime(src, (time, time))
++         f.copy(DestNoWrite(dest))
++@@ -246,14 +258,18 @@ class TestAbsoluteSymlinkFile(TestWithTm
++     def test_absolute_relative(self):
++         AbsoluteSymlinkFile('/foo')
++ 
++-        with self.assertRaisesRegexp(ValueError, 'Symlink target not absolute'):
+++        self.assertRaisesRegexp(ValueError, 'Symlink target not absolute').__enter__()
+++        if 1:
++             AbsoluteSymlinkFile('./foo')
++ 
+++        self.assertRaisesRegexp(ValueError, 'Symlink target not absolute').__exit__(0, 0, 0)
++     def test_symlink_file(self):
++         source = self.tmppath('test_path')
++-        with open(source, 'wt') as fh:
+++        fh = open(source, 'wt').__enter__()
+++        if 1:
++             fh.write('Hello world')
++ 
+++        fh.__exit__(0, 0, 0)
++         s = AbsoluteSymlinkFile(source)
++         dest = self.tmppath('symlink')
++         self.assertTrue(s.copy(dest))
++@@ -271,13 +287,17 @@ class TestAbsoluteSymlinkFile(TestWithTm
++         # If symlinks are supported, an existing file should be replaced by a
++         # symlink.
++         source = self.tmppath('test_path')
++-        with open(source, 'wt') as fh:
+++        fh = open(source, 'wt').__enter__()
+++        if 1:
++             fh.write('source')
++ 
+++        fh.__exit__(0, 0, 0)
++         dest = self.tmppath('dest')
++-        with open(dest, 'a'):
+++        open(dest, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(dest, 'a').__exit__(0, 0, 0)
++         s = AbsoluteSymlinkFile(source)
++         s.copy(dest, skip_if_older=False)
++ 
++@@ -295,9 +315,11 @@ class TestAbsoluteSymlinkFile(TestWithTm
++             return
++ 
++         source = self.tmppath('source')
++-        with open(source, 'a'):
+++        open(source, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(source, 'a').__exit__(0, 0, 0)
++         dest = self.tmppath('dest')
++ 
++         os.symlink(self.tmppath('bad'), dest)
++@@ -317,9 +339,11 @@ class TestAbsoluteSymlinkFile(TestWithTm
++         source = self.tmppath('source')
++         dest = self.tmppath('dest')
++ 
++-        with open(source, 'a'):
+++        open(source, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(source, 'a').__exit__(0, 0, 0)
++         os.symlink(source, dest)
++         link = os.readlink(dest)
++         self.assertEqual(link, source)
++@@ -338,9 +362,11 @@ class TestPreprocessedFile(TestWithTmpDi
++         src = self.tmppath('src')
++         dest = self.tmppath('dest')
++ 
++-        with open(src, 'wb') as tmp:
+++        tmp = open(src, 'wb').__enter__()
+++        if 1:
++             tmp.write('#ifdef FOO\ntest\n#endif')
++ 
+++        tmp.__exit__(0, 0, 0)
++         f = PreprocessedFile(src, depfile_path=None, marker='#', defines={'FOO': True})
++         self.assertTrue(f.copy(dest))
++ 
++@@ -355,9 +381,11 @@ class TestPreprocessedFile(TestWithTmpDi
++         dest = self.tmppath('dest')
++         depfile = self.tmppath('depfile')
++ 
++-        with open(src, 'wb') as tmp:
+++        tmp = open(src, 'wb').__enter__()
+++        if 1:
++             tmp.write('#ifdef FOO\ntest\n#endif')
++ 
+++        tmp.__exit__(0, 0, 0)
++         # Initial copy
++         f = PreprocessedFile(src, depfile_path=depfile, marker='#', defines={'FOO': True})
++         self.assertTrue(f.copy(dest))
++@@ -368,8 +396,10 @@ class TestPreprocessedFile(TestWithTmpDi
++ 
++         # When the source file is older than the destination file, even with
++         # different content, no copy should occur.
++-        with open(src, 'wb') as tmp:
+++        tmp = open(src, 'wb').__enter__()
+++        if 1:
++             tmp.write('#ifdef FOO\nfooo\n#endif')
+++        tmp.__exit__(0, 0, 0)
++         time = os.path.getmtime(dest) - 1
++         os.utime(src, (time, time))
++         self.assertFalse(f.copy(DestNoWrite(dest)))
++@@ -388,19 +418,25 @@ class TestPreprocessedFile(TestWithTmpDi
++         incl = self.tmppath('incl')
++         deps = self.tmppath('src.pp')
++ 
++-        with open(src, 'wb') as tmp:
+++        tmp = open(src, 'wb').__enter__()
+++        if 1:
++             tmp.write('#ifdef FOO\ntest\n#endif')
++ 
++-        with open(incl, 'wb') as tmp:
+++        tmp.__exit__(0, 0, 0)
+++        tmp = open(incl, 'wb').__enter__()
+++        if 1:
++             tmp.write('foo bar')
++ 
+++        tmp.__exit__(0, 0, 0)
++         # Initial copy
++         f = PreprocessedFile(src, depfile_path=deps, marker='#', defines={'FOO': True})
++         self.assertTrue(f.copy(dest))
++ 
++         # Update the source so it #includes the include file.
++-        with open(src, 'wb') as tmp:
+++        tmp = open(src, 'wb').__enter__()
+++        if 1:
++             tmp.write('#include incl\n')
+++        tmp.__exit__(0, 0, 0)
++         time = os.path.getmtime(dest) + 1
++         os.utime(src, (time, time))
++         self.assertTrue(f.copy(dest))
++@@ -409,8 +445,10 @@ class TestPreprocessedFile(TestWithTmpDi
++         # If one of the dependencies changes, the file should be updated. The
++         # mtime of the dependency is set after the destination file, to avoid
++         # both files having the same time.
++-        with open(incl, 'wb') as tmp:
+++        tmp = open(incl, 'wb').__enter__()
+++        if 1:
++             tmp.write('quux')
+++        tmp.close()
++         time = os.path.getmtime(dest) + 1
++         os.utime(incl, (time, time))
++         self.assertTrue(f.copy(dest))
++@@ -436,15 +474,19 @@ class TestPreprocessedFile(TestWithTmpDi
++         pp_source = self.tmppath('pp_in')
++         deps = self.tmppath('deps')
++ 
++-        with open(source, 'a'):
+++        open(source, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(source, 'a').__exit__(0, 0, 0)
++         os.symlink(source, dest)
++         self.assertTrue(os.path.islink(dest))
++ 
++-        with open(pp_source, 'wb') as tmp:
+++        tmp = open(pp_source, 'wb').__enter__()
+++        if 1:
++             tmp.write('#define FOO\nPREPROCESSED')
++ 
+++        tmp.close()
++         f = PreprocessedFile(pp_source, depfile_path=deps, marker='#',
++             defines={'FOO': True})
++         self.assertTrue(f.copy(dest))
++@@ -455,15 +497,19 @@ class TestPreprocessedFile(TestWithTmpDi
++ 
++ class TestExistingFile(TestWithTmpDir):
++     def test_required_missing_dest(self):
++-        with self.assertRaisesRegexp(ErrorMessage, 'Required existing file'):
+++        self.assertRaisesRegexp(ErrorMessage, 'Required existing file').__enter__()
+++        if 1:
++             f = ExistingFile(required=True)
++             f.copy(self.tmppath('dest'))
++ 
+++        self.assertRaisesRegexp(ErrorMessage, 'Required existing file').__exit__(0, 0, 0)
++     def test_required_existing_dest(self):
++         p = self.tmppath('dest')
++-        with open(p, 'a'):
+++        open(p, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(p, 'a').__exit__(0, 0, 0)
++         f = ExistingFile(required=True)
++         f.copy(p)
++ 
++@@ -473,9 +519,11 @@ class TestExistingFile(TestWithTmpDir):
++ 
++     def test_optional_existing_dest(self):
++         p = self.tmppath('dest')
++-        with open(p, 'a'):
+++        open(p, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(p, 'a').__exit__(0, 0, 0)
++         f = ExistingFile(required=False)
++         f.copy(p)
++ 
++@@ -541,13 +589,15 @@ class TestDeflatedFile(TestWithTmpDir):
++         dest = self.tmppath('dest')
++ 
++         contents = {}
++-        with JarWriter(src) as jar:
+++        jar = JarWriter(src).__enter__()
+++        if 1:
++             for content in samples:
++                 name = ''.join(random.choice(string.letters)
++                                for i in xrange(8))
++                 jar.add(name, content, compress=True)
++                 contents[name] = content
++ 
+++        jar.__exit__(0, 0, 0)
++         for j in JarReader(src):
++             f = DeflatedFile(j)
++             f.copy(dest)
++@@ -560,9 +610,11 @@ class TestDeflatedFile(TestWithTmpDir):
++         '''
++         src = self.tmppath('src.jar')
++         content = ''.join(samples)
++-        with JarWriter(src) as jar:
+++        jar = JarWriter(src).__enter__()
+++        if 1:
++             jar.add('content', content)
++ 
+++        jar.__exit__(0, 0, 0)
++         f = DeflatedFile(JarReader(src)['content'])
++         self.assertEqual(content[:42], f.open().read(42))
++         self.assertEqual(content, f.open().read())
++@@ -575,11 +627,13 @@ class TestDeflatedFile(TestWithTmpDir):
++         src = self.tmppath('src.jar')
++         dest = self.tmppath('dest')
++ 
++-        with JarWriter(src) as jar:
+++        jar = JarWriter(src).__enter__()
+++        if 1:
++             jar.add('test', 'test')
++             jar.add('test2', 'test')
++             jar.add('fooo', 'fooo')
++ 
+++        jar.__exit__(0, 0, 0)
++         jar = JarReader(src)
++         # Initial copy
++         f = DeflatedFile(jar['test'])
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/test/test_manifests.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/test/test_manifests.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/test/test_manifests.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/test/test_manifests.py	2014-10-24 11:41:35.504880036 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import os
++ 
++@@ -40,27 +40,41 @@ class TestInstallManifest(TestWithTmpDir
++         self.assertIn('e_dest', m)
++         self.assertIn('o_dest', m)
++ 
++-        with self.assertRaises(ValueError):
+++        self.assertRaises(ValueError).__enter__()
+++        if 1:
++             m.add_symlink('s_other', 's_dest')
++ 
++-        with self.assertRaises(ValueError):
+++        self.assertRaises(ValueError).__exit__(0, 0, 0)
+++        self.assertRaises(ValueError).__enter__()
+++        if 1:
++             m.add_copy('c_other', 'c_dest')
++ 
++-        with self.assertRaises(ValueError):
+++        self.assertRaises(ValueError).__exit__(0, 0, 0)
+++        self.assertRaises(ValueError).__enter__()
+++        if 1:
++             m.add_preprocess('p_other', 'p_dest', 'p_other.pp')
++ 
++-        with self.assertRaises(ValueError):
+++        self.assertRaises(ValueError).__exit__(0, 0, 0)
+++        self.assertRaises(ValueError).__enter__()
+++        if 1:
++             m.add_required_exists('e_dest')
++ 
++-        with self.assertRaises(ValueError):
+++        self.assertRaises(ValueError).__exit__(0, 0, 0)
+++        self.assertRaises(ValueError).__enter__()
+++        if 1:
++             m.add_optional_exists('o_dest')
++ 
++-        with self.assertRaises(ValueError):
+++        self.assertRaises(ValueError).__exit__(0, 0, 0)
+++        self.assertRaises(ValueError).__enter__()
+++        if 1:
++             m.add_pattern_symlink('ps_base', 'ps/*', 'ps_dest')
++ 
++-        with self.assertRaises(ValueError):
+++        self.assertRaises(ValueError).__exit__(0, 0, 0)
+++        self.assertRaises(ValueError).__enter__()
+++        if 1:
++             m.add_pattern_copy('pc_base', 'pc/**', 'pc_dest')
++ 
+++        self.assertRaises(ValueError).__exit__(0, 0, 0)
++     def _get_test_manifest(self):
++         m = InstallManifest()
++         m.add_symlink(self.tmppath('s_source'), 's_dest')
++@@ -80,9 +94,11 @@ class TestInstallManifest(TestWithTmpDir
++         m.write(path=p)
++         self.assertTrue(os.path.isfile(p))
++ 
++-        with open(p, 'rb') as fh:
+++        fh = open(p, 'rb')
+++        if 1:
++             c = fh.read()
++ 
+++        fh.__exit__(0, 0, 0)
++         self.assertEqual(c.count('\n'), 8)
++ 
++         lines = c.splitlines()
++@@ -95,9 +111,11 @@ class TestInstallManifest(TestWithTmpDir
++         p2 = self.tmppath('m2')
++         m2.write(path=p2)
++ 
++-        with open(p2, 'rb') as fh:
+++        fh = open(p2, 'rb').__enter__()
+++        if 1:
++             c2 = fh.read()
++ 
+++        fh.__exit__(0, 0, 0)
++         self.assertEqual(c, c2)
++ 
++     def test_populate_registry(self):
++@@ -114,12 +132,16 @@ class TestInstallManifest(TestWithTmpDir
++         os.mkdir('%s/base' % source)
++         os.mkdir('%s/base/foo' % source)
++ 
++-        with open('%s/base/foo/file1' % source, 'a'):
+++        open('%s/base/foo/file1' % source, 'a').__enter__()
+++        if 1:
++             pass
++ 
++-        with open('%s/base/foo/file2' % source, 'a'):
+++        open('%s/base/foo/file1' % source, 'a').__exit__(0, 0, 0)
+++        open('%s/base/foo/file2' % source, 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open('%s/base/foo/file2' % source, 'a').__exit__(0, 0, 0)
++         m = InstallManifest()
++         m.add_pattern_symlink('%s/base' % source, '**', 'dest')
++ 
++@@ -147,24 +169,36 @@ class TestInstallManifest(TestWithTmpDir
++         os.mkdir(dest)
++ 
++         to_delete = self.tmppath('dest/to_delete')
++-        with open(to_delete, 'a'):
+++        open(to_delete, 'a').__enter__()
+++        if 1:
++             pass
++ 
++-        with open(self.tmppath('s_source'), 'wt') as fh:
+++        open(to_delete, 'a').__exit__(0, 0, 0)
+++        fh = open(self.tmppath('s_source'), 'wt').__enter__()
+++        if 1:
++             fh.write('symlink!')
++ 
++-        with open(self.tmppath('c_source'), 'wt') as fh:
+++        fh.__exit__(0, 0, 0)
+++        fh = open(self.tmppath('c_source'), 'wt').__enter__()
+++        if 1:
++             fh.write('copy!')
++ 
++-        with open(self.tmppath('p_source'), 'wt') as fh:
+++        fh.__exit__(0, 0, 0)
+++        fh = open(self.tmppath('p_source'), 'wt').__enter__()
+++        if 1:
++             fh.write('#define FOO 1\npreprocess!')
++ 
++-        with open(self.tmppath('dest/e_dest'), 'a'):
+++        fh.__exit__(0, 0, 0)
+++        open(self.tmppath('dest/e_dest'), 'a').__enter__()
+++        if 1:
++             pass
++ 
++-        with open(self.tmppath('dest/o_dest'), 'a'):
+++        open(self.tmppath('dest/e_dest'), 'a').__exit__(0, 0, 0)
+++        open(self.tmppath('dest/o_dest'), 'a').__enter__()
+++        if 1:
++             pass
++ 
+++        open(self.tmppath('dest/o_dest'), 'a').__exit__(0, 0, 0)
++         m = self._get_test_manifest()
++         c = FileCopier()
++         m.populate_registry(c)
++@@ -177,15 +211,21 @@ class TestInstallManifest(TestWithTmpDir
++         self.assertTrue(os.path.exists(self.tmppath('dest/o_dest')))
++         self.assertFalse(os.path.exists(to_delete))
++ 
++-        with open(self.tmppath('dest/s_dest'), 'rt') as fh:
+++        fh = open(self.tmppath('dest/s_dest'), 'rt').__enter__()
+++        if 1:
++             self.assertEqual(fh.read(), 'symlink!')
++ 
++-        with open(self.tmppath('dest/c_dest'), 'rt') as fh:
+++        fh.__exit__(0, 0, 0)
+++        fh = open(self.tmppath('dest/c_dest'), 'rt').__enter__()
+++        if 1:
++             self.assertEqual(fh.read(), 'copy!')
++ 
++-        with open(self.tmppath('dest/p_dest'), 'rt') as fh:
+++        fh.__exit__(0, 0, 0)
+++        fh = open(self.tmppath('dest/p_dest'), 'rt').__enter__()
+++        if 1:
++             self.assertEqual(fh.read(), 'preprocess!')
++ 
+++        fh.__exit__(0, 0, 0)
++         self.assertEqual(result.updated_files, set(self.tmppath(p) for p in (
++             'dest/s_dest', 'dest/c_dest', 'dest/p_dest')))
++         self.assertEqual(result.existing_files,
++@@ -199,15 +239,19 @@ class TestInstallManifest(TestWithTmpDir
++         dest = self.tmppath('dest')
++         include = self.tmppath('p_incl')
++ 
++-        with open(include, 'wt') as fh:
+++        fh = open(include, 'wt').__enter__()
+++        if 1:
++             fh.write('#define INCL\n')
+++        fh.__exit__(0, 0, 0)
++         time = os.path.getmtime(include) - 3
++         os.utime(include, (time, time))
++ 
++-        with open(self.tmppath('p_source'), 'wt') as fh:
+++        fh = open(self.tmppath('p_source'), 'wt').__enter__()
+++        if 1:
++             fh.write('#ifdef FOO\n#if BAZ == QUX\nPASS1\n#endif\n#endif\n')
++             fh.write('#ifdef DEPTEST\nPASS2\n#endif\n')
++             fh.write('#include p_incl\n#ifdef INCLTEST\nPASS3\n#endif\n')
+++        fh.__exit__(0, 0, 0)
++         time = os.path.getmtime(self.tmppath('p_source')) - 3
++         os.utime(self.tmppath('p_source'), (time, time))
++ 
++@@ -224,9 +268,11 @@ class TestInstallManifest(TestWithTmpDir
++ 
++         self.assertTrue(os.path.exists(self.tmppath('dest/p_dest')))
++ 
++-        with open(self.tmppath('dest/p_dest'), 'rt') as fh:
+++        fh = open(self.tmppath('dest/p_dest'), 'rt').__enter__()
+++        if 1:
++             self.assertEqual(fh.read(), 'PASS1\n')
++ 
+++        fh.__exit__(0, 0, 0)
++         # Create a second manifest with the preprocessed file, then apply it.
++         # Since this manifest does not exist on the disk, there should not be a
++         # dependency on it, and the preprocessed file should not be modified.
++@@ -252,9 +298,11 @@ class TestInstallManifest(TestWithTmpDir
++         m2.populate_registry(c)
++         self.assertTrue(c.copy(dest))
++ 
++-        with open(self.tmppath('dest/p_dest'), 'rt') as fh:
+++        fh = open(self.tmppath('dest/p_dest'), 'rt').__enter__()
+++        if 1:
++             self.assertEqual(fh.read(), 'PASS2\n')
++ 
+++        fh.__exit__(0, 0, 0)
++         # Set the time on the manifest back, so it won't be picked up as
++         # modified in the next test
++         time = os.path.getmtime(manifest) - 1
++@@ -262,18 +310,22 @@ class TestInstallManifest(TestWithTmpDir
++ 
++         # Update the contents of a file included by the source file. This should
++         # cause the destination to be regenerated.
++-        with open(include, 'wt') as fh:
+++        fh = open(include, 'wt').__enter__()
+++        if 1:
++             fh.write('#define INCLTEST\n')
++ 
+++        fh.__exit__(0, 0, 0)
++         time = os.path.getmtime(include) - 1
++         os.utime(self.tmppath('dest/p_dest'), (time, time))
++         c = FileCopier()
++         m2.populate_registry(c)
++         self.assertTrue(c.copy(dest))
++ 
++-        with open(self.tmppath('dest/p_dest'), 'rt') as fh:
+++        fh = open(self.tmppath('dest/p_dest'), 'rt').__enter__()
+++        if 1:
++             self.assertEqual(fh.read(), 'PASS2\nPASS3\n')
++ 
+++        fh.__exit__(0, 0, 0)
++     def test_preprocessor_dependencies(self):
++         manifest = self.tmppath('m')
++         deps = self.tmppath('m.pp')
++@@ -283,13 +335,17 @@ class TestInstallManifest(TestWithTmpDir
++         include = self.tmppath('p_incl')
++         os.mkdir(dest)
++ 
++-        with open(source, 'wt') as fh:
+++        fh = open(source, 'wt').__enter__()
+++        if 1:
++             fh.write('#define SRC\nSOURCE\n')
+++        fh.__exit__(0, 0, 0)
++         time = os.path.getmtime(source) - 3
++         os.utime(source, (time, time))
++ 
++-        with open(include, 'wt') as fh:
+++        fh = open(include, 'wt').__enter__()
+++        if 1:
++             fh.write('INCLUDE\n')
+++        fh.__exit__(0, 0, 0)
++         time = os.path.getmtime(source) - 3
++         os.utime(include, (time, time))
++ 
++@@ -308,12 +364,16 @@ class TestInstallManifest(TestWithTmpDir
++         m.populate_registry(c)
++         self.assertTrue(c.copy(dest))
++ 
++-        with open(destfile, 'rt') as fh:
+++        fh = open(destfile, 'rt').__enter__()
+++        if 1:
++             self.assertEqual(fh.read(), 'SOURCE\n')
++ 
+++        fh.__exit__(0, 0, 0)
++         # Next, modify the source to #INCLUDE another file.
++-        with open(source, 'wt') as fh:
+++        fh = open(source, 'wt').__enter__()
+++        if 1:
++             fh.write('SOURCE\n#include p_incl\n')
+++        fh.__exit__(0, 0, 0)
++         time = os.path.getmtime(source) - 1
++         os.utime(destfile, (time, time))
++ 
++@@ -324,17 +384,21 @@ class TestInstallManifest(TestWithTmpDir
++         m.populate_registry(c)
++         c.copy(dest)
++ 
++-        with open(destfile, 'rt') as fh:
+++        fh = open(destfile, 'rt').__enter__()
+++        if 1:
++             self.assertEqual(fh.read(), 'SOURCE\nINCLUDE\n')
++ 
+++        fh.__exit__(0, 0, 0)
++         # Set the time on the source file back, so it won't be picked up as
++         # modified in the next test.
++         time = os.path.getmtime(source) - 1
++         os.utime(source, (time, time))
++ 
++         # Now, modify the include file (but not the original source).
++-        with open(include, 'wt') as fh:
+++        fh = open(include, 'wt').__enter__()
+++        if 1:
++             fh.write('INCLUDE MODIFIED\n')
+++        fh.__exit__(0, 0, 0)
++         time = os.path.getmtime(include) - 1
++         os.utime(destfile, (time, time))
++ 
++@@ -345,8 +409,10 @@ class TestInstallManifest(TestWithTmpDir
++         m.populate_registry(c)
++         c.copy(dest)
++ 
++-        with open(destfile, 'rt') as fh:
+++        fh = open(destfile, 'rt').__enter__()
+++        if 1:
++             self.assertEqual(fh.read(), 'SOURCE\nINCLUDE MODIFIED\n')
++ 
+++        fh.close()
++ if __name__ == '__main__':
++     mozunit.main()
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/test/test_mozjar.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/test/test_mozjar.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/test/test_mozjar.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/test/test_mozjar.py	2014-10-24 11:41:35.504880036 -0600
++@@ -53,7 +53,7 @@ class TestJarStruct(unittest.TestCase):
++         foo['string'] = 'abcde'
++         foo['string2'] = 'Arbitrarily long string'
++ 
++-        serialized = b'\x04\x03\x02\x01\x45\x44\x43\x42\xcd\xab\x01\xef' + \
+++        serialized = '\x04\x03\x02\x01\x45\x44\x43\x42\xcd\xab\x01\xef' + \
++                      b'\x05\x00\x17\x00abcdeArbitrarily long string'
++         self.assertEqual(foo.size, len(serialized))
++         foo_serialized = foo.serialize()
++@@ -73,12 +73,12 @@ class TestJarStruct(unittest.TestCase):
++         self.assertEqual(foo['string2'], '67')
++ 
++     def test_read_jar_struct(self):
++-        data = b'\x00\x04\x03\x02\x01\x42\x43\x44\x45\xab\xcd\xef' + \
+++        data = '\x00\x04\x03\x02\x01\x42\x43\x44\x45\xab\xcd\xef' + \
++                b'\x01\x06\x00\x02\x0001234567890'
++         self.do_test_read_jar_struct(data)
++ 
++     def test_read_jar_struct_memoryview(self):
++-        data = b'\x00\x04\x03\x02\x01\x42\x43\x44\x45\xab\xcd\xef' + \
+++        data = '\x00\x04\x03\x02\x01\x42\x43\x44\x45\xab\xcd\xef' + \
++                b'\x01\x06\x00\x02\x0001234567890'
++         self.do_test_read_jar_struct(memoryview(data))
++ 
++@@ -130,12 +130,14 @@ class TestJar(unittest.TestCase):
++ 
++     def test_jar(self):
++         s = MockDest()
++-        with JarWriter(fileobj=s, optimize=self.optimize) as jar:
+++        jar = JarWriter(fileobj=s, optimize=self.optimize).__enter__()
+++        if 1:
++             jar.add('foo', 'foo')
++             self.assertRaises(JarWriterError, jar.add, 'foo', 'bar')
++             jar.add('bar', 'aaaaaaaaaaaaanopqrstuvwxyz')
++             jar.add('baz/qux', 'aaaaaaaaaaaaanopqrstuvwxyz', False)
++ 
+++        jar.__exit__(0, 0, 0)
++         files = [j for j in JarReader(fileobj=s)]
++ 
++         self.assertEqual(files[0].filename, 'foo')
++@@ -204,16 +206,20 @@ class TestJar(unittest.TestCase):
++ 
++     def test_rejar(self):
++         s = MockDest()
++-        with JarWriter(fileobj=s, optimize=self.optimize) as jar:
+++        jar = JarWriter(fileobj=s, optimize=self.optimize).__enter__()
+++        if 1:
++             jar.add('foo', 'foo')
++             jar.add('bar', 'aaaaaaaaaaaaanopqrstuvwxyz')
++             jar.add('baz/qux', 'aaaaaaaaaaaaanopqrstuvwxyz', False)
++ 
+++        jar.__exit__(0, 0, 0)
++         new = MockDest()
++-        with JarWriter(fileobj=new, optimize=self.optimize) as jar:
+++        jar = JarWriter(fileobj=new, optimize=self.optimize).__enter__()
+++        if 1:
++             for j in JarReader(fileobj=s):
++                 jar.add(j.filename, j)
++ 
+++        jar.__exit__(0, 0, 0)
++         jar = JarReader(fileobj=new)
++         files = [j for j in jar]
++ 
++@@ -237,20 +243,24 @@ class TestOptimizeJar(TestJar):
++ class TestPreload(unittest.TestCase):
++     def test_preload(self):
++         s = MockDest()
++-        with JarWriter(fileobj=s) as jar:
+++        jar = JarWriter(fileobj=s).__enter__()
+++        if 1:
++             jar.add('foo', 'foo')
++             jar.add('bar', 'abcdefghijklmnopqrstuvwxyz')
++             jar.add('baz/qux', 'aaaaaaaaaaaaanopqrstuvwxyz')
++ 
+++        jar.__exit__(0, 0, 0)
++         jar = JarReader(fileobj=s)
++         self.assertEqual(jar.last_preloaded, None)
++ 
++-        with JarWriter(fileobj=s) as jar:
+++        jar = JarWriter(fileobj=s).__enter__()
+++        if 1:
++             jar.add('foo', 'foo')
++             jar.add('bar', 'abcdefghijklmnopqrstuvwxyz')
++             jar.add('baz/qux', 'aaaaaaaaaaaaanopqrstuvwxyz')
++             jar.preload(['baz/qux', 'bar'])
++ 
+++        jar.__exit__(0, 0, 0)
++         jar = JarReader(fileobj=s)
++         self.assertEqual(jar.last_preloaded, 'bar')
++         files = [j for j in jar]
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/test/test_packager.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/test/test_packager.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/test/test_packager.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/test/test_packager.py	2014-10-24 11:41:35.505880032 -0600
++@@ -69,12 +69,15 @@ class TestPreprocessManifest(unittest.Te
++         self.sink = MockSink()
++ 
++     def test_preprocess_manifest(self):
++-        with MockedOpen({'manifest': MANIFEST}):
+++        MockedOpen({'manifest': MANIFEST}).__enter__()
+++        if 1:
++             preprocess_manifest(self.sink, 'manifest')
+++        MockedOpen({'manifest': MANIFEST}).__exit__(0, 0, 0)
++         self.assertEqual(self.sink.log, self.EXPECTED_LOG)
++ 
++     def test_preprocess_manifest_missing_define(self):
++-        with MockedOpen({'manifest': MANIFEST}):
+++        MockedOpen({'manifest': MANIFEST}).__enter__()
+++        if 1:
++             self.assertRaises(
++                 Preprocessor.Error,
++                 preprocess_manifest,
++@@ -83,10 +86,13 @@ class TestPreprocessManifest(unittest.Te
++                 {'baz': 1}
++             )
++ 
+++        MockedOpen({'manifest': MANIFEST}).__exit__(0, 0, 0)
++     def test_preprocess_manifest_defines(self):
++-        with MockedOpen({'manifest': MANIFEST}):
+++        MockedOpen({'manifest': MANIFEST}).__enter__()
+++        if 1:
++             preprocess_manifest(self.sink, 'manifest',
++                                 {'baz': 1, 'SUFFIX': '.exe'})
+++        MockedOpen({'manifest': MANIFEST}).__exit__(0, 0, 0)
++         self.assertEqual(self.sink.log, self.EXPECTED_LOG +
++                          [((self.MANIFEST_PATH, 12), 'add', 'baz', 'baz.exe')])
++ 
++@@ -139,42 +145,58 @@ class TestSimplePackager(unittest.TestCa
++         file = GeneratedFileWithPath(os.path.join(curdir, 'foo',
++                                                   'bar.manifest'),
++                                      'resource bar bar/\ncontent bar bar/')
++-        with errors.context('manifest', 1):
+++        errors.context('manifest', 1).__enter__()
+++        if 1:
++             packager.add('foo/bar.manifest', file)
++ 
+++        errors.context('manifest', 1).__exit__(0, 0, 0)
++         file = GeneratedFileWithPath(os.path.join(curdir, 'foo',
++                                                   'baz.manifest'),
++                                      'resource baz baz/')
++-        with errors.context('manifest', 2):
+++        errors.context('manifest', 2).__enter__()
+++        if 1:
++             packager.add('bar/baz.manifest', file)
++ 
++-        with errors.context('manifest', 3):
+++        errors.context('manifest', 2).__exit__(0, 0, 0)
+++        errors.context('manifest', 3).__enter__()
+++        if 1:
++             packager.add('qux/qux.manifest',
++                          GeneratedFile('resource qux qux/'))
+++        errors.context('manifest', 3).__exit__(0, 0, 0)
++         bar_xpt = GeneratedFile('bar.xpt')
++         qux_xpt = GeneratedFile('qux.xpt')
++         foo_html = GeneratedFile('foo_html')
++         bar_html = GeneratedFile('bar_html')
++-        with errors.context('manifest', 4):
+++        errors.context('manifest', 4).__enter__()
+++        if 1:
++             packager.add('foo/bar.xpt', bar_xpt)
++-        with errors.context('manifest', 5):
+++        errors.context('manifest', 4).__exit__(0, 0, 0)
+++        errors.context('manifest', 5).__enter__()
+++        if 1:
++             packager.add('foo/bar/foo.html', foo_html)
++             packager.add('foo/bar/bar.html', bar_html)
++ 
+++        errors.context('manifest', 5).__exit__(0, 0, 0)
++         file = GeneratedFileWithPath(os.path.join(curdir, 'foo.manifest'),
++                                      ''.join([
++                                          'manifest foo/bar.manifest\n',
++                                          'manifest bar/baz.manifest\n',
++                                      ]))
++-        with errors.context('manifest', 6):
+++        errors.context('manifest', 6).__enter__()
+++        if 1:
++             packager.add('foo.manifest', file)
++-        with errors.context('manifest', 7):
+++        errors.context('manifest', 6).__exit__(0, 0, 0)
+++        errors.context('manifest', 7).__enter__()
+++        if 1:
++             packager.add('foo/qux.xpt', qux_xpt)
++ 
+++        errors.context('manifest', 7).__exit__(0, 0, 0)
++         self.assertEqual(formatter.log, [])
++ 
++-        with errors.context('dummy', 1):
+++        errors.context('dummy', 1).__enter__()
+++        if 1:
++             packager.close()
+++        errors.context('dummy', 1).__exit__(0, 0, 0)
++         self.maxDiff = None
++         # The formatter is expected to reorder the manifest entries so that
++         # chrome entries appear before the others.
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/test/test_unify.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/test/test_unify.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/test/test_unify.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/test/test_unify.py	2014-10-24 11:41:35.505880032 -0600
++@@ -105,22 +105,28 @@ class TestUnifiedBuildFinder(TestUnified
++                          ]))])
++ 
++         xpi = MockDest()
++-        with JarWriter(fileobj=xpi, compress=True) as jar:
+++        jar = JarWriter(fileobj=xpi, compress=True).__enter__()
+++        if 1:
++             jar.add('foo', 'foo')
++             jar.add('bar', 'bar')
+++        jar.__exit__(0, 0, 0)
++         foo_xpi = xpi.read()
++         self.create_both('foo.xpi', foo_xpi)
++ 
++-        with JarWriter(fileobj=xpi, compress=True) as jar:
+++        jar = JarWriter(fileobj=xpi, compress=True).__enter__()
+++        if 1:
++             jar.add('foo', 'bar')
+++        jar.__exit__(0, 0, 0)
++         self.create_one('a', 'bar.xpi', foo_xpi)
++         self.create_one('b', 'bar.xpi', xpi.read())
++ 
++         errors.out = StringIO()
++-        with self.assertRaises(AccumulatedErrors), errors.accumulate():
+++        self.assertRaises(AccumulatedErrors), errors.accumulate().__enter__()
+++        if 1:
++             self.assertEqual([(f, c.open().read()) for f, c in
++                               finder.find('*.xpi')],
++                              [('foo.xpi', foo_xpi)])
+++        self.assertRaises(AccumulatedErrors), errors.accumulate().__exit__(0, 0, 0)
++         errors.out = sys.stderr
++ 
++ 
++diff -up comm-esr31/mozilla/python/mozbuild/mozpack/unify.py.python3 comm-esr31/mozilla/python/mozbuild/mozpack/unify.py
++--- comm-esr31/mozilla/python/mozbuild/mozpack/unify.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozbuild/mozpack/unify.py	2014-10-24 11:41:35.505880032 -0600
++@@ -19,7 +19,7 @@ import mozpack.path
++ import struct
++ import os
++ import subprocess
++-from collections import OrderedDict
+++from ordereddict import OrderedDict
++ 
++ 
++ def may_unify_binary(file):
++@@ -80,8 +80,7 @@ class UnifiedFinder(BaseFinder):
++         Initialize a UnifiedFinder. finder1 and finder2 are BaseFinder
++         instances from which files are picked. UnifiedFinder.find() will act as
++         FileFinder.find() but will error out when matches can only be found in
++-        one of the two trees and not the other. It will also error out if
++-        matches can be found on both ends but their contents are not identical.
+++        one of the two trees and not the other. It will also error out if matches can be found on both ends but their contents are not identical.
++ 
++         The sorted argument gives a list of mozpack.path.match patterns. File
++         paths matching one of these patterns will have their contents compared
++diff -up comm-esr31/mozilla/python/mozversioncontrol/mozversioncontrol/repoupdate.py.python3 comm-esr31/mozilla/python/mozversioncontrol/mozversioncontrol/repoupdate.py
++--- comm-esr31/mozilla/python/mozversioncontrol/mozversioncontrol/repoupdate.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/mozversioncontrol/mozversioncontrol/repoupdate.py	2014-10-24 11:41:35.505880032 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this,
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import os
++ import subprocess
++diff -up comm-esr31/mozilla/python/psutil/psutil/_common.py.python3 comm-esr31/mozilla/python/psutil/psutil/_common.py
++--- comm-esr31/mozilla/python/psutil/psutil/_common.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/psutil/psutil/_common.py	2014-10-24 11:41:35.505880032 -0600
++@@ -6,7 +6,7 @@
++ 
++ """Common objects shared by all _ps* modules."""
++ 
++-from __future__ import division
+++
++ import sys
++ import os
++ import stat
++diff -up comm-esr31/mozilla/python/psutil/psutil/__init__.py.python3 comm-esr31/mozilla/python/psutil/psutil/__init__.py
++--- comm-esr31/mozilla/python/psutil/psutil/__init__.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/psutil/psutil/__init__.py	2014-10-24 11:41:35.506880028 -0600
++@@ -10,7 +10,7 @@ processes and gather system information
++ Python.
++ """
++ 
++-from __future__ import division
+++
++ 
++ __version__ = "1.0.1"
++ version_info = tuple([int(num) for num in __version__.split('.')])
++@@ -229,8 +229,7 @@ class Process(object):
++                 ret = ad_value
++             except NotImplementedError:
++                 # in case of not implemented functionality (may happen
++-                # on old or exotic systems) we want to crash only if
++-                # the user explicitly asked for that particular attr
+++                # on old or exotic systems) we want to crash only if # the user explicitly asked for that particular attr
++                 if attrs:
++                     raise
++                 continue
++@@ -368,8 +367,7 @@ class Process(object):
++ 
++         @property
++         def terminal(self):
++-            """The terminal associated with this process, if any,
++-            else None.
+++            """The terminal associated with this process,any, = (None., )[]
++             """
++             return self._platform_impl.get_process_terminal()
++ 
++@@ -795,8 +793,7 @@ class Process(object):
++             self._platform_impl.kill_process()
++ 
++     def wait(self, timeout=None):
++-        """Wait for process to terminate and, if process is a children
++-        of the current one also return its exit code, else None.
+++        """Wait for process to terminate and,process is a children of the current one also return its exit code, = (None., )[]
++         """
++         if timeout is not None and not timeout >= 0:
++             raise ValueError("timeout must be a positive integer")
++diff -up comm-esr31/mozilla/python/psutil/psutil/_pslinux.py.python3 comm-esr31/mozilla/python/psutil/psutil/_pslinux.py
++--- comm-esr31/mozilla/python/psutil/psutil/_pslinux.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/psutil/psutil/_pslinux.py	2014-10-24 11:41:35.506880028 -0600
++@@ -6,7 +6,7 @@
++ 
++ """Linux platform implementation."""
++ 
++-from __future__ import division
+++
++ 
++ import os
++ import errno
++@@ -437,8 +437,7 @@ def wrap_exceptions(fun):
++             return fun(self, *args, **kwargs)
++         except EnvironmentError:
++             # ENOENT (no such file or directory) gets raised on open().
++-            # ESRCH (no such process) can get raised on read() if
++-            # process is gone in meantime.
+++            # ESRCH (no such process) can get raised on read() if # process is gone in meantime.
++             err = sys.exc_info()[1]
++             if err.errno in (errno.ENOENT, errno.ESRCH):
++                 raise NoSuchProcess(self.pid, self._process_name)
++diff -up comm-esr31/mozilla/python/psutil/psutil/_pssunos.py.python3 comm-esr31/mozilla/python/psutil/psutil/_pssunos.py
++--- comm-esr31/mozilla/python/psutil/psutil/_pssunos.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/psutil/psutil/_pssunos.py	2014-10-24 11:41:35.506880028 -0600
++@@ -148,8 +148,7 @@ def wrap_exceptions(callable):
++             return callable(self, *args, **kwargs)
++         except EnvironmentError:
++             # ENOENT (no such file or directory) gets raised on open().
++-            # ESRCH (no such process) can get raised on read() if
++-            # process is gone in meantime.
+++            # ESRCH (no such process) can get raised on read() if # process is gone in meantime.
++             err = sys.exc_info()[1]
++             if err.errno in (errno.ENOENT, errno.ESRCH):
++                 raise NoSuchProcess(self.pid, self._process_name)
++@@ -287,8 +286,7 @@ class Process(object):
++ 
++     @wrap_exceptions
++     def get_process_cwd(self):
++-        # /proc/PID/path/cwd may not be resolved by readlink() even if
++-        # it exists (ls shows it). If that's the case and the process
+++        # /proc/PID/path/cwd may not be resolved by readlink() even if # it exists (ls shows it). If that's the case and the process
++         # is still alive return None (we can return None also on BSD).
++         # Reference: http://goo.gl/55XgO
++         try:
++diff -up comm-esr31/mozilla/python/psutil/test/_linux.py.python3 comm-esr31/mozilla/python/psutil/test/_linux.py
++--- comm-esr31/mozilla/python/psutil/test/_linux.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/psutil/test/_linux.py	2014-10-24 11:41:35.506880028 -0600
++@@ -6,7 +6,7 @@
++ 
++ """Linux specific tests.  These are implicitly run by test_psutil.py."""
++ 
++-from __future__ import division
+++
++ import unittest
++ import subprocess
++ import sys
++diff -up comm-esr31/mozilla/python/psutil/test/test_memory_leaks.py.python3 comm-esr31/mozilla/python/psutil/test/test_memory_leaks.py
++--- comm-esr31/mozilla/python/psutil/test/test_memory_leaks.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/psutil/test/test_memory_leaks.py	2014-10-24 11:41:35.507880023 -0600
++@@ -60,8 +60,7 @@ class Base(unittest.TestCase):
++             # function so many times the memory usage is stabilized
++             # and if there are no leaks it should not increase any
++             # more.
++-            # Let's keep calling fun for 3 more seconds and fail if
++-            # we notice any difference.
+++            # Let's keep calling fun for 3 more seconds and fail if # we notice any difference.
++             stop_at = time.time() + 3
++             while 1:
++                 self.call(function, *args, **kwargs)
++diff -up comm-esr31/mozilla/python/psutil/test/test_psutil.py.python3 comm-esr31/mozilla/python/psutil/test/test_psutil.py
++--- comm-esr31/mozilla/python/psutil/test/test_psutil.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/python/psutil/test/test_psutil.py	2014-10-24 11:41:35.507880023 -0600
++@@ -14,7 +14,7 @@ If you're on Python < 2.7 it is recommen
++ from: https://pypi.python.org/pypi/unittest2
++ """
++ 
++-from __future__ import division
+++
++ import os
++ import sys
++ import subprocess
++diff -up comm-esr31/mozilla/security/apps/gen_cert_header.py.python3 comm-esr31/mozilla/security/apps/gen_cert_header.py
++--- comm-esr31/mozilla/security/apps/gen_cert_header.py.python3	2014-07-17 18:05:48.000000000 -0600
+++++ comm-esr31/mozilla/security/apps/gen_cert_header.py	2014-10-24 11:41:35.507880023 -0600
++@@ -6,7 +6,8 @@ import sys
++ import binascii
++ 
++ def file_byte_generator(filename, block_size = 512):
++-  with open(filename, "rb") as f:
+++  f = open(filename, "rb")
+++  if 1:
++     while True:
++       block = f.read(block_size)
++       if block:
++@@ -15,6 +16,7 @@ def file_byte_generator(filename, block_
++       else:
++         break
++ 
+++  f.close()
++ def create_header(array_name, in_filename):
++   hexified = ["0x" + binascii.hexlify(byte) for byte in file_byte_generator(in_filename)]
++   print "const uint8_t " + array_name + "[] = {"
++diff -up comm-esr31/mozilla/security/manager/ssl/tests/unit/test_signed_apps/gentestfiles/sign_b2g_app.py.python3 comm-esr31/mozilla/security/manager/ssl/tests/unit/test_signed_apps/gentestfiles/sign_b2g_app.py
++--- comm-esr31/mozilla/security/manager/ssl/tests/unit/test_signed_apps/gentestfiles/sign_b2g_app.py.python3	2014-07-17 18:05:49.000000000 -0600
+++++ comm-esr31/mozilla/security/manager/ssl/tests/unit/test_signed_apps/gentestfiles/sign_b2g_app.py	2014-10-24 11:41:35.508880019 -0600
++@@ -50,8 +50,10 @@ def sign_zip(in_zipfile_name, out_zipfil
++ 
++   total_uncompressed_len = 0
++   entry_count = 0
++-  with zipfile.ZipFile(out_zipfile_name, 'w') as out_zip:
++-    with zipfile.ZipFile(in_zipfile_name, 'r') as in_zip:
+++  out_zip = zipfile.ZipFile(out_zipfile_name, 'w').__enter__()
+++  if 1:
+++    in_zip = zipfile.ZipFile(in_zipfile_name, 'r').__enter__()
+++    if 1:
++       for entry_info in in_zip.infolist():
++         name = entry_info.filename
++ 
++@@ -98,6 +100,7 @@ def sign_zip(in_zipfile_name, out_zipfil
++           # Add the entry to the manifest we're building
++           mf_entries.append('Name: %s\nSHA1-Digest: %s\n'
++                                 % (name, b64encode(sha1(contents).digest())))
+++    in_zip.__exit__(0, 0, 0)
++     if (ids_json):
++       mf_entries.append('Name: %s\nSHA1-Digest: %s\n'
++                         % ("META-INF/ids.json", b64encode(sha1(ids_json).digest())))
++@@ -121,6 +124,7 @@ def sign_zip(in_zipfile_name, out_zipfil
++     if (ids_json):
++         out_zip.writestr("META-INF/ids.json", ids_json, zipfile.ZIP_DEFLATED)
++ 
+++  out_zip.__exit__(0, 0, 0)
++ def main():
++   parser = argparse.ArgumentParser(description='Sign a B2G app.')
++   parser.add_argument('-d', action='store',
++diff -up comm-esr31/mozilla/testing/gtest/rungtests.py.python3 comm-esr31/mozilla/testing/gtest/rungtests.py
++--- comm-esr31/mozilla/testing/gtest/rungtests.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/gtest/rungtests.py	2014-10-24 11:41:35.508880019 -0600
++@@ -4,7 +4,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import with_statement
+++
++ import sys, os
++ from optparse import OptionParser
++ import mozprocess, mozinfo, mozlog, mozcrash
++@@ -117,7 +117,7 @@ def main():
++     except Exception, e:
++         log.error(str(e))
++         result = False
++-    sys.exit(0 if result else 1)
+++    sys.exit(1, 0)[result]
++ 
++ if __name__ == '__main__':
++     main()
++diff -up comm-esr31/mozilla/testing/mach_commands.py.python3 comm-esr31/mozilla/testing/mach_commands.py
++--- comm-esr31/mozilla/testing/mach_commands.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mach_commands.py	2014-10-24 11:41:35.508880019 -0600
++@@ -2,7 +2,11 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ import os
++ 
++@@ -213,7 +217,10 @@ class MachCommands(MachCommandBase):
++                 'Caught exception running cpp unit tests: {exception}')
++             result = False
++ 
++-        return 0 if result else 1
+++        if result:
+++          return 0
+++        else:
+++          return 1
++ 
++ @CommandProvider
++ class JittestCommand(MachCommandBase):
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/b2gbuild.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/b2gbuild.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/b2gbuild.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/b2gbuild.py	2014-10-24 11:41:35.508880019 -0600
++@@ -82,7 +82,11 @@ class B2GBuild(object):
++         self.homedir = homedir
++         self.adb_path = self.check_adb(self.homedir)
++         self.update_tools = os.path.join(self.homedir, 'tools', 'update-tools')
++-        self.fastboot_path = None if emulator else self.check_fastboot(self.homedir)
+++        self.fastboot_path = None
+++        if emulator:
+++          self.fastboot_path = None
+++        else:
+++          self.fastboot_path = self.check_fastboot(self.homedir)
++ 
++     def import_update_tools(self):
++         """Import the update_tools package from B2G"""
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/b2g_update_test.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/b2g_update_test.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/b2g_update_test.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/b2g_update_test.py	2014-10-24 11:41:35.508880019 -0600
++@@ -163,9 +163,11 @@ class B2GUpdateTestCase(MarionetteTestCa
++ 
++         update_test_js = os.path.join(os.path.dirname(__file__), 'atoms',
++                                       'b2g_update_test.js')
++-        with open(update_test_js, 'r') as f:
+++        f = open(update_test_js, 'r')
+++        if 1:
++             self.update_test_js = f.read()
++ 
+++        f.__exit__(0, 0, 0)
++         self.b2g_pid = self.runner.find_b2g_pid()
++         if not self.b2g_pid:
++             raise Exception('B2G PID could not be found for update test')
++@@ -228,9 +230,11 @@ class B2GUpdateTestCase(MarionetteTestCa
++ 
++     def execute_update_js(self, path, stage=None, will_restart=True):
++         data = self.update_test_js[:]
++-        with open(path, "r") as f:
+++        f = open(path, "r").__enter__()
+++        if 1:
++             data += f.read()
++ 
+++        f.close()
++         status = 'EXEC'
++         if stage:
++             status += '-' + stage.upper()
++@@ -254,12 +258,16 @@ class B2GUpdateTestCase(MarionetteTestCa
++         failed = results['failed']
++ 
++         fails = StringIO()
++-        stage_msg = ' %s' % stage if stage else ''
+++        stage_msg = None
+++        if stage:
+++          stage_msg = ' %s' % stage
+++        else:
+++          stage_msg = ''
++         fails.write('%d%s tests failed:\n' % (failed, stage_msg))
++ 
++         for failure in results['failures']:
++             diag = failure.get('diag')
++-            diag_msg = "" if not diag else "| %s " % diag
+++            diag_msg = ("| %s " % diag, "")[not diag]
++             name = failure.get('name') or 'got false, expected true'
++             fails.write('TEST-UNEXPECTED-FAIL | %s %s| %s\n' %
++                         (os.path.basename(path), diag_msg, name))
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/emulator.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/emulator.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/emulator.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/emulator.py	2014-10-24 11:41:35.509880015 -0600
++@@ -171,8 +171,7 @@ class Emulator(object):
++ 
++     def check_for_crash(self):
++         """
++-        Checks if the emulator has crashed or not.  Always returns False if
++-        we've connected to an already-running emulator, since we can't track
+++        Checks if the emulator has crashed or not.  Always returns False if we've connected to an already-running emulator, since we can't track
++         the emulator's pid in that case.  Otherwise, returns True iff
++         self.proc is not None (meaning the emulator hasn't been explicitly
++         closed), and self.proc.poll() is also not None (meaning the emulator
++@@ -317,8 +316,10 @@ waitFor(
++     def add_prefs_to_profile(self, prefs=()):
++         local_user_js = tempfile.mktemp(prefix='localuserjs')
++         self.dm.getFile(self.remote_user_js, local_user_js)
++-        with open(local_user_js, 'a') as f:
+++        f = open(local_user_js, 'a')
+++        if 1:
++             f.write('%s\n' % '\n'.join(prefs))
+++        f.close()
++         self.dm.pushFile(local_user_js, self.remote_user_js)
++ 
++     def start(self):
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/marionette.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/marionette.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/marionette.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/marionette.py	2014-10-24 11:41:35.509880015 -0600
++@@ -1291,8 +1291,10 @@ class Marionette(object):
++           assert "i'm a test function!" == self.marionette.execute_script("return testFunc();")
++         '''
++         js = ''
++-        with open(js_file, 'r') as f:
+++        f = open(js_file, 'r')
+++        if 1:
++             js = f.read()
+++        f.close()
++         return self._send_message('importScript', 'ok', script=js)
++ 
++     def clear_imported_scripts(self):
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/marionette_test.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/marionette_test.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/marionette_test.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/marionette_test.py	2014-10-24 11:41:35.509880015 -0600
++@@ -143,11 +143,11 @@ class CommonTestCase(unittest.TestCase):
++                         raise _ExpectedFailure(sys.exc_info())
++                 else:
++                     self.setUp()
++-            except SkipTest as e:
+++            except SkipTest, e:
++                 self._addSkip(result, str(e))
++             except KeyboardInterrupt:
++                 raise
++-            except _ExpectedFailure as e:
+++            except _ExpectedFailure, e:
++                 expected_failure(result, e.exc_info)
++             except:
++                 result.addError(self, sys.exc_info())
++@@ -165,7 +165,7 @@ class CommonTestCase(unittest.TestCase):
++                     result.addFailure(self, sys.exc_info())
++                 except KeyboardInterrupt:
++                     raise
++-                except _ExpectedFailure as e:
+++                except _ExpectedFailure, e:
++                     expected_failure(result, e.exc_info)
++                 except _UnexpectedSuccess:
++                     addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
++@@ -175,7 +175,7 @@ class CommonTestCase(unittest.TestCase):
++                         warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
++                                       RuntimeWarning)
++                         result.addFailure(self, sys.exc_info())
++-                except SkipTest as e:
+++                except SkipTest, e:
++                     self._addSkip(result, str(e))
++                 except:
++                     result.addError(self, sys.exc_info())
++@@ -191,7 +191,7 @@ class CommonTestCase(unittest.TestCase):
++                         self.tearDown()
++                 except KeyboardInterrupt:
++                     raise
++-                except _ExpectedFailure as e:
+++                except _ExpectedFailure, e:
++                     expected_failure(result, e.exc_info)
++                 except:
++                     result.addError(self, sys.exc_info())
++@@ -498,8 +498,16 @@ setReq.onerror = function() {
++             else:
++                 fails = []
++                 for failure in results['failures']:
++-                    diag = "" if failure.get('diag') is None else "| %s " % failure['diag']
++-                    name = "got false, expected true" if failure.get('name') is None else failure['name']
+++                    diag = None
+++                    if failure.get('diag') is None:
+++                      diag = "" # ("", "| %s " % failure['diag'] name = "got false, expected true")[failure.get('diag') is None]
+++                    else:
+++                      diag = failure['diag']
+++                    name = ""
+++                    if failure.get('name') is None:
+++                      name = "got false, expected true"
+++                    else:
+++                      name = failure['name']
++                     fails.append('TEST-UNEXPECTED-FAIL | %s %s| %s' %
++                                  (os.path.basename(self.jsFile), diag, name))
++                 self.assertEqual(0, results['failed'],
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/runner/base.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/runner/base.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/runner/base.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/runner/base.py	2014-10-24 11:41:35.510880011 -0600
++@@ -123,7 +123,7 @@ class MarionetteTestResult(unittest._Tex
++         for modifier in self.result_modifiers:
++             result_expected, result_actual, output, context = modifier(t, result_expected, result_actual, output, context)
++         t.finish(result_actual,
++-                 time_end=time.time() if test.start_time else 0,
+++                 time_end=(0, time.time())[test.start_time],
++                  reason=relevant_line(output),
++                  output=output)
++         self.append(t)
++@@ -599,9 +599,11 @@ class BaseMarionetteTestRunner(object):
++ 
++             import json
++             try:
++-                with open(testvars) as f:
+++                f = open(testvars)
+++                if 1:
++                     self.testvars = json.loads(f.read())
++-            except ValueError as e:
+++                f.close()
+++            except ValueError, e:
++                 json_path = os.path.abspath(testvars)
++                 raise Exception("JSON file (%s) is not properly "
++                                 "formatted: %s" % (json_path, e.message))
++@@ -823,9 +825,11 @@ class BaseMarionetteTestRunner(object):
++             xml_dir = os.path.dirname(os.path.abspath(self.xml_output))
++             if not os.path.exists(xml_dir):
++                 os.makedirs(xml_dir)
++-            with open(self.xml_output, 'w') as f:
+++            f = open(self.xml_output, 'w')
+++            if 1:
++                 f.write(self.generate_xml(self.results))
++ 
+++            f.close()
++         if self.marionette.instance:
++             self.marionette.instance.close()
++             self.marionette.instance = None
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/runner/mixins/endurance.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/runner/mixins/endurance.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/runner/mixins/endurance.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/runner/mixins/endurance.py	2014-10-24 11:41:35.510880011 -0600
++@@ -112,13 +112,17 @@ class EnduranceTestCaseMixin(object):
++             if not os.path.exists(self.checkpoint_path):
++                 os.makedirs(self.checkpoint_path, 0755)
++             self.log_name = "%s/checkpoint_%s_%s.log" % (self.checkpoint_path, self.test_method.__name__, self.cur_time)
++-            with open(self.log_name, 'a') as log_file:
+++            log_file = open(self.log_name, 'a')
+++            if 1:
++                 log_file.write('%s Endurance Test: %s\n' % (self.cur_time, self.test_method.__name__))
++                 log_file.write('%s Checkpoint after iteration %d of %d:\n' % (self.cur_time, self.iteration, self.iterations))
+++            log_file.__exit__(0, 0, 0)
++         else:
++-            with open(self.log_name, 'a') as log_file:
+++            log_file = open(self.log_name, 'a').__enter__()
+++            if 1:
++                 log_file.write('%s Checkpoint after iteration %d of %d:\n' % (self.cur_time, self.iteration, self.iterations))
++ 
+++            log_file.close()
++         for function in self.checkpoint_functions:
++             function()
++ 
++@@ -146,9 +150,11 @@ class MemoryEnduranceTestCaseMixin(objec
++         # Dump out some memory status info
++         self.marionette.log("checkpoint")
++         output_str = self.device_manager.shellCheckOutput(["b2g-ps"])
++-        with open(self.log_name, 'a') as log_file:
+++        log_file = open(self.log_name, 'a')
+++        if 1:
++             log_file.write('%s\n' % output_str)
++ 
+++        log_file.close()
++     def memory_b2g_process_checkpoint(self):
++         # Process checkpoint data into .json
++         self.marionette.log("processing checkpoint data from %s" % self.log_name)
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/runner/mixins/reporting.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/runner/mixins/reporting.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/runner/mixins/reporting.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/runner/mixins/reporting.py	2014-10-24 11:41:35.510880011 -0600
++@@ -39,9 +39,11 @@ class HTMLReportingTestRunnerMixin(objec
++             html_dir = os.path.dirname(os.path.abspath(self.html_output))
++             if not os.path.exists(html_dir):
++                 os.makedirs(html_dir)
++-            with open(self.html_output, 'w') as f:
+++            f = open(self.html_output, 'w')
+++            if 1:
++                 f.write(self.generate_html(self.results))
++ 
+++            f.close()
++     def generate_html(self, results_list):
++         tests = sum([results.testsRun for results in results_list])
++         failures = sum([len(results.failures) for results in results_list])
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_errors.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_errors.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_errors.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_errors.py	2014-10-24 11:41:35.510880011 -0600
++@@ -12,7 +12,7 @@ from errors import ErrorCodes
++ def fake_cause():
++     try:
++         raise ValueError("bar")
++-    except ValueError as e:
+++    except ValueError, e:
++         return sys.exc_info()
++ 
++ message = "foo"
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_execute_isolate.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_execute_isolate.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_execute_isolate.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_execute_isolate.py	2014-10-24 11:41:35.511880007 -0600
++@@ -13,7 +13,7 @@ class TestExecuteIsolationContent(Marion
++     def test_execute_async_isolate(self):
++         # Results from one execute call that has timed out should not
++         # contaminate a future call.
++-        multiplier = "*3" if self.content else "*1"
+++        multiplier = ("*1", "*3")[self.content]
++         self.marionette.set_script_timeout(500)
++         self.assertRaises(ScriptTimeoutException,
++                           self.marionette.execute_async_script,
++@@ -24,7 +24,7 @@ class TestExecuteIsolationContent(Marion
++         result = self.marionette.execute_async_script("""
++ setTimeout(function() { marionetteScriptFinished(10%s); }, 5000);
++ """ % multiplier)
++-        self.assertEqual(result, 30 if self.content else 10)
+++        self.assertEqual(result, (10, 30)[self.content])
++ 
++ class TestExecuteIsolationChrome(TestExecuteIsolationContent):
++     def setUp(self):
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_execute_script.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_execute_script.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_execute_script.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_execute_script.py	2014-10-24 11:41:35.511880007 -0600
++@@ -22,7 +22,7 @@ class TestExecuteContent(MarionetteTestC
++                 """)
++             self.assertFalse(True)
++         except JavascriptException, inst:
++-            self.assertTrue('return b' in inst.stacktrace)
+++            self.assertTrue('return ' in inst.stacktrace)
++ 
++     def test_execute_simple(self):
++         self.assertEqual(1, self.marionette.execute_script("return 1;"))
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_getactiveframe_oop.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_getactiveframe_oop.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_getactiveframe_oop.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_getactiveframe_oop.py	2014-10-24 11:41:35.511880007 -0600
++@@ -99,7 +99,7 @@ class TestGetActiveFrameOOP(MarionetteTe
++         else:
++             self.marionette.execute_script("""
++                 SpecialPowers.setBoolPref('dom.ipc.browser_frames.oop_by_default', %s);
++-                """ % 'true' if self.oop_by_default else 'false')
+++                """ % ('false, 'true')[self.oop_by_default])
++         if self.mozBrowserFramesEnabled is None:
++             self.marionette.execute_script("""
++                 SpecialPowers.clearUserPref('dom.mozBrowserFramesEnabled');
++@@ -107,4 +107,4 @@ class TestGetActiveFrameOOP(MarionetteTe
++         else:
++             self.marionette.execute_script("""
++                 SpecialPowers.setBoolPref('dom.mozBrowserFramesEnabled', %s);
++-                """ % 'true' if self.mozBrowserFramesEnabled else 'false')
+++                """ % ('false', 'true')[self.mozBrowserFramesEnabled])
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_navigation.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_navigation.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_navigation.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_navigation.py	2014-10-24 11:41:35.511880007 -0600
++@@ -75,9 +75,9 @@ class TestNavigate(MarionetteTestCase):
++             self.fail("Should have thrown a MarionetteException")
++         except TimeoutException:
++             self.fail("The socket shouldn't have timed out when navigating to a non-existent URL")
++-        except MarionetteException as e:
+++        except MarionetteException, e:
++             self.assertIn("Error loading page", str(e))
++-        except Exception as inst:
+++        except Exception, inst:
++             import traceback
++             print traceback.format_exc()
++             self.fail("Should have thrown a MarionetteException instead of %s" % type(inst))
++@@ -96,9 +96,9 @@ class TestNavigate(MarionetteTestCase):
++             self.marionette.navigate(test_html)
++             self.assertTrue(self.marionette.find_element("id", "mozLink"))
++             self.fail("Should have thrown a MarionetteException")
++-        except MarionetteException as e:
+++        except MarionetteException, e:
++             self.assertTrue("Error loading page, timed out" in str(e))
++-        except Exception as inst:
+++        except Exception, inst:
++             import traceback
++             print traceback.format_exc()
++             self.fail("Should have thrown a MarionetteException instead of %s" % type(inst))
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_screen_orientation.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_screen_orientation.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_screen_orientation.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_screen_orientation.py	2014-10-24 11:41:35.511880007 -0600
++@@ -82,9 +82,14 @@ class TestScreenOrientation(MarionetteTe
++         self.assertEqual(new_orientation, "landscape-primary")
++ 
++     def test_set_invalid_orientation(self):
++-        with self.assertRaisesRegexp(MarionetteException, unknown_orientation % "cheese"):
+++        self.assertRaisesRegexp(MarionetteException, unknown_orientation % "cheese").__enter__()
+++        if 1:
++             self.marionette.set_orientation("cheese")
++ 
+++        self.assertRaisesRegexp(MarionetteException, unknown_orientation % "cheese").__exit__(0, 0, 0)
++     def test_set_null_orientation(self):
++-        with self.assertRaisesRegexp(MarionetteException, unknown_orientation % "null"):
+++        self.assertRaisesRegexp(MarionetteException, unknown_orientation % "null").__enter__()
+++        if 1:
++             self.marionette.set_orientation(None)
+++        self.assertRaisesRegexp(MarionetteException, unknown_orientation % "null").__exit__(0, 0, 0)
+++
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py	2014-10-24 11:41:35.512880002 -0600
++@@ -45,5 +45,5 @@ class TestSwitchFrameChrome(MarionetteTe
++         self.assertRaises(JavascriptException, self.marionette.execute_async_script, "foo();")
++         try:
++             self.marionette.execute_async_script("foo();")
++-        except JavascriptException as e:
+++        except JavascriptException, e:
++             self.assertIn("foo", e.msg)
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_switch_frame.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_switch_frame.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_switch_frame.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_switch_frame.py	2014-10-24 11:41:35.512880002 -0600
++@@ -45,7 +45,7 @@ class TestSwitchFrame(MarionetteTestCase
++         self.assertRaises(JavascriptException, self.marionette.execute_async_script, "foo();")
++         try:
++             self.marionette.execute_async_script("foo();")
++-        except JavascriptException as e:
+++        except JavascriptException, e:
++             self.assertTrue("foo" in e.msg)
++ 
++     def testShouldBeAbleToCarryOnWorkingIfTheFrameIsDeletedFromUnderUs(self):
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_switch_remote_frame.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_switch_remote_frame.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_switch_remote_frame.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_switch_remote_frame.py	2014-10-24 11:41:35.512880002 -0600
++@@ -84,7 +84,7 @@ class TestSwitchRemoteFrame(MarionetteTe
++         else:
++             self.marionette.execute_script("""
++                 SpecialPowers.setBoolPref('dom.ipc.browser_frames.oop_by_default', %s);
++-                """ % 'true' if self.oop_by_default else 'false')
+++                """ % ('false', 'true')[self.oop_by_default])
++         if self.mozBrowserFramesEnabled is None:
++             self.marionette.execute_script("""
++                 SpecialPowers.clearUserPref('dom.mozBrowserFramesEnabled');
++@@ -92,4 +92,4 @@ class TestSwitchRemoteFrame(MarionetteTe
++         else:
++             self.marionette.execute_script("""
++                 SpecialPowers.setBoolPref('dom.mozBrowserFramesEnabled', %s);
++-                """ % 'true' if self.mozBrowserFramesEnabled else 'false')
+++                """ % ('false, 'true')[self.mozBrowserFramesEnabled])
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_wait.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_wait.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_wait.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/tests/unit/test_wait.py	2014-10-24 11:41:35.512880002 -0600
++@@ -190,27 +190,33 @@ class WaitUntilTest(MarionetteTestCase):
++         self.assertEqual(self.clock.ticks, 4)
++ 
++     def test_timeout(self):
++-        with self.assertRaises(errors.TimeoutException):
+++        self.assertRaises(errors.TimeoutException).__enter__()
+++        if 1:
++             r = self.wt.until(lambda x: x.true(wait=15))
+++        self.assertRaises(errors.TimeoutException).__exit__(0, 0, 0)
++         self.assertEqual(self.clock.ticks, 10)
++ 
++     def test_exception_raises_immediately(self):
++-        with self.assertRaises(TypeError):
+++        self.assertRaises(TypeError).__enter__()
+++        if 1:
++             self.wt.until(lambda x: x.exception(e=TypeError))
+++        self.assertRaises(TypeError).__exit__(0, 0, 0)
++         self.assertEqual(self.clock.ticks, 0)
++ 
++     def test_ignored_exception(self):
++         self.wt.exceptions = (TypeError,)
++-        with self.assertRaises(errors.TimeoutException):
+++        self.assertRaises(errors.TimeoutException).__enter__()
+++        if 1:
++             self.wt.until(lambda x: x.exception(e=TypeError))
++ 
+++        self.assertRaises(errors.TimeoutException).__exit__(0, 0, 0)
++     def test_ignored_exception_wrapped_in_timeoutexception(self):
++         self.wt.exceptions = (TypeError,)
++ 
++         exc = None
++         try:
++             self.wt.until(lambda x: x.exception(e=TypeError))
++-        except Exception as e:
+++        except Exception, e:
++             exc = e
++ 
++         s = str(exc)
++@@ -220,18 +226,24 @@ class WaitUntilTest(MarionetteTestCase):
++         self.assertIn("self.wt.until(lambda x: x.exception(e=TypeError))", s)
++ 
++     def test_ignored_exception_after_timeout_is_not_raised(self):
++-        with self.assertRaises(errors.TimeoutException):
+++        self.assertRaises(errors.TimeoutException).__enter__()
+++        if 1:
++             r = self.wt.until(lambda x: x.exception(wait=15))
+++        self.assertRaises(errors.TimeoutException).__exit__(0, 0, 0)
++         self.assertEqual(self.clock.ticks, 10)
++ 
++     def test_keyboard_interrupt(self):
++-        with self.assertRaises(KeyboardInterrupt):
+++        self.assertRaises(KeyboardInterrupt).__enter__()
+++        if 1:
++             self.wt.until(lambda x: x.exception(e=KeyboardInterrupt))
++ 
+++        self.assertRaises(KeyboardInterrupt).__exit__(0, 0, 0)
++     def test_system_exit(self):
++-        with self.assertRaises(SystemExit):
+++        self.assertRaises(SystemExit).__enter__()
+++        if 1:
++             self.wt.until(lambda x: x.exception(SystemExit))
++ 
+++        self.assertRaises(SystemExit).__exit__(0, 0, 0)
++     def test_true_condition_returns_immediately(self):
++         r = self.wt.until(lambda x: x.true())
++         self.assertIsInstance(r, bool)
++@@ -249,9 +261,11 @@ class WaitUntilTest(MarionetteTestCase):
++         self.assertEqual(self.clock.ticks, 1)
++ 
++     def test_custom_predicate_times_out(self):
++-        with self.assertRaises(errors.TimeoutException):
+++        self.assertRaises(errors.TimeoutException).__enter__()
+++        if 1:
++             self.wt.until(lambda x: x.true(wait=4), is_true=at_third_attempt)
++ 
+++        self.assertRaises(errors.TimeoutException).__exit__(0, 0, 0)
++         self.assertEqual(self.clock.ticks, 2)
++ 
++     def test_timeout_elapsed_duration(self):
++@@ -270,7 +284,7 @@ class WaitUntilTest(MarionetteTestCase):
++         exc = None
++         try:
++             self.wt.until(lambda x: x.exception(e=TypeError), message="hooba")
++-        except errors.TimeoutException as e:
+++        except errors.TimeoutException, e:
++             exc = e
++ 
++         result = str(exc)
++@@ -281,7 +295,7 @@ class WaitUntilTest(MarionetteTestCase):
++         exc = None
++         try:
++             self.wt.until(lambda x: x.exception(e=TypeError), message="")
++-        except errors.TimeoutException as e:
+++        except errors.TimeoutException, e:
++             exc = e
++ 
++         result = str(exc)
++@@ -292,7 +306,7 @@ class WaitUntilTest(MarionetteTestCase):
++         exc = None
++         try:
++             self.wt.until(False, None, None)
++-        except errors.TimeoutException as e:
+++        except errors.TimeoutException, e:
++             exc = e
++ 
++         result = str(exc)
++diff -up comm-esr31/mozilla/testing/marionette/client/marionette/wait.py.python3 comm-esr31/mozilla/testing/marionette/client/marionette/wait.py
++--- comm-esr31/mozilla/testing/marionette/client/marionette/wait.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/client/marionette/wait.py	2014-10-24 11:41:35.512880002 -0600
++@@ -120,9 +120,9 @@ class Wait(object):
++         while not until(self.clock, self.end):
++             try:
++                 rv = condition(self.marionette)
++-            except (KeyboardInterrupt, SystemExit) as e:
+++            except (KeyboardInterrupt, SystemExit), e:
++                 raise e
++-            except self.exceptions as e:
+++            except self.exceptions, e:
++                 last_exc = sys.exc_info()
++ 
++             if isinstance(rv, bool) and not rv:
++@@ -139,7 +139,7 @@ class Wait(object):
++ 
++         raise errors.TimeoutException(
++             "Timed out after %s seconds%s" %
++-            (round((self.clock.now - start), 1), message if message else ""),
+++            (round((self.clock.now - start), 1), ("", message)[message]),
++             cause=last_exc)
++ 
++ def until_pred(clock, end):
++diff -up comm-esr31/mozilla/testing/marionette/mach_commands.py.python3 comm-esr31/mozilla/testing/marionette/mach_commands.py
++--- comm-esr31/mozilla/testing/marionette/mach_commands.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/mach_commands.py	2014-10-24 11:41:35.513879998 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ import os
++ 
++ from mozbuild.base import (
++diff -up comm-esr31/mozilla/testing/marionette/transport/marionette_transport/transport.py.python3 comm-esr31/mozilla/testing/marionette/transport/marionette_transport/transport.py
++--- comm-esr31/mozilla/testing/marionette/transport/marionette_transport/transport.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/transport/marionette_transport/transport.py	2014-10-24 11:41:35.513879998 -0600
++@@ -89,7 +89,7 @@ class MarionetteTransport(object):
++                        range(0, len(data), self.max_packet_length)]:
++             try: 
++                 self.sock.send(packet)
++-            except IOError as e:
+++            except IOError, e:
++                 if e.errno == errno.EPIPE:
++                     raise IOError("%s: %s" % (str(e)), self.connection_lost_msg)
++                 else:
++diff -up comm-esr31/mozilla/testing/marionette/update-smoketests/smoketest.py.python3 comm-esr31/mozilla/testing/marionette/update-smoketests/smoketest.py
++--- comm-esr31/mozilla/testing/marionette/update-smoketests/smoketest.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/marionette/update-smoketests/smoketest.py	2014-10-24 11:41:35.513879998 -0600
++@@ -52,9 +52,11 @@ class SmokeTestConfig(DictObject):
++         self.build_data = {}
++         self.flash_template = None
++ 
++-        with open(os.path.join(build_dir, 'smoketest-config.json')) as f:
+++        f = open(os.path.join(build_dir, 'smoketest-config.json'))
+++        if 1:
++             DictObject.__init__(self, json.loads(f.read()))
++ 
+++        f.close()
++         for required in self.TOP_LEVEL_REQUIRED:
++             if required not in self:
++                 raise SmokeTestConfigError('No "%s" found' % required)
++@@ -76,12 +78,14 @@ class SmokeTestConfig(DictObject):
++ 
++         build_dir = os.path.join(self.top_dir, device, build_id)
++         flash_zip = os.path.join(build_dir, 'flash.zip')
++-        with zipfile.ZipFile(flash_zip) as zip:
+++        zip = zipfile.ZipFile(flash_zip).__enter__()
+++        if 1:
++             app_ini = ConfigParser()
++             app_ini.readfp(zip.open('system/b2g/application.ini'))
++             platform_ini = ConfigParser()
++             platform_ini.readfp(zip.open('system/b2g/platform.ini'))
++ 
+++        zip.__exit__(0, 0, 0)
++         build_data = self.build_data[device][build_id] = DictObject({
++             'app_version': app_ini.get('App', 'version'),
++             'app_build_id': app_ini.get('App', 'buildid'),
++diff -up comm-esr31/mozilla/testing/mochitest/mach_commands.py.python3 comm-esr31/mozilla/testing/mochitest/mach_commands.py
++--- comm-esr31/mozilla/testing/mochitest/mach_commands.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mochitest/mach_commands.py	2014-10-24 11:41:35.513879998 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import logging
++ import mozpack.path
++@@ -114,18 +114,22 @@ class MochitestRunner(MozbuildObject):
++ 
++         # The imp module can spew warnings if the modules below have
++         # already been imported, ignore them.
++-        with warnings.catch_warnings():
+++        warnings.catch_warnings().__enter__()
+++        if 1:
++             warnings.simplefilter('ignore')
++ 
++             import imp
++             path = os.path.join(self.mochitest_dir, 'runtestsb2g.py')
++-            with open(path, 'r') as fh:
+++            fh = open(path, 'r')
+++            if 1:
++                 imp.load_module('mochitest', fh, path,
++                     ('.py', 'r', imp.PY_SOURCE))
++ 
+++            fh.__exit__(0, 0, 0)
++             import mochitest
++             from mochitest_options import B2GOptions
++ 
+++        warnings.catch_warnings().__exit__(0, 0, 0)
++         parser = B2GOptions()
++         options = parser.parse_args([])[0]
++ 
++@@ -233,10 +237,12 @@ class MochitestRunner(MozbuildObject):
++         if 'mochitest' not in sys.modules:
++             import imp
++             path = os.path.join(self.mochitest_dir, 'runtests.py')
++-            with open(path, 'r') as fh:
+++            fh = open(path, 'r').__enter__()
+++            if 1:
++                 imp.load_module('mochitest', fh, path,
++                     ('.py', 'r', imp.PY_SOURCE))
++ 
+++            fh.close()
++         import mozinfo
++         import mochitest
++         from manifestparser import TestManifest
++diff -up comm-esr31/mozilla/testing/mochitest/mochitest_options.py.python3 comm-esr31/mozilla/testing/mochitest/mochitest_options.py
++--- comm-esr31/mozilla/testing/mochitest/mochitest_options.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mochitest/mochitest_options.py	2014-10-24 11:41:35.514879994 -0600
++@@ -51,7 +51,7 @@ class MochitestOptions(optparse.OptionPa
++         { "action": "store",
++           "type": "string",
++           "dest": "utilityPath",
++-          "default": build_obj.bindir if build_obj is not None else None,
+++          "default": (None, build_obj.bindir)[build_obj is not None],
++           "help": "absolute path to directory containing utility programs (xpcshell, ssltunnel, certutil)",
++         }],
++         [["--certificate-path"],
++@@ -59,7 +59,7 @@ class MochitestOptions(optparse.OptionPa
++           "type": "string",
++           "dest": "certPath",
++           "help": "absolute path to directory containing certificate store to use testing profile",
++-          "default": os.path.join(build_obj.topsrcdir, 'build', 'pgo', 'certs') if build_obj is not None else None,
+++          "default": (None, os.path.join(build_obj.topsrcdir, 'build', 'pgo', 'certs'))[build_obj is not None],
++         }],
++         [["--log-file"],
++         { "action": "store",
++diff -up comm-esr31/mozilla/testing/mochitest/runtestsb2g.py.python3 comm-esr31/mozilla/testing/mochitest/runtestsb2g.py
++--- comm-esr31/mozilla/testing/mochitest/runtestsb2g.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mochitest/runtestsb2g.py	2014-10-24 11:41:35.514879994 -0600
++@@ -84,7 +84,7 @@ class B2GMochitest(MochitestUtilsMixin):
++ 
++         # interpolate the preferences
++         interpolation = { "server": "%s:%s" % (options.webServer, options.httpPort),
++-                          "OOP": "true" if self.out_of_process else "false" }
+++                          "OOP": ("false", "true" })[self.out_of_process]
++         prefs = json.loads(json.dumps(prefs) % interpolation)
++         for pref in prefs:
++             prefs[pref] = Preferences.cast(prefs[pref])
++diff -up comm-esr31/mozilla/testing/mochitest/runtests.py.python3 comm-esr31/mozilla/testing/mochitest/runtests.py
++--- comm-esr31/mozilla/testing/mochitest/runtests.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mochitest/runtests.py	2014-10-24 11:41:35.514879994 -0600
++@@ -6,7 +6,7 @@
++ Runs the Mochitest test harness.
++ """
++ 
++-from __future__ import with_statement
+++
++ import os
++ import sys
++ SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(__file__)))
++@@ -104,8 +104,7 @@ else:
++       # The method throws OSError if the PID is invalid, which we catch below.
++       os.kill(pid, 0)
++ 
++-      # Wait on it to see if it's a zombie. This can throw OSError.ECHILD if
++-      # the process terminates before we get to this point.
+++      # Wait on it to see if it's a zombie. This can throw OSError.ECHILD if # the process terminates before we get to this point.
++       wpid, wstatus = os.waitpid(pid, os.WNOHANG)
++       return wpid == 0
++     except OSError, err:
++@@ -133,7 +132,7 @@ class MochitestServer(object):
++     self.webServer = options['webServer']
++     self.httpPort = options['httpPort']
++     self.shutdownURL = "http://%(server)s:%(port)s/server/shutdown" % { "server" : self.webServer, "port" : self.httpPort }
++-    self.testPrefix = "'webapprt_'" if options.get('webapprtContent') else "undefined"
+++    self.testPrefix = ("undefined", "'webapprt_'")[options.get('webapprtContent')]
++ 
++     if options.get('httpdPath'):
++         self._httpdPath = options['httpdPath']
++@@ -191,9 +190,11 @@ class MochitestServer(object):
++ 
++   def stop(self):
++     try:
++-      with urllib2.urlopen(self.shutdownURL) as c:
+++      c = urllib2.urlopen(self.shutdownURL).__enter__()
+++      if 1:
++         c.read()
++ 
+++      c.__exit__(0, 0, 0)
++       # TODO: need ProcessHandler.poll()
++       # https://bugzilla.mozilla.org/show_bug.cgi?id=912285
++       #      rtncode = self._process.poll()
++@@ -511,8 +512,10 @@ class MochitestUtilsMixin(object):
++       paths.sort(path_sort)
++ 
++       # Bug 883865 - add this functionality into manifestDestiny
++-      with open(os.path.join(testdir, 'tests.json'), 'w') as manifestFile:
+++      manifestFile = open(os.path.join(testdir, 'tests.json'), 'w')
+++      if 1:
++         manifestFile.write(json.dumps({'tests': paths}))
+++      manifestFile.close()
++       options.manifestFile = 'tests.json'
++ 
++     return self.buildTestURL(options)
++@@ -529,9 +532,11 @@ class MochitestUtilsMixin(object):
++     self.server.start()
++ 
++     if options.pidFile != "":
++-      with open(options.pidFile + ".xpcshell.pid", 'w') as f:
+++      f = open(options.pidFile + ".xpcshell.pid", 'w')
+++      if 1:
++         f.write("%s" % self.server._process.pid)
++ 
+++      f.close()
++   def startServers(self, options, debuggerInfo):
++     # start servers and set ports
++     # TODO: pass these values, don't set on `self`
++@@ -602,9 +607,11 @@ class MochitestUtilsMixin(object):
++       copy mochijar directory to profile as an extension so we have chrome://mochikit for all harness code
++     """
++     # Write chrome.manifest.
++-    with open(os.path.join(options.profilePath, "extensions", "staged", "mochikit at mozilla.org", "chrome.manifest"), "a") as mfile:
+++    mfile = open(os.path.join(options.profilePath, "extensions", "staged", "mochikit at mozilla.org", "chrome.manifest"), "a")
+++    if 1:
++       mfile.write(chrome)
++ 
+++    mfile.close()
++   def addChromeToProfile(self, options):
++     "Adds MochiKit chrome tests to the profile."
++ 
++@@ -623,11 +630,14 @@ toolbar#nav-bar {
++   background-image: none !important;
++ }
++ """
++-    with open(os.path.join(options.profilePath, "userChrome.css"), "a") as chromeFile:
+++    chromeFile = open(os.path.join(options.profilePath, "userChrome.css"), "a")
+++    if 1:
++       chromeFile.write(chrome)
++ 
+++    chromeFile.close()
++     manifest = os.path.join(options.profilePath, "tests.manifest")
++-    with open(manifest, "w") as manifestFile:
+++    manifestFile = open(manifest, "w")
+++    if 1:
++       # Register chrome directory.
++       chrometestDir = os.path.join(os.path.abspath("."), SCRIPT_DIR) + "/"
++       if mozinfo.isWin:
++@@ -638,6 +648,7 @@ toolbar#nav-bar {
++         manifestFile.write("resource testing-common file:///%s\n" %
++           options.testingModulesDir)
++ 
+++    manifestFile.close()
++     # Call installChromeJar().
++     if not os.path.isdir(os.path.join(SCRIPT_DIR, self.jarDir)):
++       log.testFail("invalid setup: missing mochikit extension")
++@@ -660,7 +671,11 @@ overlay chrome://webapprt/content/webapp
++   def getExtensionsToInstall(self, options):
++     "Return a list of extensions to install in the profile"
++     extensions = options.extensionsToInstall or []
++-    appDir = options.app[:options.app.rfind(os.sep)] if options.app else options.utilityPath
+++    appDir = None
+++    if options.app:
+++      appDir = options.app[:options.app.rfind(os.sep)]
+++    else:
+++      appDir = options.utilityPath
++ 
++     extensionDirs = [
++       # Extensions distributed with the test harness.
++@@ -720,7 +735,8 @@ class SSLTunnel:
++   def buildConfig(self, locations):
++     """Create the ssltunnel configuration file"""
++     configFd, self.configFile = tempfile.mkstemp(prefix="ssltunnel", suffix=".cfg")
++-    with os.fdopen(configFd, "w") as config:
+++    config = os.fdopen(configFd, "w").__enter__()
+++    if 1:
++       config.write("httpproxy:1\n")
++       config.write("certdbdir:%s\n" % self.certPath)
++       config.write("forward:127.0.0.1:%s\n" % self.httpPort)
++@@ -731,6 +747,7 @@ class SSLTunnel:
++         if loc.scheme == "https" and "nocert" not in loc.options:
++           self.writeLocation(config, loc)
++ 
+++    config.__exit__(0, 0, 0)
++   def start(self):
++     """ Starts the SSL Tunnel """
++ 
++@@ -770,10 +787,13 @@ class Mochitest(MochitestUtilsMixin):
++     # environment function for browserEnv
++     self.environment = environment
++ 
++-    # Max time in seconds to wait for server startup before tests will fail -- if
++-    # this seems big, it's mostly for debug machines where cold startup
+++    # Max time in seconds to wait for server startup before tests will fail -- if # this seems big, it's mostly for debug machines where cold startup
++     # (particularly after a build) takes forever.
++-    self.SERVER_STARTUP_TIMEOUT = 180 if mozinfo.info.get('debug') else 90
+++    self.SERVER_STARTUP_TIMEOUT = None
+++    if mozinfo.info.get('debug'):
+++      self.SERVER_STARTUP_TIMEOUT = 180
+++    else:
+++      self.SERVER_STARTUP_TIMEOUT = 90
++ 
++     # metro browser sub process id
++     self.browserProcessId = None
++@@ -795,9 +815,11 @@ class Mochitest(MochitestUtilsMixin):
++     # https://bugzilla.mozilla.org/show_bug.cgi?id=746243#c35
++ 
++     pwfilePath = os.path.join(options.profilePath, ".crtdbpw")
++-    with open(pwfilePath, "w") as pwfile:
+++    pwfile = open(pwfilePath, "w")
+++    if 1:
++       pwfile.write("\n")
++ 
+++    pwfile.close()
++     # Pre-create the certification database for the profile
++     env = self.environment(xrePath=options.xrePath)
++     bin_suffix = mozinfo.info.get('bin_suffix', '')
++@@ -838,8 +860,8 @@ class Mochitest(MochitestUtilsMixin):
++     """ create the profile and add optional chrome bits and files if requested """
++     if options.browserChrome and options.timeout:
++       options.extraPrefs.append("testing.browserTestHarness.timeout=%d" % options.timeout)
++-    options.extraPrefs.append("browser.tabs.remote=%s" % ('true' if options.e10s else 'false'))
++-    options.extraPrefs.append("browser.tabs.remote.autostart=%s" % ('true' if options.e10s else 'false'))
+++    options.extraPrefs.append("browser.tabs.remote=%s" % (('false', 'true')[options.e10s]))
+++    options.extraPrefs.append("browser.tabs.remote.autostart=%s" % (('false', 'true)[options.e10s]))
++ 
++     # get extensions to install
++     extensions = self.getExtensionsToInstall(options)
++@@ -847,8 +869,10 @@ class Mochitest(MochitestUtilsMixin):
++     # web apps
++     appsPath = os.path.join(SCRIPT_DIR, 'profile_data', 'webapps_mochitest.json')
++     if os.path.exists(appsPath):
++-      with open(appsPath) as apps_file:
+++      apps_file = open(appsPath)
+++      if 1:
++         apps = json.load(apps_file)
+++      apps_file.close()
++     else:
++       apps = None
++ 
++@@ -997,13 +1021,15 @@ class Mochitest(MochitestUtilsMixin):
++     log.info('INFO | zombiecheck | Reading PID log: %s', processLog)
++     processList = []
++     pidRE = re.compile(r'launched child process (\d+)$')
++-    with open(processLog) as processLogFD:
+++    processLogFD = open(processLog)
+++    if 1:
++       for line in processLogFD:
++         log.info(line.rstrip())
++         m = pidRE.search(line)
++         if m:
++           processList.append(int(m.group(1)))
++ 
+++    processLogFD.close()
++     # kill zombies
++     foundZombie = False
++     for processPID in processList:
++@@ -1305,11 +1331,13 @@ class Mochitest(MochitestUtilsMixin):
++     processLeakLog(self.leak_report_file, options.leakThreshold)
++ 
++     if self.nsprLogs:
++-      with zipfile.ZipFile("%s/nsprlog.zip" % browserEnv["MOZ_UPLOAD_DIR"], "w", zipfile.ZIP_DEFLATED) as logzip:
+++      logzip = zipfile.ZipFile("%s/nsprlog.zip" % browserEnv["MOZ_UPLOAD_DIR"], "w", zipfile.ZIP_DEFLATED).__enter__()
+++      if 1:
++         for logfile in glob.glob("%s/nspr*.log*" % tempfile.gettempdir()):
++           logzip.write(logfile)
++           os.remove(logfile)
++ 
+++      logzip.__exit__(0, 0, 0)
++     log.info("runtests.py | Running tests: end.")
++ 
++     if manifest is not None:
++@@ -1505,9 +1533,11 @@ class Mochitest(MochitestUtilsMixin):
++     d['testRoot'] = testRoot
++     content = json.dumps(d)
++ 
++-    with open(os.path.join(options.profilePath, "testConfig.js"), "w") as config:
+++    config = open(os.path.join(options.profilePath, "testConfig.js"), "w")
+++    if 1:
++       config.write(content)
++ 
+++    config.close()
++   def installExtensionFromPath(self, options, path, extensionID = None):
++     """install an extension to options.profilePath"""
++ 
++diff -up comm-esr31/mozilla/testing/mochitest/runtestsremote.py.python3 comm-esr31/mozilla/testing/mochitest/runtestsremote.py
++--- comm-esr31/mozilla/testing/mochitest/runtestsremote.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mochitest/runtestsremote.py	2014-10-24 11:41:35.515879990 -0600
++@@ -407,9 +407,11 @@ class MochiRemote(Mochitest):
++ 
++     # In the future we could use LogParser: http://hg.mozilla.org/automation/logparser/
++     def addLogData(self):
++-        with open(self.localLog) as currentLog:
+++        currentLog = open(self.localLog)
+++        if 1:
++             data = currentLog.readlines()
++ 
+++        currentLog.close()
++         restart = re.compile('0 INFO SimpleTest START.*')
++         reend = re.compile('([0-9]+) INFO TEST-START . Shutdown.*')
++         refail = re.compile('([0-9]+) INFO TEST-UNEXPECTED-FAIL.*')
++@@ -466,9 +468,11 @@ class MochiRemote(Mochitest):
++ 
++         # TODO: Consider not printing to stdout because we might be duplicating output
++         print '\n'.join(logFile)
++-        with open(self.localLog, 'w') as localLog:
+++        localLog = open(self.localLog, 'w')
+++        if 1:
++             localLog.write('\n'.join(logFile))
++ 
+++        localLog.close()
++         if failed > 0:
++             return 1
++         return 0
++diff -up comm-esr31/mozilla/testing/mozbase/manifestdestiny/manifestparser/manifestparser.py.python3 comm-esr31/mozilla/testing/mozbase/manifestdestiny/manifestparser/manifestparser.py
++--- comm-esr31/mozilla/testing/mozbase/manifestdestiny/manifestparser/manifestparser.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/manifestdestiny/manifestparser/manifestparser.py	2014-10-24 11:41:35.515879990 -0600
++@@ -14,7 +14,7 @@ __all__ = ['read_ini', # .ini reader
++ 
++ import fnmatch
++ import os
++-import re
+++import re, sre
++ import shutil
++ import sys
++ 
++@@ -258,12 +258,13 @@ class ExpressionParser(object):
++         passed to the constructor. Raises a ParseError if the expression
++         could not be parsed.
++         """
++-        try:
+++        #try:
+++        if 1:
++             self.iter = self._tokenize()
++             self.token = self.iter.next()
++             return self.expression()
++-        except:
++-            raise ParseError("could not parse: %s; variables: %s" % (self.text, self.valuemapping))
+++        #except:
+++        #    raise ParseError("could not parse: %s; variables: %s" % (self.text, self.valuemapping))
++ 
++     __call__ = parse
++ 
++@@ -318,7 +319,7 @@ def read_ini(fp, variables=None, default
++         fp = file(fp)
++ 
++     # read the lines
++-    for (linenum, line) in enumerate(fp.readlines(), start=1):
+++    for (linenum, line) in enumerate(fp.readlines()):
++ 
++         stripped = line.strip()
++ 
++@@ -385,7 +386,7 @@ def read_ini(fp, variables=None, default
++                 else:
++                     filename = 'unknown'
++                 raise Exception("Error parsing manifest file '%s', line %s" %
++-                                (filename, linenum))
+++                                (filename, linenum+1))
++ 
++     # interpret the variables
++     def interpret_variables(global_dict, local_dict):
++@@ -961,12 +962,14 @@ class ManifestParser(object):
++ 
++             manifest_path = os.path.join(dirpath, filename)
++             if (dirnames or filenames) and not (os.path.exists(manifest_path) and overwrite):
++-                with file(manifest_path, 'w') as manifest:
+++                manifest = file(manifest_path, 'w').__enter__()
+++                if 1:
++                     for dirname in dirnames:
++                         print >> manifest, '[include:%s]' % os.path.join(dirname, filename)
++                     for _filename in filenames:
++                         print >> manifest, '[%s]' % _filename
++ 
+++                manifest.__exit__(0, 0, 0)
++                 # add to list of manifests
++                 manifest_dict.setdefault(directory, manifest_path)
++ 
++diff -up comm-esr31/mozilla/testing/mozbase/manifestdestiny/tests/test_convert_directory.py.python3 comm-esr31/mozilla/testing/mozbase/manifestdestiny/tests/test_convert_directory.py
++--- comm-esr31/mozilla/testing/mozbase/manifestdestiny/tests/test_convert_directory.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/manifestdestiny/tests/test_convert_directory.py	2014-10-24 11:41:35.515879990 -0600
++@@ -136,9 +136,11 @@ subsuite =
++         newtempdir = tempfile.mkdtemp()
++         manifest_file = os.path.join(newtempdir, 'manifest.ini')
++         manifest_contents = str(convert([tempdir], relative_to=tempdir))
++-        with file(manifest_file, 'w') as f:
+++        f = file(manifest_file, 'w').__enter__()
+++        if 1:
++             f.write(manifest_contents)
++ 
+++        f.__exit__(0, 0, 0)
++         # get the manifest
++         manifest = ManifestParser(manifests=(manifest_file,))
++ 
++diff -up comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py.python3 comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py
++--- comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py	2014-10-24 11:41:35.516879985 -0600
++@@ -579,7 +579,8 @@ class DeviceManagerADB(DeviceManager):
++ 
++         timeout = int(timeout)
++         retries = 0
++-        with tempfile.SpooledTemporaryFile() as procOut:
+++        procOut = tempfile.SpooledTemporaryFile().__enter__()
+++        if 1:
++             while retries < retryLimit:
++                 proc = subprocess.Popen(finalArgs, stdout=procOut, stderr=subprocess.STDOUT)
++                 start_time = time.time()
++@@ -592,6 +593,7 @@ class DeviceManagerADB(DeviceManager):
++                     retries += 1
++                     continue
++                 return ret_code
+++        procOut.__exit__(0, 0, 0)
++         raise DMError("Timeout exceeded for _checkCmd call after %d retries." % retries)
++ 
++     def chmodDir(self, remoteDir, mask="777"):
++diff -up comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/devicemanager.py.python3 comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/devicemanager.py
++--- comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/devicemanager.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/devicemanager.py	2014-10-24 11:41:35.516879985 -0600
++@@ -72,7 +72,11 @@ class DeviceManager(object):
++     @debug.setter
++     def debug_setter(self, newDebug):
++         self._logger.warn("dm.debug is deprecated. Use logLevel.")
++-        newDebug = 5 if newDebug > 5 else newDebug # truncate >=5 to 5
+++        newDebug = None
+++        if newDebug > 5:
+++          newDebug = 5
+++        else:
+++          newDebug = newDebug # truncate >=5 to 5
++         levels = {5: mozlog.DEBUG, 3: mozlog.INFO, 2: mozlog.WARNING,
++                   1: mozlog.ERROR, 0: mozlog.CRITICAL}
++         self.logLevel = levels[newDebug]
++@@ -154,7 +158,8 @@ class DeviceManager(object):
++         if not self.fileExists(screencap):
++             raise DMError("Unable to capture screenshot on device: no screencap utility")
++ 
++-        with open(filename, 'w') as pngfile:
+++        pngfile = open(filename, 'w')
+++        if 1:
++             # newer versions of screencap can write directly to a png, but some
++             # older versions can't
++             tempScreenshotFile = self.getDeviceRoot() + "/ss-dm.tmp"
++@@ -164,10 +169,13 @@ class DeviceManager(object):
++             buf = self.pullFile(tempScreenshotFile)
++             width = int(struct.unpack("I", buf[0:4])[0])
++             height = int(struct.unpack("I", buf[4:8])[0])
++-            with open(filename, 'w') as pngfile:
+++            pngfile = open(filename, 'w')
+++            if 1:
++                 pngfile.write(self._writePNG(buf[12:], width, height))
+++            pngfile.close()
++             self.removeFile(tempScreenshotFile)
++ 
+++        pngfile.close()
++     @abstractmethod
++     def pushFile(self, localFilename, remoteFilename, retryLimit=1, createDir=True):
++         """
++@@ -511,11 +519,11 @@ class DeviceManager(object):
++         """
++         # Based on: http://code.activestate.com/recipes/577443-write-a-png-image-in-native-python/
++         width_byte_4 = width * 4
++-        raw_data = b"".join(b'\x00' + buf[span:span + width_byte_4] for span in range(0, (height - 1) * width * 4, width_byte_4))
+++        raw_data = "".join(b'\x00' + buf[span:span + width_byte_4] for span in range(0, (height - 1) * width * 4, width_byte_4))
++         def png_pack(png_tag, data):
++             chunk_head = png_tag + data
++             return struct.pack("!I", len(data)) + chunk_head + struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head))
++-        return b"".join([
+++        return "".join([
++                 b'\x89PNG\r\n\x1a\n',
++                 png_pack(b'IHDR', struct.pack("!2I5B", width, height, 8, 6, 0, 0, 0)),
++                 png_pack(b'IDAT', zlib.compress(raw_data, 9)),
++diff -up comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/devicemanagerSUT.py.python3 comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/devicemanagerSUT.py
++--- comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/devicemanagerSUT.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/devicemanagerSUT.py	2014-10-24 11:41:35.516879985 -0600
++@@ -119,8 +119,7 @@ class DeviceManagerSUT(DeviceManager):
++         """
++         # this allows us to move the retry logic outside of the _doCmds() to make it
++         # easier for debugging in the future.
++-        # note that since cmdlist is a list of commands, they will all be retried if
++-        # one fails.  this is necessary in particular for pushFile(), where we don't want
+++        # note that since cmdlist is a list of commands, they will all be retried if # one fails.  this is necessary in particular for pushFile(), where we don't want
++         # to accidentally send extra data if a failure occurs during data transmission.
++ 
++         retryLimit = retryLimit or self.retryLimit
++@@ -347,9 +346,11 @@ class DeviceManagerSUT(DeviceManager):
++ 
++         try:
++             filesize = os.path.getsize(localname)
++-            with open(localname, 'rb') as f:
+++            f = open(localname, 'rb')
+++            if 1:
++                 remoteHash = self._runCmds([{ 'cmd': 'push ' + destname + ' ' + str(filesize),
++                                               'data': f.read() }], retryLimit=retryLimit).strip()
+++            f.close()
++         except OSError:
++             raise DMError("DeviceManager: Error reading file to push")
++ 
++diff -up comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/droid.py.python3 comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/droid.py
++--- comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/droid.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/droid.py	2014-10-24 11:41:35.516879985 -0600
++@@ -42,7 +42,7 @@ class DroidMixin(object):
++                           "at once")
++ 
++         acmd = [ "am", "start" ] + self._getExtraAmStartArgs() + \
++-            ["-W" if wait else '', "-n", "%s/%s" % (appName, activityName)]
+++            [('', "-W")[wait], "-n", "%s/%s" % (appName, activityName)]
++ 
++         if intent:
++             acmd.extend(["-a", intent])
++diff -up comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/sutini.py.python3 comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/sutini.py
++--- comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/sutini.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/sutini.py	2014-10-24 11:41:35.517879981 -0600
++@@ -70,7 +70,7 @@ def set_opt(cfg, s, o, dflt):
++ 
++ def bool_query(prompt, dflt):
++     while True:
++-        i = raw_input('%s [%s] ' % (prompt, 'y' if dflt else 'n')).lower()
+++        i = raw_input('%s [%s] ' % (prompt, ('n', 'y')[dflt])).lower()
++         if not i or i[0] in ('y', 'n'):
++             break
++         print 'Enter y or n.'
++diff -up comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/Zeroconf.py.python3 comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/Zeroconf.py
++--- comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/Zeroconf.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozdevice/mozdevice/Zeroconf.py	2014-10-24 11:41:35.517879981 -0600
++@@ -1470,8 +1470,7 @@ class Zeroconf(object):
++             self.updateRecord(now, record)
++ 
++     def handleQuery(self, msg, addr, port):
++-        """Deal with incoming query packets.  Provides a response if
++-        possible."""
+++        """Deal with incoming query packets.  Provides a response if possible."""
++         out = None
++ 
++         # Support unicast client responses
++diff -up comm-esr31/mozilla/testing/mozbase/mozdevice/sut_tests/genfiles.py.python3 comm-esr31/mozilla/testing/mozbase/mozdevice/sut_tests/genfiles.py
++--- comm-esr31/mozilla/testing/mozbase/mozdevice/sut_tests/genfiles.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozdevice/sut_tests/genfiles.py	2014-10-24 11:41:35.517879981 -0600
++@@ -10,19 +10,23 @@ import shutil
++ 
++ 
++ def gen_binary_file(path, size):
++-    with open(path, 'wb') as f:
+++    f = open(path, 'wb')
+++    if 1:
++         for i in xrange(size):
++             byte = '%c' % randint(0, 255)
++             f.write(byte)
++ 
++ 
+++    f.close()
++ def gen_zip(path, files, stripped_prefix=''):
++-    with ZipFile(path, 'w') as z:
+++    z = ZipFile(path, 'w').__enter__()
+++    if 1:
++         for f in files:
++             new_name = f.replace(stripped_prefix, '')
++             z.write(f, new_name)
++ 
++ 
+++    z.__exit__(0, 0, 0)
++ def mkdir(path, *args):
++     try:
++         os.mkdir(path, *args)
++diff -up comm-esr31/mozilla/testing/mozbase/mozdevice/sut_tests/test_fileExists.py.python3 comm-esr31/mozilla/testing/mozbase/mozdevice/sut_tests/test_fileExists.py
++--- comm-esr31/mozilla/testing/mozbase/mozdevice/sut_tests/test_fileExists.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozdevice/sut_tests/test_fileExists.py	2014-10-24 11:41:35.517879981 -0600
++@@ -20,8 +20,10 @@ class FileExistsTestCase(DeviceManagerTe
++     def testOnRegularFile(self):
++         remote_path = posixpath.join(self.dm.getDeviceRoot(), 'testFile')
++         self.assertFalse(self.dm.fileExists(remote_path))
++-        with tempfile.NamedTemporaryFile() as f:
+++        f = tempfile.NamedTemporaryFile().__enter__()
+++        if 1:
++             self.dm.pushFile(f.name, remote_path)
+++        f.__exit__(0, 0, 0)
++         self.assertTrue(self.dm.fileExists(remote_path))
++         self.dm.removeFile(remote_path)
++ 
++@@ -29,8 +31,10 @@ class FileExistsTestCase(DeviceManagerTe
++         remote_path = posixpath.join(self.dm.getDeviceRoot(), 'testDir')
++         remote_path_file = posixpath.join(remote_path, 'testFile')
++         self.assertFalse(self.dm.fileExists(remote_path))
++-        with tempfile.NamedTemporaryFile() as f:
+++        f = tempfile.NamedTemporaryFile().__enter__()
+++        if 1:
++             self.dm.pushFile(f.name, remote_path_file)
+++        f.__exit__(0, 0, 0)
++         self.assertTrue(self.dm.fileExists(remote_path))
++         self.dm.removeFile(remote_path_file)
++         self.dm.removeDir(remote_path)
++diff -up comm-esr31/mozilla/testing/mozbase/mozdevice/tests/sut_fileMethods.py.python3 comm-esr31/mozilla/testing/mozbase/mozdevice/tests/sut_fileMethods.py
++--- comm-esr31/mozilla/testing/mozbase/mozdevice/tests/sut_fileMethods.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozdevice/tests/sut_fileMethods.py	2014-10-24 11:41:35.518879977 -0600
++@@ -21,7 +21,8 @@ class TestFileMethods(unittest.TestCase)
++ 
++     def test_validateFile(self):
++ 
++-        with tempfile.NamedTemporaryFile() as f:
+++        f = tempfile.NamedTemporaryFile().__enter__()
+++        if 1:
++             f.write(self.content)
++             f.flush()
++ 
++@@ -39,18 +40,21 @@ class TestFileMethods(unittest.TestCase)
++             d = mozdevice.DroidSUT("127.0.0.1", port=m.port, logLevel=mozlog.DEBUG)
++             self.assertFalse(d.validateFile('/sdcard/test/file', f.name))
++ 
+++        f.__exit__(0, 0, 0)
++     def test_getFile(self):
++ 
++         fname = "/mnt/sdcard/file"
++         commands = [("pull %s" % fname, "%s,%s\n%s" % (fname, len(self.content), self.content)),
++                     ("hash %s" % fname, self.temp_hash)]
++ 
++-        with tempfile.NamedTemporaryFile() as f:
+++        f = tempfile.NamedTemporaryFile().__enter__()
+++        if 1:
++             m = MockAgent(self, commands=commands)
++             d = mozdevice.DroidSUT("127.0.0.1", port=m.port, logLevel=mozlog.DEBUG)
++             # No error means success
++             self.assertEqual(None, d.getFile(fname, f.name))
++ 
+++        f.__exit__(0, 0, 0)
++     def test_getDirectory(self):
++ 
++         fname = "/mnt/sdcard/file"
++diff -up comm-esr31/mozilla/testing/mozbase/mozdevice/tests/sut_push.py.python3 comm-esr31/mozilla/testing/mozbase/mozdevice/tests/sut_push.py
++--- comm-esr31/mozilla/testing/mozbase/mozdevice/tests/sut_push.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozdevice/tests/sut_push.py	2014-10-24 11:41:35.518879977 -0600
++@@ -20,7 +20,8 @@ class PushTest(unittest.TestCase):
++             a = MockAgent(self, commands = [("isdir /mnt/sdcard", "TRUE"),
++                                             (cmd, response[0])])
++             exceptionThrown = False
++-            with tempfile.NamedTemporaryFile() as f:
+++            f = tempfile.NamedTemporaryFile().__enter__()
+++            if 1:
++                 try:
++                     f.write(pushfile)
++                     f.flush()
++@@ -29,6 +30,7 @@ class PushTest(unittest.TestCase):
++                 except mozdevice.DMError, e:
++                     exceptionThrown = True
++                 self.assertEqual(exceptionThrown, response[1])
+++            f.__exit__(0, 0, 0)
++             a.wait()
++ 
++     def test_push_dir(self):
++diff -up comm-esr31/mozilla/testing/mozbase/mozfile/mozfile/mozfile.py.python3 comm-esr31/mozilla/testing/mozbase/mozfile/mozfile/mozfile.py
++--- comm-esr31/mozilla/testing/mozbase/mozfile/mozfile/mozfile.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozfile/mozfile/mozfile.py	2014-10-24 11:41:35.518879977 -0600
++@@ -4,7 +4,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from contextlib import contextmanager
+++
++ import errno
++ import os
++ import shutil
++@@ -287,12 +287,12 @@ def tree(directory,
++         # if the top-level entry directory, print as passed
++         retval.append('%s%s%s'% (''.join(indent[:-1]),
++                                  dirpath_mark,
++-                                 basename if retval else directory))
+++                                 (directory, basename)[retval]))
++         # add the files
++         if filenames:
++             last_file = filenames[-1]
++             retval.extend([('%s%s%s' % (''.join(indent),
++-                                        files_end if filename == last_file else item_marker,
+++                                        (item_marker, files_end)[filename == last_file],
++                                         filename))
++                                         for index, filename in enumerate(filenames)])
++ 
++@@ -312,11 +312,13 @@ class NamedTemporaryFile(object):
++ 
++     Example usage:
++ 
++-    with NamedTemporaryFile() as fh:
+++    fh = NamedTemporaryFile().__enter__()
+++    if 1:
++         fh.write(b'foobar')
++ 
++         print('Filename: %s' % fh.name)
++ 
+++    fh.__exit__(0, 0, 0)
++     see https://bugzilla.mozilla.org/show_bug.cgi?id=821362
++     """
++     def __init__(self, mode='w+b', bufsize=-1, suffix='', prefix='tmp',
++@@ -354,21 +356,23 @@ class NamedTemporaryFile(object):
++             os.unlink(self.__dict__['_path'])
++ 
++ 
++- at contextmanager
+++#@contextmanager
++ def TemporaryDirectory():
++     """
++     create a temporary directory using tempfile.mkdtemp, and then clean it up.
++ 
++     Example usage:
++-    with TemporaryDirectory() as tmp:
+++    tmp = TemporaryDirectory().__enter__()
+++    if 1:
++        open(os.path.join(tmp, "a_temp_file"), "w").write("data")
++ 
+++    tmp.__exit__(0, 0, 0)
++     """
++     tempdir = tempfile.mkdtemp()
++-    try:
++-        yield tempdir
++-    finally:
++-        shutil.rmtree(tempdir)
+++    #try:
+++    yield tempdir
+++    #finally:
+++    shutil.rmtree(tempdir)
++ 
++ 
++ ### utilities dealing with URLs
++diff -up comm-esr31/mozilla/testing/mozbase/mozfile/tests/test_remove.py.python3 comm-esr31/mozilla/testing/mozbase/mozfile/tests/test_remove.py
++--- comm-esr31/mozilla/testing/mozbase/mozfile/tests/test_remove.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozfile/tests/test_remove.py	2014-10-24 11:41:35.518879977 -0600
++@@ -32,8 +32,10 @@ class FileOpenCloseThread(threading.Thre
++         self.delete = delete
++ 
++     def run(self):
++-        with open(self.path) as f:
+++        f = open(self.path)
+++        if 1:
++             time.sleep(self.delay)
+++        f.__exit__(0, 0, 0)
++         if self.delete:
++             try:
++                 os.remove(self.path)
++@@ -79,9 +81,11 @@ class MozfileRemoveTestCase(unittest.Tes
++         """Test removing a closed file"""
++         # Open a file in the generated stub
++         filepath = os.path.join(self.tempdir, *stubs.files[1])
++-        with open(filepath, 'w') as f:
+++        f = open(filepath, 'w').__enter__()
+++        if 1:
++             f.write('foo-bar')
++ 
+++        f.close()
++         # Folder should be deleted on all platforms
++         mozfile.remove(self.tempdir)
++         self.assertFalse(os.path.exists(self.tempdir))
++diff -up comm-esr31/mozilla/testing/mozbase/mozfile/tests/test_tempdir.py.python3 comm-esr31/mozilla/testing/mozbase/mozfile/tests/test_tempdir.py
++--- comm-esr31/mozilla/testing/mozbase/mozfile/tests/test_tempdir.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozfile/tests/test_tempdir.py	2014-10-24 11:41:35.518879977 -0600
++@@ -18,23 +18,29 @@ class TestTemporaryDirectory(unittest.Te
++     def test_removed(self):
++         """ensure that a TemporaryDirectory gets removed"""
++         path = None
++-        with TemporaryDirectory() as tmp:
+++        tmp = TemporaryDirectory().__enter__()
+++        if 1:
++             path = tmp
++             self.assertTrue(os.path.isdir(tmp))
++             tmpfile = os.path.join(tmp, "a_temp_file")
++             open(tmpfile, "w").write("data")
++             self.assertTrue(os.path.isfile(tmpfile))
+++        tmp.__exit__(0, 0, 0)
++         self.assertFalse(os.path.isdir(path))
++         self.assertFalse(os.path.exists(path))
++ 
++     def test_exception(self):
++         """ensure that TemporaryDirectory handles exceptions"""
++         path = None
++-        with self.assertRaises(Exception):
++-            with TemporaryDirectory() as tmp:
+++        self.assertRaises(Exception).__enter__()
+++        if 1:
+++            tmp = TemporaryDirectory().__enter__()
+++            if 1:
++                 path = tmp
++                 self.assertTrue(os.path.isdir(tmp))
++                 raise Exception("oops")
+++            tmp.__exit__(0, 0, 0)
+++        self.assertRaises(Exception).__exit__(0, 0, 0)
++         self.assertFalse(os.path.isdir(path))
++         self.assertFalse(os.path.exists(path))
++ 
++diff -up comm-esr31/mozilla/testing/mozbase/mozfile/tests/test_tempfile.py.python3 comm-esr31/mozilla/testing/mozbase/mozfile/tests/test_tempfile.py
++--- comm-esr31/mozilla/testing/mozbase/mozfile/tests/test_tempfile.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozfile/tests/test_tempfile.py	2014-10-24 11:41:35.519879973 -0600
++@@ -24,7 +24,8 @@ class TestNamedTemporaryFile(unittest.Te
++         """
++ 
++         test_string = "A simple test"
++-        with mozfile.NamedTemporaryFile() as temp:
+++        temp = mozfile.NamedTemporaryFile().__enter__()
+++        if 1:
++             # Test we can write to file
++             temp.write(test_string)
++             # Forced flush, so that we can read later
++@@ -33,6 +34,7 @@ class TestNamedTemporaryFile(unittest.Te
++             # Test we can open the file again on all platforms
++             self.assertEqual(open(temp.name).read(), test_string)
++ 
+++        temp.__exit__(0, 0, 0)
++     def test_iteration(self):
++         """ensure the line iterator works"""
++ 
++@@ -64,8 +66,10 @@ class TestNamedTemporaryFile(unittest.Te
++ 
++         # make a deleteable file; ensure it gets cleaned up
++         path = None
++-        with mozfile.NamedTemporaryFile(delete=True) as tf:
+++        tf = mozfile.NamedTemporaryFile(delete=True).__enter__()
+++        if 1:
++             path = tf.name
+++        tf.__exit__(0, 0, 0)
++         self.assertTrue(isinstance(path, basestring))
++         self.assertFalse(os.path.exists(path))
++ 
++@@ -80,8 +84,10 @@ class TestNamedTemporaryFile(unittest.Te
++         # Now the same thing but we won't delete the file
++         path = None
++         try:
++-            with mozfile.NamedTemporaryFile(delete=False) as tf:
+++            tf = mozfile.NamedTemporaryFile(delete=False).__enter__()
+++            if 1:
++                 path = tf.name
+++            tf.__exit__(0, 0, 0)
++             self.assertTrue(os.path.exists(path))
++         finally:
++             if path and os.path.exists(path):
++diff -up comm-esr31/mozilla/testing/mozbase/mozhttpd/mozhttpd/mozhttpd.py.python3 comm-esr31/mozilla/testing/mozbase/mozhttpd/mozhttpd/mozhttpd.py
++--- comm-esr31/mozilla/testing/mozbase/mozhttpd/mozhttpd/mozhttpd.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozhttpd/mozhttpd/mozhttpd.py	2014-10-24 11:41:35.519879973 -0600
++@@ -213,8 +213,7 @@ class MozHttpd(object):
++     from <self.docroot>/<host>/.
++ 
++     For example, the request "GET http://foo.bar/dir/file.html" would
++-    (assuming no handlers match) serve <docroot>/dir/file.html if
++-    proxy_host_dirs is False, or <docroot>/foo.bar/dir/file.html if it is
+++    (assuming no handlers match) serve <docroot>/dir/file.html if proxy_host_dirs is False, or <docroot>/foo.bar/dir/file.html if it is
++     True.
++     """
++ 
++diff -up comm-esr31/mozilla/testing/mozbase/mozhttpd/tests/basic.py.python3 comm-esr31/mozilla/testing/mozbase/mozhttpd/tests/basic.py
++--- comm-esr31/mozilla/testing/mozbase/mozhttpd/tests/basic.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozhttpd/tests/basic.py	2014-10-24 11:41:35.519879973 -0600
++@@ -27,9 +27,11 @@ class TestBasic(unittest.TestCase):
++             sizes[k].append(fpath)
++ 
++             # Write binary string to file
++-            with open(fpath, 'wb') as f:
+++            f = open(fpath, 'wb')
+++            if 1:
++                 f.write(sizes[k][1])
++ 
+++            f.close()
++         server = mozhttpd.MozHttpd(docroot=tempdir)
++         server.start()
++         server_url = server.get_url()
++diff -up comm-esr31/mozilla/testing/mozbase/mozhttpd/tests/paths.py.python3 comm-esr31/mozilla/testing/mozbase/mozhttpd/tests/paths.py
++--- comm-esr31/mozilla/testing/mozbase/mozhttpd/tests/paths.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozhttpd/tests/paths.py	2014-10-24 11:41:35.519879973 -0600
++@@ -16,13 +16,16 @@ class PathTest(unittest.TestCase):
++         self.assertEqual(f.read(), expected_contents)
++ 
++     def try_get_expect_404(self, url):
++-        with self.assertRaises(urllib2.HTTPError) as cm:
+++        cm = self.assertRaises(urllib2.HTTPError).__enter__()
+++        if 1:
++             urllib2.urlopen(url)
+++        cm.__exit__(0, 0, 0)
++         self.assertEqual(404, cm.exception.code)
++ 
++     def test_basic(self):
++         """Test that requests to docroot and a path mapping work as expected."""
++-        with TemporaryDirectory() as d1, TemporaryDirectory() as d2:
+++        d1, TemporaryDirectory() = d2 = TemporaryDirectory().__enter__()
+++        if 1:
++             open(os.path.join(d1, "test1.txt"), "w").write("test 1 contents")
++             open(os.path.join(d2, "test2.txt"), "w").write("test 2 contents")
++             httpd = mozhttpd.MozHttpd(port=0,
++@@ -35,9 +38,11 @@ class PathTest(unittest.TestCase):
++             self.try_get_expect_404(httpd.get_url("/files/test2_nope.txt"))
++             httpd.stop()
++ 
+++        d2.__exit__(0, 0, 0)
++     def test_substring_mappings(self):
++         """Test that a path mapping that's a substring of another works."""
++-        with TemporaryDirectory() as d1, TemporaryDirectory() as d2:
+++        d1, TemporaryDirectory() = d2 = TemporaryDirectory().__enter__()
+++        if 1:
++             open(os.path.join(d1, "test1.txt"), "w").write("test 1 contents")
++             open(os.path.join(d2, "test2.txt"), "w").write("test 2 contents")
++             httpd = mozhttpd.MozHttpd(port=0,
++@@ -49,9 +54,11 @@ class PathTest(unittest.TestCase):
++             self.try_get(httpd.get_url("/abc/test2.txt"), "test 2 contents")
++             httpd.stop()
++ 
+++        d2.__exit__(0, 0, 0)
++     def test_multipart_path_mapping(self):
++         """Test that a path mapping with multiple directories works."""
++-        with TemporaryDirectory() as d1:
+++        d1 = TemporaryDirectory().__enter__()
+++        if 1:
++             open(os.path.join(d1, "test1.txt"), "w").write("test 1 contents")
++             httpd = mozhttpd.MozHttpd(port=0,
++                                       path_mappings={'/abc/def/ghi': d1}
++@@ -62,14 +69,17 @@ class PathTest(unittest.TestCase):
++             self.try_get_expect_404(httpd.get_url("/abc/def/test1.txt"))
++             httpd.stop()
++ 
+++        d1.__exit__(0, 0, 0)
++     def test_no_docroot(self):
++         """Test that path mappings with no docroot work."""
++-        with TemporaryDirectory() as d1:
+++        d1 = TemporaryDirectory().__enter__()
+++        if 1:
++             httpd = mozhttpd.MozHttpd(port=0,
++                                       path_mappings={'/foo': d1})
++             httpd.start(block=False)
++             self.try_get_expect_404(httpd.get_url())
++             httpd.stop()
++ 
+++        d1.__exit__(0, 0, 0)
++ if __name__ == '__main__':
++     unittest.main()
++diff -up comm-esr31/mozilla/testing/mozbase/mozinfo/tests/test.py.python3 comm-esr31/mozilla/testing/mozbase/mozinfo/tests/test.py
++--- comm-esr31/mozilla/testing/mozbase/mozinfo/tests/test.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozinfo/tests/test.py	2014-10-24 11:41:35.519879973 -0600
++@@ -41,24 +41,30 @@ class TestMozinfo(unittest.TestCase):
++     def test_update_file(self):
++         """Test that mozinfo.update can load a JSON file."""
++         j = os.path.join(self.tempdir, "mozinfo.json")
++-        with open(j, "w") as f:
+++        f = open(j, "w")
+++        if 1:
++             f.write(json.dumps({"foo": "xyz"}))
+++        f.__exit__(0, 0, 0)
++         mozinfo.update(j)
++         self.assertEqual(mozinfo.info["foo"], "xyz")
++ 
++     def test_update_file_invalid_json(self):
++         """Test that mozinfo.update handles invalid JSON correctly"""
++         j = os.path.join(self.tempdir,'test.json')
++-        with open(j, 'w') as f:
+++        f = open(j, 'w')
+++        if 1:
++             f.write('invalid{"json":')
+++        f.__exit__(0, 0, 0)
++         self.assertRaises(ValueError,mozinfo.update,[j])
++ 
++     def test_find_and_update_file(self):
++         """Test that mozinfo.find_and_update_from_json can
++         find mozinfo.json in a directory passed to it."""
++         j = os.path.join(self.tempdir, "mozinfo.json")
++-        with open(j, "w") as f:
+++        f = open(j, "w").__enter__()
+++        if 1:
++             f.write(json.dumps({"foo": "abcdefg"}))
+++        f.__exit__(0, 0, 0)
++         self.assertEqual(mozinfo.find_and_update_from_json(self.tempdir), j)
++         self.assertEqual(mozinfo.info["foo"], "abcdefg")
++ 
++@@ -66,8 +72,10 @@ class TestMozinfo(unittest.TestCase):
++         """Test that mozinfo.find_and_update_from_json can
++         handle invalid JSON"""
++         j = os.path.join(self.tempdir, "mozinfo.json")
++-        with open(j, 'w') as f:
+++        f = open(j, 'w').__enter__()
+++        if 1:
++             f.write('invalid{"json":')
+++        f.close()
++         self.assertRaises(ValueError, mozinfo.find_and_update_from_json, self.tempdir)
++ 
++ 
++@@ -75,13 +83,17 @@ class TestMozinfo(unittest.TestCase):
++         """Test that mozinfo.find_and_update_from_json can
++         find mozinfo.json using the mozbuild module."""
++         j = os.path.join(self.tempdir, "mozinfo.json")
++-        with open(j, "w") as f:
+++        f = open(j, "w").__enter__()
+++        if 1:
++             f.write(json.dumps({"foo": "123456"}))
+++        f.close()
++         m = mock.MagicMock()
++         # Mock the value of MozbuildObject.from_environment().topobjdir.
++         m.MozbuildObject.from_environment.return_value.topobjdir = self.tempdir
++-        with mock.patch.dict(sys.modules, {"mozbuild": m, "mozbuild.base": m}):
+++        mock.patch.dict(sys.modules, {"mozbuild": m, "mozbuild.base": m}).__enter__()
+++        if 1:
++             self.assertEqual(mozinfo.find_and_update_from_json(), j)
+++        mock.patch.dict(sys.modules, {"mozbuild": m, "mozbuild.base": m}).__exit__(0, 0, 0)
++         self.assertEqual(mozinfo.info["foo"], "123456")
++ 
++ if __name__ == '__main__':
++diff -up comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/logger.py.python3 comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/logger.py
++--- comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/logger.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/logger.py	2014-10-24 11:41:35.520879968 -0600
++@@ -72,8 +72,7 @@ class MozLogger(_LoggerClass):
++ 
++             # If the logger is fed a level number unknown to the logging
++             # module, getLevelName will return a string. Unfortunately,
++-            # the logging module will raise a type error elsewhere if
++-            # the level is not an integer.
+++            # the logging module will raise a type error elsewhere if # the level is not an integer.
++             if not isinstance(level, int):
++                 level = _default_level
++ 
++diff -up comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/structured/formatters/html/html.py.python3 comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/structured/formatters/html/html.py
++--- comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/structured/formatters/html/html.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/structured/formatters/html/html.py	2014-10-24 11:41:35.520879968 -0600
++@@ -38,12 +38,14 @@ class HTMLFormatter(base.BaseFormatter):
++     def suite_start(self, data):
++         self.suite_times["start"] = data["time"]
++         self.suite_name = data["source"]
++-        with open(os.path.join(base_path, "style.css")) as f:
+++        f = open(os.path.join(base_path, "style.css"))
+++        if 1:
++             self.head = html.head(
++                 html.meta(charset="utf-8"),
++                 html.title(data["source"]),
++                 html.style(raw(f.read())))
++ 
+++        f.close()
++     def suite_end(self, data):
++         self.suite_times["end"] = data["time"]
++         return self.generate_html()
++@@ -123,7 +125,8 @@ class HTMLFormatter(base.BaseFormatter):
++ 
++     def generate_html(self):
++         generated = datetime.datetime.now()
++-        with open(os.path.join(base_path, "main.js")) as main_f:
+++        main_f = open(os.path.join(base_path, "main.js"))
+++        if 1:
++             doc = html.html(
++                 self.head,
++                 html.body(
++@@ -157,6 +160,7 @@ class HTMLFormatter(base.BaseFormatter):
++                             html.th('Links')]), id='results-table-head'),
++                         html.tbody(self.result_rows, id='results-table-body')], id='results-table'))))
++ 
+++        main_f.close()
++         return doc.unicode(indent=2)
++ 
++ 
++diff -up comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/structured/formatters/machformatter.py.python3 comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/structured/formatters/machformatter.py
++--- comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/structured/formatters/machformatter.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/structured/formatters/machformatter.py	2014-10-24 11:41:35.520879968 -0600
++@@ -53,7 +53,11 @@ class BaseMachFormatter(base.BaseFormatt
++             expected_str = ""
++ 
++         subtests = self._get_subtest_data(data)
++-        unexpected = subtests["unexpected"] + (1 if "expected" in data else 0)
+++        unexpected = None
+++        if "expected" in data:
+++          unexpected = subtests["unexpected"] + (1
+++        else:
+++          unexpected = 0)
++ 
++         return "Harness status %s%s. Subtests passed %i/%i. Unexpected %i" % (
++             data["status"], expected_str, subtests["pass"],
++diff -up comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/structured/handlers/__init__.py.python3 comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/structured/handlers/__init__.py
++--- comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/structured/handlers/__init__.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/structured/handlers/__init__.py	2014-10-24 11:41:35.520879968 -0600
++@@ -60,10 +60,13 @@ class StreamHandler(BaseHandler):
++         formatted = self.formatter(data)
++         if not formatted:
++             return
++-        with self._lock:
+++        self._lock.__enter__()
+++        if 1:
++             #XXX Should encoding be the formatter's responsibility?
++             try:
++                 self.stream.write(formatted.encode("utf8"))
++             except:
++                 raise
++             self.stream.flush()
+++        self._lock.__exit__(0, 0, 0)
+++
++diff -up comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/structured/structuredlog.py.python3 comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/structured/structuredlog.py
++--- comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/structured/structuredlog.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozlog/mozlog/structured/structuredlog.py	2014-10-24 11:41:35.520879968 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import sys
++ from collections import defaultdict
++@@ -90,11 +90,13 @@ class StructuredLogger(object):
++     def _log_data(self, action, data=None):
++         if data is None:
++             data = {}
++-        with self._lock:
+++        self._lock.__enter__()
+++        if 1:
++             log_data = self._make_log_data(action, data)
++             for handler in self.handlers:
++                 handler(log_data)
++ 
+++        self._lock.__exit__(0, 0, 0)
++     def _make_log_data(self, action, data):
++         all_data = {"action": action,
++                     "time": int(time.time() * 1000),
++diff -up comm-esr31/mozilla/testing/mozbase/moznetwork/moznetwork/moznetwork.py.python3 comm-esr31/mozilla/testing/mozbase/moznetwork/moznetwork/moznetwork.py
++--- comm-esr31/mozilla/testing/mozbase/moznetwork/moznetwork/moznetwork.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/moznetwork/moznetwork/moznetwork.py	2014-10-24 11:41:35.521879964 -0600
++@@ -22,7 +22,11 @@ def _get_interface_list():
++     max_iface = 32  # Maximum number of interfaces(Aribtrary)
++     bytes = max_iface * 32
++     is_32bit = (8 * struct.calcsize("P")) == 32  # Set Architecture
++-    struct_size = 32 if is_32bit else 40
+++    struct_size = None
+++    if is_32bit:
+++      struct_size = 32
+++    else:
+++      struct_size = 40
++ 
++     try:
++         s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
++diff -up comm-esr31/mozilla/testing/mozbase/moznetwork/tests/test.py.python3 comm-esr31/mozilla/testing/mozbase/moznetwork/tests/test.py
++--- comm-esr31/mozilla/testing/mozbase/moznetwork/tests/test.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/moznetwork/tests/test.py	2014-10-24 11:41:35.521879964 -0600
++@@ -64,7 +64,8 @@ class TestGetIP(unittest.TestCase):
++ 
++         if mozinfo.isLinux or mozinfo.isMac:
++ 
++-            with mock.patch('socket.gethostbyname') as byname:
+++            byname = mock.patch('socket.gethostbyname').__enter__()
+++            if 1:
++                 # Force socket.gethostbyname to return None
++                 byname.return_value = None
++ 
++@@ -74,5 +75,6 @@ class TestGetIP(unittest.TestCase):
++                 self.assertTrue(verify_ip_in_list(ip))
++ 
++ 
+++            byname.__exit__(0, 0, 0)
++ if __name__ == '__main__':
++     unittest.main()
++diff -up comm-esr31/mozilla/testing/mozbase/mozprocess/tests/test_mozprocess_params.py.python3 comm-esr31/mozilla/testing/mozbase/mozprocess/tests/test_mozprocess_params.py
++--- comm-esr31/mozilla/testing/mozbase/mozprocess/tests/test_mozprocess_params.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozprocess/tests/test_mozprocess_params.py	2014-10-24 11:41:35.521879964 -0600
++@@ -17,7 +17,7 @@ class ParamTests(unittest.TestCase):
++         err = None
++         try:
++             p = processhandler.ProcessHandler(['ls','-l'], processOutputLine=output)
++-        except (TypeError, AttributeError) as e:
+++        except (TypeError, AttributeError), e:
++             err = e
++         self.assertFalse(err)
++ 
++@@ -28,7 +28,7 @@ class ParamTests(unittest.TestCase):
++         err = None
++         try:
++             p = processhandler.ProcessHandler(['ls','-l'], processOutputLine=[output])
++-        except (TypeError, AttributeError) as e:
+++        except (TypeError, AttributeError), e:
++             err = e
++         self.assertFalse(err)
++ 
++@@ -40,7 +40,7 @@ class ParamTests(unittest.TestCase):
++         err = None
++         try:
++             p = processhandler.ProcessHandler(['sleep', '2'], onTimeout=timeout)
++-        except (TypeError, AttributeError) as e:
+++        except (TypeError, AttributeError), e:
++             err = e
++         self.assertFalse(err)
++ 
++@@ -51,7 +51,7 @@ class ParamTests(unittest.TestCase):
++         err = None
++         try:
++             p = processhandler.ProcessHandler(['sleep', '2'], onTimeout=[timeout])
++-        except (TypeError, AttributeError) as e:
+++        except (TypeError, AttributeError), e:
++             err = e
++         self.assertFalse(err)
++ 
++@@ -62,7 +62,7 @@ class ParamTests(unittest.TestCase):
++         err = None
++         try:
++             p = processhandler.ProcessHandler(['sleep', '1'], onFinish=finish)
++-        except (TypeError, AttributeError) as e:
+++        except (TypeError, AttributeError), e:
++             err = e
++         self.assertFalse(err)
++ 
++@@ -73,7 +73,7 @@ class ParamTests(unittest.TestCase):
++         err = None
++         try:
++             p = processhandler.ProcessHandler(['sleep', '1'], onFinish=[finish])
++-        except (TypeError, AttributeError) as e:
+++        except (TypeError, AttributeError), e:
++             err = e
++         self.assertFalse(err)
++ 
++diff -up comm-esr31/mozilla/testing/mozbase/mozprocess/tests/test_mozprocess.py.python3 comm-esr31/mozilla/testing/mozbase/mozprocess/tests/test_mozprocess.py
++--- comm-esr31/mozilla/testing/mozbase/mozprocess/tests/test_mozprocess.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozprocess/tests/test_mozprocess.py	2014-10-24 11:41:35.521879964 -0600
++@@ -117,7 +117,7 @@ class ProcTest(unittest.TestCase):
++             if os.path.exists(path):
++                 try:
++                     os.remove(path)
++-                except OSError as e:
+++                except OSError, e:
++                     errors.append(str(e))
++         if errors:
++             raise OSError("Error(s) encountered tearing down %s.%s:\n%s" % (cls.__module__, cls.__name__, '\n'.join(errors)))
++diff -up comm-esr31/mozilla/testing/mozbase/mozprofile/mozprofile/addons.py.python3 comm-esr31/mozilla/testing/mozbase/mozprofile/mozprofile/addons.py
++--- comm-esr31/mozilla/testing/mozbase/mozprofile/mozprofile/addons.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozprofile/mozprofile/addons.py	2014-10-24 11:41:35.522879960 -0600
++@@ -275,8 +275,10 @@ class AddonManager(object):
++                 finally:
++                     compressed_file.close()
++             elif os.path.isdir(addon_path):
++-                with open(os.path.join(addon_path, 'install.rdf'), 'r') as f:
+++                f = open(os.path.join(addon_path, 'install.rdf'), 'r')
+++                if 1:
++                     manifest = f.read()
+++                f.close()
++             else:
++                 raise IOError('Add-on path is neither an XPI nor a directory: %s' % addon_path)
++         except (IOError, KeyError), e:
++@@ -334,8 +336,7 @@ class AddonManager(object):
++             if not os.path.isdir(path):
++                 return
++ 
++-            addons = [os.path.join(path, x) for x in os.listdir(path) if
++-                      self.is_addon(os.path.join(path, x))]
+++            addons = [os.path.join(path, x) for x in os.listdir(path) if self.is_addon(os.path.join(path, x))]
++             addons.sort()
++ 
++         # install each addon
++diff -up comm-esr31/mozilla/testing/mozbase/mozprofile/mozprofile/profile.py.python3 comm-esr31/mozilla/testing/mozbase/mozprofile/mozprofile/profile.py
++--- comm-esr31/mozilla/testing/mozbase/mozprofile/mozprofile/profile.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozprofile/mozprofile/profile.py	2014-10-24 11:41:35.522879960 -0600
++@@ -206,8 +206,10 @@ class Profile(object):
++         """
++ 
++         path = os.path.join(self.profile, filename)
++-        with file(path) as f:
+++        f = file(path).__enter__()
+++        if 1:
++             lines = f.read().splitlines()
+++        f.__exit__(0, 0, 0)
++         def last_index(_list, value):
++             """
++             returns the last index of an item;
++@@ -231,8 +233,10 @@ class Profile(object):
++ 
++         # write the prefs
++         cleaned_prefs = '\n'.join(lines[:s] + lines[e+1:])
++-        with file(path, 'w') as f:
+++        f = file(path, 'w').__enter__()
+++        if 1:
++             f.write(cleaned_prefs)
+++        f.__exit__(0, 0, 0)
++         return True
++ 
++     ### methods for introspection
++diff -up comm-esr31/mozilla/testing/mozbase/mozprofile/tests/addon_stubs.py.python3 comm-esr31/mozilla/testing/mozbase/mozprofile/tests/addon_stubs.py
++--- comm-esr31/mozilla/testing/mozbase/mozprofile/tests/addon_stubs.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozprofile/tests/addon_stubs.py	2014-10-24 11:41:35.522879960 -0600
++@@ -49,18 +49,22 @@ def generate_addon(addon_id, path=None,
++     # Write install.rdf for addon
++     if stubs[addon_id]:
++         install_rdf = os.path.join(addon_dir, 'install.rdf')
++-        with open(install_rdf, 'w') as f:
+++        f = open(install_rdf, 'w')
+++        if 1:
++             manifest = os.path.join(here, 'install_manifests', stubs[addon_id])
++             f.write(open(manifest, 'r').read())
++ 
+++        f.close()
++     if not xpi:
++         return addon_dir
++ 
++     # Generate the .xpi for the addon
++     xpi_file = os.path.join(tmpdir, (name or addon_id) + '.xpi')
++-    with zipfile.ZipFile(xpi_file, 'w') as x:
+++    x = zipfile.ZipFile(xpi_file, 'w').__enter__()
+++    if 1:
++         x.write(install_rdf, install_rdf[len(addon_dir):])
++ 
+++    x.__exit__(0, 0, 0)
++     # Ensure we remove the temporary folder to not install the addon twice
++     mozfile.rmtree(addon_dir)
++ 
++@@ -72,8 +76,10 @@ def generate_manifest(addon_list, path=N
++     addons = [generate_addon(addon, path=tmpdir) for addon in addon_list]
++ 
++     manifest = os.path.join(tmpdir, 'manifest.ini')
++-    with open(manifest, 'w') as f:
+++    f = open(manifest, 'w')
+++    if 1:
++         for addon in addons:
++             f.write('[' + addon + ']\n')
++ 
+++    f.close()
++     return manifest
++diff -up comm-esr31/mozilla/testing/mozbase/mozprofile/tests/permissions.py.python3 comm-esr31/mozilla/testing/mozbase/mozprofile/tests/permissions.py
++--- comm-esr31/mozilla/testing/mozbase/mozprofile/tests/permissions.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozprofile/tests/permissions.py	2014-10-24 11:41:35.522879960 -0600
++@@ -149,7 +149,11 @@ http://127.0.0.1:8888           privileg
++ 
++         self.assertEqual(len(entries), 3)
++ 
++-        columns = 8 if version == 3 else 6
+++        columns = None
+++        if version == 3:
+++          columns = 8
+++        else:
+++          columns = 6
++         self.assertEqual(len(entries[0]), columns)
++         for x in range(4, columns):
++             self.assertEqual(entries[0][x], 0)
++diff -up comm-esr31/mozilla/testing/mozbase/mozprofile/tests/test_addons.py.python3 comm-esr31/mozilla/testing/mozbase/mozprofile/tests/test_addons.py
++--- comm-esr31/mozilla/testing/mozbase/mozprofile/tests/test_addons.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozprofile/tests/test_addons.py	2014-10-24 11:41:35.522879960 -0600
++@@ -64,8 +64,7 @@ class TestAddonsManager(unittest.TestCas
++         self.assertEqual(self.am.installed_addons, [addon_xpi])
++         self.am.clean()
++ 
++-        # Even if it is the same id the add-on should be installed twice, if
++-        # specified via XPI and folder
+++        # Even if it is the same id the add-on should be installed twice, if # specified via XPI and folder
++         self.am.install_addons([addon_folder, addon_xpi])
++         self.assertEqual(len(self.am.installed_addons), 2)
++         self.assertIn(addon_folder, self.am.installed_addons)
++diff -up comm-esr31/mozilla/testing/mozbase/mozprofile/tests/test_preferences.py.python3 comm-esr31/mozilla/testing/mozbase/mozprofile/tests/test_preferences.py
++--- comm-esr31/mozilla/testing/mozbase/mozprofile/tests/test_preferences.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozprofile/tests/test_preferences.py	2014-10-24 11:41:35.523879956 -0600
++@@ -241,10 +241,12 @@ user_pref("webgl.force-enabled", true);
++         path = None
++         read_prefs = None
++         try:
++-            with mozfile.NamedTemporaryFile(suffix='.js', delete=False) as f:
+++            f = mozfile.NamedTemporaryFile(suffix='.js', delete=False).__enter__()
+++            if 1:
++                 path = f.name
++                 preferences.write(f, _prefs)
++ 
+++            f.__exit__(0, 0, 0)
++             # read them back and ensure we get what we put in
++             read_prefs = dict(Preferences.read_prefs(path))
++ 
++diff -up comm-esr31/mozilla/testing/mozbase/mozrunner/mozrunner/base.py.python3 comm-esr31/mozilla/testing/mozbase/mozrunner/mozrunner/base.py
++--- comm-esr31/mozilla/testing/mozbase/mozrunner/mozrunner/base.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozrunner/mozrunner/base.py	2014-10-24 11:41:35.523879956 -0600
++@@ -11,7 +11,7 @@ from mozprocess.processhandler import Pr
++ import mozcrash
++ import mozlog
++ 
++-from .errors import RunnerNotStartedError
+++from errors import RunnerNotStartedError
++ 
++ 
++ # we can replace these methods with 'abc'
++@@ -99,8 +99,7 @@ class Runner(object):
++ 
++         :param timeout: if not None, will return after timeout seconds.
++                         Use is_running() to determine whether or not a
++-                        timeout occured. Timeout is ignored if
++-                        interactive was set to True.
+++                        timeout occured. Timeout is ignored if interactive was set to True.
++ 
++         """
++         if self.is_running():
++diff -up comm-esr31/mozilla/testing/mozbase/mozrunner/mozrunner/__init__.py.python3 comm-esr31/mozilla/testing/mozbase/mozrunner/mozrunner/__init__.py
++--- comm-esr31/mozilla/testing/mozbase/mozrunner/mozrunner/__init__.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozrunner/mozrunner/__init__.py	2014-10-24 11:41:35.523879956 -0600
++@@ -2,10 +2,10 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this file,
++ # You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from .errors import *
++-from .local import *
++-from .local import LocalRunner as Runner
++-from .remote import *
+++from errors import *
+++from local import *
+++from local import LocalRunner as Runner
+++from remote import *
++ 
++ runners = local_runners
++ runners.update(remote_runners)
++diff -up comm-esr31/mozilla/testing/mozbase/mozrunner/mozrunner/local.py.python3 comm-esr31/mozilla/testing/mozbase/mozrunner/mozrunner/local.py
++--- comm-esr31/mozilla/testing/mozbase/mozrunner/mozrunner/local.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozrunner/mozrunner/local.py	2014-10-24 11:41:35.523879956 -0600
++@@ -17,8 +17,8 @@ if mozinfo.isMac:
++ 
++ from mozprofile import Profile, FirefoxProfile, MetroFirefoxProfile, ThunderbirdProfile, MozProfileCLI
++ 
++-from .base import Runner
++-from .utils import findInPath, get_metadata_from_egg
+++from base import Runner
+++from utils import findInPath, get_metadata_from_egg
++ 
++ 
++ __all__ = ['CLI',
++diff -up comm-esr31/mozilla/testing/mozbase/mozrunner/mozrunner/remote.py.python3 comm-esr31/mozilla/testing/mozbase/mozrunner/mozrunner/remote.py
++--- comm-esr31/mozilla/testing/mozbase/mozrunner/mozrunner/remote.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozrunner/mozrunner/remote.py	2014-10-24 11:41:35.523879956 -0600
++@@ -17,7 +17,7 @@ from mozdevice import DMError
++ import mozfile
++ import mozlog
++ 
++-from .base import Runner
+++from base import Runner
++ 
++ 
++ __all__ = ['B2GRunner',
++diff -up comm-esr31/mozilla/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py.python3 comm-esr31/mozilla/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py
++--- comm-esr31/mozilla/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py	2014-10-24 11:41:35.524879951 -0600
++@@ -12,12 +12,12 @@ try:
++ except Exception:
++     psutil = None
++ 
++-from collections import (
+++from mycollections import (
++     OrderedDict,
++     namedtuple,
++ )
++ 
++-from contextlib import contextmanager
+++
++ 
++ 
++ def _collect(pipe, poll_interval):
++@@ -126,9 +126,11 @@ class SystemResourceMonitor(object):
++     monitor.record_event('foo_did_stuff')
++ 
++     # Record that we're about to perform a possibly long-running event.
++-    with monitor.phase('long_job'):
+++    monitor.phase('long_job').__enter__()
+++    if 1:
++         foo.do_long_running_job()
++ 
+++    monitor.phase('long_job').__exit__(0, 0, 0)
++     # Stop recording. Currently we need to stop before data is available.
++     monitor.stop()
++ 
++diff -up comm-esr31/mozilla/testing/mozbase/mozsystemmonitor/mozsystemmonitor/test/test_resource_monitor.py.python3 comm-esr31/mozilla/testing/mozbase/mozsystemmonitor/mozsystemmonitor/test/test_resource_monitor.py
++--- comm-esr31/mozilla/testing/mozbase/mozsystemmonitor/mozsystemmonitor/test/test_resource_monitor.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozsystemmonitor/mozsystemmonitor/test/test_resource_monitor.py	2014-10-24 11:41:35.524879951 -0600
++@@ -47,12 +47,14 @@ class TestResourceMonitor(unittest.TestC
++         monitor.start()
++         time.sleep(1)
++ 
++-        with monitor.phase('phase1'):
+++        monitor.phase('phase1').__enter__()
+++        if 1:
++             time.sleep(1)
++ 
++             with monitor.phase('phase2'):
++                 time.sleep(1)
++ 
+++        monitor.phase('phase1').__exit__(0, 0, 0)
++         monitor.stop()
++ 
++         self.assertEqual(len(monitor.phases), 2)
++diff -up comm-esr31/mozilla/testing/mozbase/moztest/moztest/output/base.py.python3 comm-esr31/mozilla/testing/mozbase/moztest/moztest/output/base.py
++--- comm-esr31/mozilla/testing/mozbase/moztest/moztest/output/base.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/moztest/moztest/output/base.py	2014-10-24 11:41:35.524879951 -0600
++@@ -3,7 +3,7 @@
++ # You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++ 
++-from __future__ import with_statement
+++
++ from contextlib import closing
++ from StringIO import StringIO
++ 
++@@ -30,11 +30,13 @@ class Output(object):
++ 
++     def dump_string(self, results_collection):
++         """ Returns the string representation of the results collection """
++-        with closing(StringIO()) as s:
+++        s = closing(StringIO()).__enter__()
+++        if 1:
++             self.serialize(results_collection, s)
++             return s.getvalue()
++ 
++ 
+++        s.__exit__(0, 0, 0)
++ # helper functions
++ def count(iterable):
++     """ Return the count of an iterable. Useful for generators. """
++diff -up comm-esr31/mozilla/testing/mozbase/moztest/moztest/results.py.python3 comm-esr31/mozilla/testing/mozbase/moztest/moztest/results.py
++--- comm-esr31/mozilla/testing/mozbase/moztest/moztest/results.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/moztest/moztest/results.py	2014-10-24 11:41:35.524879951 -0600
++@@ -90,7 +90,11 @@ class TestResult(object):
++         self.name = name
++         self.test_class = test_class
++         self.context = context
++-        self.time_start = time_start if time_start is not None else time.time()
+++        self.time_start = None
+++        if time_start is not None:
+++          self.time_start = time_start
+++        else:
+++          self.time_start = time.time()
++         self.time_end = None
++         self._result_expected = result_expected
++         self._result_actual = None
++@@ -173,7 +177,11 @@ class TestResult(object):
++         if isinstance(output, basestring):
++             output = output.splitlines()
++ 
++-        self.time_end = time_end if time_end is not None else time.time()
+++        self.time_end = None
+++        if time_end is not None:
+++          self.time_end = time_end
+++        else:
+++          self.time_end = time.time()
++         self.output = output or self.output
++         self.reason = reason
++ 
++diff -up comm-esr31/mozilla/testing/mozbase/mozversion/mozversion/mozversion.py.python3 comm-esr31/mozilla/testing/mozbase/mozversion/mozversion/mozversion.py
++--- comm-esr31/mozilla/testing/mozbase/mozversion/mozversion/mozversion.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozversion/mozversion/mozversion.py	2014-10-24 11:41:35.524879951 -0600
++@@ -104,8 +104,10 @@ class B2GVersion(Version):
++             gaia_commit = os.path.join(tempdir, 'gaia_commit.txt')
++             try:
++                 zip_file = zipfile.ZipFile(app_zip.name)
++-                with open(gaia_commit, 'w') as f:
+++                f = open(gaia_commit, 'w')
+++                if 1:
++                     f.write(zip_file.read('resources/gaia_commit.txt'))
+++                f.__exit__(0, 0, 0)
++             except zipfile.BadZipfile:
++                 self.info('Unable to unzip application.zip, falling back to '
++                           'system unzip')
++@@ -113,11 +115,13 @@ class B2GVersion(Version):
++                 call(['unzip', '-j', app_zip.name, 'resources/gaia_commit.txt',
++                       '-d', tempdir])
++ 
++-            with open(gaia_commit) as f:
+++            f = open(gaia_commit)
+++            if 1:
++                 changeset, date = f.read().splitlines()
++                 self._info['gaia_changeset'] = re.match(
++                     '^\w{40}$', changeset) and changeset or None
++                 self._info['gaia_date'] = date
+++            f.__exit__(0, 0, 0)
++         finally:
++             mozfile.remove(tempdir)
++ 
++@@ -141,8 +145,10 @@ class LocalB2GVersion(B2GVersion):
++             path, 'gaia', 'profile', 'webapps',
++             'settings.gaiamobile.org', 'application.zip')
++         if os.path.exists(zip_path):
++-            with open(zip_path, 'rb') as zip_file:
+++            zip_file = open(zip_path, 'rb').__enter__()
+++            if 1:
++                 self.get_gaia_info(zip_file)
+++            zip_file.__exit__(0, 0, 0)
++         else:
++             self.warn('Error pulling gaia file')
++ 
++@@ -170,18 +176,22 @@ class RemoteB2GVersion(B2GVersion):
++ 
++         tempdir = tempfile.mkdtemp()
++         for ini in ('application', 'platform'):
++-            with open(os.path.join(tempdir, '%s.ini' % ini), 'w') as f:
+++            f = open(os.path.join(tempdir, '%s.ini' % ini), 'w').__enter__()
+++            if 1:
++                 f.write(dm.pullFile('/system/b2g/%s.ini' % ini))
++                 f.flush()
+++            f.close()
++         self.get_gecko_info(tempdir)
++         mozfile.remove(tempdir)
++ 
++         for path in ['/system/b2g', '/data/local']:
++             path += '/webapps/settings.gaiamobile.org/application.zip'
++             if dm.fileExists(path):
++-                with tempfile.NamedTemporaryFile() as f:
+++                f = tempfile.NamedTemporaryFile().__enter__()
+++                if 1:
++                     dm.getFile(path, f.name)
++                     self.get_gaia_info(f)
+++                f.close()
++                 break
++         else:
++             self.warn('Error pulling gaia file')
++diff -up comm-esr31/mozilla/testing/mozbase/mozversion/tests/test_b2g.py.python3 comm-esr31/mozilla/testing/mozbase/mozversion/tests/test_b2g.py
++--- comm-esr31/mozilla/testing/mozbase/mozversion/tests/test_b2g.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozversion/tests/test_b2g.py	2014-10-24 11:41:35.525879947 -0600
++@@ -20,12 +20,16 @@ class SourcesTest(unittest.TestCase):
++         self.tempdir = tempfile.mkdtemp()
++ 
++         self.binary = os.path.join(self.tempdir, 'binary')
++-        with open(self.binary, 'w') as f:
+++        f = open(self.binary, 'w')
+++        if 1:
++             f.write('foobar')
++ 
++-        with open(os.path.join(self.tempdir, 'application.ini'), 'w') as f:
+++        f.__exit__(0, 0, 0)
+++        f = open(os.path.join(self.tempdir, 'application.ini'), 'w').__enter__()
+++        if 1:
++             f.writelines("""[App]\nName = B2G\n""")
++ 
+++        f.close()
++     def tearDown(self):
++         mozfile.remove(self.tempdir)
++ 
++diff -up comm-esr31/mozilla/testing/mozbase/mozversion/tests/test_binary.py.python3 comm-esr31/mozilla/testing/mozbase/mozversion/tests/test_binary.py
++--- comm-esr31/mozilla/testing/mozbase/mozversion/tests/test_binary.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozversion/tests/test_binary.py	2014-10-24 11:41:35.525879947 -0600
++@@ -34,28 +34,38 @@ SourceRepository = PlatformSourceRepo
++         self.tempdir = tempfile.mkdtemp()
++ 
++         self.binary = os.path.join(self.tempdir, 'binary')
++-        with open(self.binary, 'w') as f:
+++        f = open(self.binary, 'w')
+++        if 1:
++             f.write('foobar')
++ 
+++        f.__exit__(0, 0, 0)
++     def tearDown(self):
++         os.chdir(self.cwd)
++         mozfile.remove(self.tempdir)
++ 
++     def test_binary(self):
++-        with open(os.path.join(self.tempdir, 'application.ini'), 'w') as f:
+++        f = open(os.path.join(self.tempdir, 'application.ini'), 'w')
+++        if 1:
++             f.writelines(self.application_ini)
++ 
++-        with open(os.path.join(self.tempdir, 'platform.ini'), 'w') as f:
+++        f.__exit__(0, 0, 0)
+++        f = open(os.path.join(self.tempdir, 'platform.ini'), 'w').__enter__()
+++        if 1:
++             f.writelines(self.platform_ini)
++ 
+++        f.__exit__(0, 0, 0)
++         self._check_version(get_version(self.binary))
++ 
++     def test_binary_in_current_path(self):
++-        with open(os.path.join(self.tempdir, 'application.ini'), 'w') as f:
+++        f = open(os.path.join(self.tempdir, 'application.ini'), 'w').__enter__()
+++        if 1:
++             f.writelines(self.application_ini)
++ 
++-        with open(os.path.join(self.tempdir, 'platform.ini'), 'w') as f:
+++        f.close()
+++        f = open(os.path.join(self.tempdir, 'platform.ini'), 'w').__enter__()
+++        if 1:
++             f.writelines(self.platform_ini)
+++        f.close()
++         os.chdir(self.tempdir)
++         self._check_version(get_version())
++ 
++diff -up comm-esr31/mozilla/testing/mozbase/mozversion/tests/test_sources.py.python3 comm-esr31/mozilla/testing/mozbase/mozversion/tests/test_sources.py
++--- comm-esr31/mozilla/testing/mozbase/mozversion/tests/test_sources.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/mozversion/tests/test_sources.py	2014-10-24 11:41:35.525879947 -0600
++@@ -28,31 +28,41 @@ class SourcesTest(unittest.TestCase):
++         self.tempdir = tempfile.mkdtemp()
++ 
++         self.binary = os.path.join(self.tempdir, 'binary')
++-        with open(self.binary, 'w') as f:
+++        f = open(self.binary, 'w')
+++        if 1:
++             f.write('foobar')
++ 
+++        f.__exit__(0, 0, 0)
++     def tearDown(self):
++         os.chdir(self.cwd)
++         mozfile.remove(self.tempdir)
++ 
++     def test_sources(self):
++-        with open(os.path.join(self.tempdir, 'application.ini'), 'w') as f:
+++        f = open(os.path.join(self.tempdir, 'application.ini'), 'w')
+++        if 1:
++             f.writelines(self.application_ini)
++ 
+++        f.__exit__(0, 0, 0)
++         sources = os.path.join(self.tempdir, 'sources.xml')
++-        with open(sources, 'w') as f:
+++        f = open(sources, 'w').__enter__()
+++        if 1:
++             f.writelines(self.sources_xml)
++ 
+++        f.__exit__(0, 0, 0)
++         os.chdir(self.tempdir)
++         self._check_version(get_version(sources=sources))
++ 
++     def test_sources_in_current_directory(self):
++-        with open(os.path.join(self.tempdir, 'application.ini'), 'w') as f:
+++        f = open(os.path.join(self.tempdir, 'application.ini'), 'w').__enter__()
+++        if 1:
++             f.writelines(self.application_ini)
++ 
++-        with open(os.path.join(self.tempdir, 'sources.xml'), 'w') as f:
+++        f.close()
+++        f = open(os.path.join(self.tempdir, 'sources.xml'), 'w').__enter__()
+++        if 1:
++             f.writelines(self.sources_xml)
++ 
+++        f.close()
++         os.chdir(self.tempdir)
++         self._check_version(get_version())
++ 
++diff -up comm-esr31/mozilla/testing/mozbase/test.py.python3 comm-esr31/mozilla/testing/mozbase/test.py
++--- comm-esr31/mozilla/testing/mozbase/test.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/mozbase/test.py	2014-10-24 11:41:35.525879947 -0600
++@@ -90,7 +90,7 @@ def main(args=sys.argv[1:]):
++     results = TestResultCollection.from_unittest_results(None, unittest_results)
++ 
++     # exit according to results
++-    sys.exit(1 if results.num_failures else 0)
+++    sys.exit(0, 1)[results.num_failures]
++ 
++ if __name__ == '__main__':
++     main()
++diff -up comm-esr31/mozilla/testing/remotecppunittests.py.python3 comm-esr31/mozilla/testing/remotecppunittests.py
++--- comm-esr31/mozilla/testing/remotecppunittests.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/remotecppunittests.py	2014-10-24 11:41:35.525879947 -0600
++@@ -53,7 +53,8 @@ class RemoteCPPUnitTests(cppunittests.CP
++ 
++     def push_libs(self):
++         if self.options.local_apk:
++-            with mozfile.TemporaryDirectory() as tmpdir:
+++            tmpdir = mozfile.TemporaryDirectory().__enter__()
+++            if 1:
++                 apk_contents = ZipFile(self.options.local_apk)
++                 szip = os.path.join(self.options.local_bin, '..', 'host', 'bin', 'szip')
++                 if not os.path.exists(szip):
++@@ -73,6 +74,7 @@ class RemoteCPPUnitTests(cppunittests.CP
++                         if szip:
++                             out = subprocess.check_output([szip, '-d', file], stderr=subprocess.STDOUT)
++                         self.device.pushFile(os.path.join(tmpdir, info.filename), remote_file)
+++            tmpdir.__exit__(0, 0, 0)
++             return
++ 
++         for file in os.listdir(self.options.local_lib):
++@@ -132,12 +134,14 @@ class RemoteCPPUnitTests(cppunittests.CP
++         returncode = self.device.shell([remote_bin], buf, env=env, cwd=self.remote_home_dir,
++                                        timeout=cppunittests.CPPUnitTests.TEST_PROC_TIMEOUT)
++         print >> sys.stdout, buf.getvalue()
++-        with mozfile.TemporaryDirectory() as tempdir:
+++        tempdir = mozfile.TemporaryDirectory().__enter__()
+++        if 1:
++             self.device.getDirectory(self.remote_home_dir, tempdir)
++             if mozcrash.check_for_crashes(tempdir, symbols_path,
++                                           test_name=basename):
++                 log.testFail("%s | test crashed", basename)
++                 return False
+++        tempdir.__exit__(0, 0, 0)
++         result = returncode == 0
++         if not result:
++             log.testFail("%s | test failed with return code %s",
++@@ -182,7 +186,7 @@ class RemoteCPPUnittestOptions(cppunitte
++         self.add_option("--localBinDir", action="store",
++                         type = "string", dest = "local_bin",
++                         help = "local path to bin directory")
++-        defaults["local_bin"] = build_obj.bindir if build_obj is not None else None
+++        defaults["local_bin"] = (None, build_obj.bindir)[build_objis not None]
++ 
++         self.add_option("--remoteTestRoot", action = "store",
++                     type = "string", dest = "remote_test_root",
++@@ -234,7 +238,7 @@ def main():
++     except Exception, e:
++         log.error(str(e))
++         result = False
++-    sys.exit(0 if result else 1)
+++    sys.exit((1, 0)[result])
++ 
++ if __name__ == '__main__':
++     main()
++diff -up comm-esr31/mozilla/testing/runcppunittests.py.python3 comm-esr31/mozilla/testing/runcppunittests.py
++--- comm-esr31/mozilla/testing/runcppunittests.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/runcppunittests.py	2014-10-24 11:41:35.526879943 -0600
++@@ -4,11 +4,11 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import with_statement
+++
++ import sys, os, tempfile, shutil
++ from optparse import OptionParser
++ import mozprocess, mozinfo, mozlog, mozcrash, mozfile
++-from contextlib import contextmanager
+++
++ 
++ log = mozlog.getLogger('cppunittests')
++ 
++@@ -32,7 +32,8 @@ class CPPUnitTests(object):
++         """
++         basename = os.path.basename(prog)
++         log.info("Running test %s", basename)
++-        with mozfile.TemporaryDirectory() as tempdir:
+++        tempdir = mozfile.TemporaryDirectory().__enter__()
+++        if 1:
++             proc = mozprocess.ProcessHandler([prog],
++                                              cwd=tempdir,
++                                              env=env)
++@@ -55,6 +56,7 @@ class CPPUnitTests(object):
++                              basename, proc.proc.returncode)
++             return result
++ 
+++        tempdir.__exit__(0, 0, 0)
++     def build_core_environment(self, env = {}):
++         """
++         Add environment variables likely to be used across all platforms, including remote systems.
++@@ -151,13 +153,15 @@ def extract_unittests_from_args(args, ma
++ 
++     if manifest_file:
++         skipped_progs.add(os.path.basename(manifest_file))
++-        with open(manifest_file) as f:
+++        f = open(manifest_file)
+++        if 1:
++             for line in f:
++                 # strip out comment, if any
++                 prog = line.split('#')[0]
++                 if prog:
++                     skipped_progs.add(prog.strip())
++ 
+++        f.close()
++     for p in args:
++         if os.path.isdir(p):
++             progs.extend([os.path.abspath(os.path.join(p, x)) for x in os.listdir(p) if not x in skipped_progs])
++@@ -184,7 +188,7 @@ def main():
++     except Exception, e:
++         log.error(str(e))
++         result = False
++-    sys.exit(0 if result else 1)
+++    sys.exit((1, 0)[result])
++ 
++ if __name__ == '__main__':
++     main()
++diff -up comm-esr31/mozilla/testing/talos/mach_commands.py.python3 comm-esr31/mozilla/testing/talos/mach_commands.py
++--- comm-esr31/mozilla/testing/talos/mach_commands.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/talos/mach_commands.py	2014-10-24 11:41:35.526879943 -0600
++@@ -4,7 +4,11 @@
++ 
++ # Integrates Talos mozharness with mach
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ import os
++ import sys
++@@ -64,7 +68,7 @@ class TalosRunner(MozbuildObject):
++            it updates it to the latest version"""
++         try:
++             mercurial = which.which('hg')
++-        except which.WhichError as e:
+++        except which.WhichError, e:
++             print("You don't have hg in your PATH: {0}".format(e))
++             raise e
++         clone_cmd = [mercurial, 'clone', '-r', self.mozharness_rev,
++@@ -112,7 +116,7 @@ class TalosRunner(MozbuildObject):
++         try:
++             config_file = open(self.config_file_path, 'wb')
++             config_file.write(json.dumps(self.config))
++-        except IOError as e:
+++        except IOError, e:
++             err_str = "Error writing to Talos Mozharness config file {0}:{1}"
++             print(err_str.format(self.config_file_path, str(e)))
++             raise e
++@@ -145,6 +149,6 @@ class MachCommands(MachCommandBase):
++ 
++         try:
++             return talos.run_test(suite, repo, rev)
++-        except Exception as e:
+++        except Exception, e:
++             print(str(e))
++             return 1
++diff -up comm-esr31/mozilla/testing/talos/talos_from_code.py.python3 comm-esr31/mozilla/testing/talos/talos_from_code.py
++--- comm-esr31/mozilla/testing/talos/talos_from_code.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/talos/talos_from_code.py	2014-10-24 11:41:35.526879943 -0600
++@@ -103,7 +103,11 @@ def download_file(url, path="", saveAs=N
++         except Exception, e:
++             print "ERROR: %s" % str(e)
++             sys.exit(1)
++-    filename = saveAs if saveAs else get_filename_from_url(url)
+++    filename = None
+++    if saveAs:
+++      filename = saveAs
+++    else:
+++      filename = get_filename_from_url(url)
++     local_file = open(os.path.join(path, filename), 'wb')
++     local_file.write(f.read())
++     local_file.close()
++diff -up comm-esr31/mozilla/testing/tps/tps/phase.py.python3 comm-esr31/mozilla/testing/tps/tps/phase.py
++--- comm-esr31/mozilla/testing/tps/tps/phase.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/tps/tps/phase.py	2014-10-24 11:41:35.526879943 -0600
++@@ -31,7 +31,10 @@ class TPSTestPhase(object):
++ 
++     @property
++     def status(self):
++-        return self._status if self._status else 'unknown'
+++        if self._status:
+++          return self._status
+++        else:
+++          return 'unknown'
++ 
++     def run(self):
++         # launch Firefox
++diff -up comm-esr31/mozilla/testing/tps/tps/testrunner.py.python3 comm-esr31/mozilla/testing/tps/tps/testrunner.py
++--- comm-esr31/mozilla/testing/tps/tps/testrunner.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/tps/tps/testrunner.py	2014-10-24 11:41:35.527879939 -0600
++@@ -16,8 +16,8 @@ import mozinfo
++ from mozprofile import Profile
++ import mozversion
++ 
++-from .firefoxrunner import TPSFirefoxRunner
++-from .phase import TPSTestPhase
+++from firefoxrunner import TPSFirefoxRunner
+++from phase import TPSTestPhase
++ 
++ 
++ class TempFile(object):
++@@ -118,7 +118,11 @@ class TPSTestRunner(object):
++                  resultfile='tps_result.json',
++                  testfile=None):
++         self.binary = binary
++-        self.config = config if config else {}
+++        self.config = None
+++        if config:
+++          self.config = config
+++        else:
+++          self.config = {}
++         self.debug = debug
++         self.extensions = []
++         self.ignore_unused_engines = ignore_unused_engines
++@@ -149,7 +153,7 @@ class TPSTestRunner(object):
++     @mobile.setter
++     def mobile(self, value):
++         self._mobile = value
++-        self.synctype = 'desktop' if not self._mobile else 'mobile'
+++        self.synctype = ('mobile', 'desktop')[not self._mobile]
++ 
++     def log(self, msg, printToConsole=False):
++         """Appends a string to the logfile"""
++@@ -258,7 +262,8 @@ class TPSTestRunner(object):
++                         for f in files:
++                             weavelog = os.path.join(profiles[profile].profile, 'weave', 'logs', f)
++                             if os.access(weavelog, os.F_OK):
++-                                with open(weavelog, 'r') as fh:
+++                                fh = open(weavelog, 'r')
+++                                if 1:
++                                     for line in fh:
++                                         possible_time = line[0:13]
++                                         if len(possible_time) == 13 and possible_time.isdigit():
++@@ -269,17 +274,30 @@ class TPSTestRunner(object):
++                                                 formatted, time_ms % 1000, line[14:] ))
++                                         else:
++                                             self.log(line)
+++                                fh.close()
++                 break;
++ 
++         # grep the log for FF and sync versions
++         f = open(self.logfile)
++         logdata = f.read()
++         match = self.syncVerRe.search(logdata)
++-        sync_version = match.group('syncversion') if match else 'unknown'
+++        sync_version = None
+++        if match:
+++          sync_version = match.group('syncversion')
+++        else:
+++          sync_version = 'unknown'
++         match = self.ffVerRe.search(logdata)
++-        firefox_version = match.group('ffver') if match else 'unknown'
+++        firefox_version = None
+++        if match:
+++          firefox_version = match.group('ffver')
+++        else:
+++          firefox_version = 'unknown'
++         match = self.ffBuildIDRe.search(logdata)
++-        firefox_buildid = match.group('ffbuildid') if match else 'unknown'
+++        firefox_buildid = None
+++        if match:
+++          firefox_buildid = match.group('ffbuildid')
+++        else:
+++          firefox_buildid = 'unknown'
++         f.close()
++         if phase.status == 'PASS':
++             logdata = ''
++@@ -292,7 +310,11 @@ class TPSTestRunner(object):
++           'FAIL': lambda x: ('TEST-UNEXPECTED-FAIL', x.rstrip()),
++           'unknown': lambda x: ('TEST-UNEXPECTED-FAIL', 'test did not complete')
++         } [phase.status](phase.errline)
++-        logstr = "\n%s | %s%s\n" % (result[0], testname, (' | %s' % result[1] if result[1] else ''))
+++        logstr = None
+++        if result[1]:
+++          logstr = "\n%s | %s%s\n" % (result[0], testname, (' | %s' % result[1]
+++        else:
+++          logstr = ''))
++ 
++         try:
++             repoinfo = mozversion.get_version(self.binary)
++diff -up comm-esr31/mozilla/testing/xpcshell/mach_commands.py.python3 comm-esr31/mozilla/testing/xpcshell/mach_commands.py
++--- comm-esr31/mozilla/testing/xpcshell/mach_commands.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/xpcshell/mach_commands.py	2014-10-24 11:41:35.527879939 -0600
++@@ -4,7 +4,7 @@
++ 
++ # Integrates the xpcshell test runner with mach.
++ 
++-from __future__ import unicode_literals, print_function
+++, print_function
++ 
++ import mozpack.path
++ import logging
++@@ -154,8 +154,7 @@ class XPCShellRunner(MozbuildObject):
++             'debugger': debugger,
++             'debuggerArgs': debuggerArgs,
++             'debuggerInteractive': debuggerInteractive,
++-            'on_message': (lambda obj, msg: xpcshell.log.info(msg.decode('utf-8', 'replace'))) \
++-                            if verbose_output else None,
+++            'on_message': (lambda obj, msg: (None, xpcshell.log.info(msg.decode('utf-8', 'replace'))))[verbose_output],
++         }
++ 
++         if test_path is not None:
++@@ -320,8 +319,10 @@ class B2GXPCShellRunner(MozbuildObject):
++                   'initial setup will be slow.')
++             return
++ 
++-        with open(busybox_path, 'wb') as f:
+++        f = open(busybox_path, 'wb')
+++        if 1:
++             f.write(data.read())
+++        f.close()
++         return busybox_path
++ 
++     def run_test(self, test_paths, b2g_home=None, busybox=None,
++@@ -442,6 +443,6 @@ class MachCommands(MachCommandBase):
++ 
++         try:
++             return xpcshell.run_test(**params)
++-        except InvalidTestPathError as e:
+++        except InvalidTestPathError, e:
++             print(e.message)
++             return 1
++diff -up comm-esr31/mozilla/testing/xpcshell/remotexpcshelltests.py.python3 comm-esr31/mozilla/testing/xpcshell/remotexpcshelltests.py
++--- comm-esr31/mozilla/testing/xpcshell/remotexpcshelltests.py.python3	2014-07-17 18:05:51.000000000 -0600
+++++ comm-esr31/mozilla/testing/xpcshell/remotexpcshelltests.py	2014-10-24 11:41:35.527879939 -0600
++@@ -130,10 +130,11 @@ class RemoteXPCShellTestThread(xpcshell.
++         self.timedout = False
++         cmd.insert(1, self.remoteHere)
++         outputFile = "xpcshelloutput"
++-        with open(outputFile, 'w+') as f:
+++        f = open(outputFile, 'w+')
+++        if 1:
++             try:
++                 self.shellReturnCode = self.device.shell(cmd, f)
++-            except devicemanager.DMError as e:
+++            except devicemanager.DMError, e:
++                 if self.timedout:
++                     # If the test timed out, there is a good chance the SUTagent also
++                     # timed out and failed to return a return code, generating a
++@@ -142,6 +143,7 @@ class RemoteXPCShellTestThread(xpcshell.
++                     pass
++                 else:
++                     raise e
+++        f.close()
++         # The device manager may have timed out waiting for xpcshell.
++         # Guard against an accumulation of hung processes by killing
++         # them here. Note also that IPC tests may spawn new instances
++@@ -161,11 +163,13 @@ class RemoteXPCShellTestThread(xpcshell.
++             print "Automation Error: No crash directory (%s) found on remote device" % self.remoteMinidumpDir
++             # Whilst no crash was found, the run should still display as a failure
++             return True
++-        with mozfile.TemporaryDirectory() as dumpDir:
+++        dumpDir = mozfile.TemporaryDirectory().__enter__()
+++        if 1:
++             self.device.getDirectory(self.remoteMinidumpDir, dumpDir)
++             crashed = xpcshell.XPCShellTestThread.checkForCrashes(self, dumpDir, symbols_path, test_name)
++             self.device.removeDir(self.remoteMinidumpDir)
++             self.device.mkDir(self.remoteMinidumpDir)
+++        dumpDir.__exit__(0, 0, 0)
++         return crashed
++ 
++     def communicate(self, proc):
++@@ -333,7 +337,7 @@ class XPCShellRemote(xpcshell.XPCShellTe
++                 packageName = self.localAPKContents.read("package-name.txt")
++                 if packageName:
++                     self.appRoot = self.device.getAppRoot(packageName.strip())
++-            except Exception as detail:
+++            except Exception, detail:
++                 print "unable to determine app root: " + str(detail)
++                 pass
++         return None
++diff -up comm-esr31/mozilla/testing/xpcshell/runxpcshelltests.py.python3 comm-esr31/mozilla/testing/xpcshell/runxpcshelltests.py
++--- comm-esr31/mozilla/testing/xpcshell/runxpcshelltests.py.python3	2014-07-17 18:05:52.000000000 -0600
+++++ comm-esr31/mozilla/testing/xpcshell/runxpcshelltests.py	2014-10-24 11:41:35.528879935 -0600
++@@ -82,7 +82,7 @@ import mozinfo
++ _cleanup_encoding_re = re.compile(u'[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f\\\\]')
++ def _cleanup_encoding_repl(m):
++     c = m.group(0)
++-    return '\\\\' if c == '\\' else '\\x{0:02X}'.format(ord(c))
+++    return ('\\x{0:02X}', '\\\\')[c == '\\'].format(ord(c))
++ def cleanup_encoding(s):
++     """S is either a byte or unicode string.  Either way it may
++        contain control characters, unpaired surrogates, reserved code
++@@ -164,7 +164,7 @@ class XPCShellTestThread(Thread):
++     def run(self):
++         try:
++             self.run_test()
++-        except Exception as e:
+++        except Exception, e:
++             self.exception = e
++             self.traceback = traceback.format_exc()
++         else:
++@@ -202,9 +202,11 @@ class XPCShellTestThread(Thread):
++           For a given test file and stdout buffer, create a log file.
++           On a remote system we have to fix the test name since it can contain directories.
++         """
++-        with open(test_file + ".log", "w") as f:
+++        f = open(test_file + ".log", "w")
+++        if 1:
++             f.write(stdout)
++ 
+++        f.close()
++     def getReturnCode(self, proc):
++         """
++           Simple wrapper to get the return code for a given process.
++@@ -448,7 +450,11 @@ class XPCShellTestThread(Thread):
++                     self.has_failure_output = True
++             return line
++ 
++-        msg = ['%s: ' % line['process'] if 'process' in line else '']
+++        msg = None
+++        if 'process' in line:
+++          msg = ['%s: ' % line['process']
+++        else:
+++          msg = '']
++ 
++         # Each call to the logger in head.js either specified '_message'
++         # or both 'source_file' and 'diagnostic'. If either of these are
++@@ -463,7 +469,7 @@ class XPCShellTestThread(Thread):
++                                          line.get('source_file', 'undefined'),
++                                          line.get('diagnostic', 'undefined')))
++ 
++-        msg.append('\n%s' % line['stack'] if 'stack' in line else '')
+++        msg.append('\n%s' % ('', line['stack']')['stack' in line ])
++         return ''.join(msg)
++ 
++     def parse_output(self, output):
++@@ -646,16 +652,18 @@ class XPCShellTestThread(Thread):
++                     self.clean_temp_dirs(name, stdout)
++                     return
++ 
++-                failureType = "TEST-UNEXPECTED-%s" % ("FAIL" if expected else "PASS")
+++                failureType = "TEST-UNEXPECTED-%s" % (("PASS", "FAIL")[expected])
++                 message = "%s | %s | test failed (with xpcshell return code: %d)" % (
++                               failureType, name, self.getReturnCode(proc))
++                 if self.output_lines:
++                     message += ", see following log:"
++ 
++-                with LOG_MUTEX:
+++                LOG_MUTEX.__enter__()
+++                if 1:
++                     self.log.error(message)
++                     self.log_output(self.output_lines)
++ 
+++                LOG_MUTEX.__exit__(0, 0, 0)
++                 self.failCount += 1
++                 self.xunit_result["passed"] = False
++ 
++@@ -666,21 +674,25 @@ class XPCShellTestThread(Thread):
++                 }
++ 
++                 if self.failureManifest:
++-                    with open(self.failureManifest, 'a') as f:
+++                    f = open(self.failureManifest, 'a')
+++                    if 1:
++                         f.write('[%s]\n' % self.test_object['path'])
++                         for k, v in self.test_object.items():
++                             f.write('%s = %s\n' % (k, v))
++ 
+++                    f.close()
++             else:
++                 now = time.time()
++                 timeTaken = (now - startTime) * 1000
++                 self.xunit_result["time"] = now - startTime
++ 
++-                with LOG_MUTEX:
++-                    self.log.info("TEST-%s | %s | test passed (time: %.3fms)" % ("PASS" if expected else "KNOWN-FAIL", name, timeTaken))
+++                LOG_MUTEX.__enter__()
+++                if 1:
+++                    self.log.info("TEST-%s | %s | test passed (time: %.3fms)" % (("KNOWN-FAIL", "PASS")[expected], name, timeTaken))
++                     if self.verbose:
++                         self.log_output(self.output_lines)
++ 
+++                LOG_MUTEX.__exit__(0, 0, 0)
++                 self.xunit_result["passed"] = True
++                 self.retry = False
++ 
++@@ -717,11 +729,13 @@ class XPCShellTestThread(Thread):
++                     self.clean_temp_dirs(name, stdout)
++                     return
++ 
++-                with LOG_MUTEX:
+++                LOG_MUTEX.__enter__()
+++                if 1:
++                     message = "TEST-UNEXPECTED-FAIL | %s | Process still running after test!" % name
++                     self.log.error(message)
++                     self.log_output(self.output_lines)
++ 
+++                LOG_MUTEX.__exit__(0, 0, 0)
++                 self.failCount = 1
++                 self.xunit_result["passed"] = False
++                 self.xunit_result["failure"] = {
++@@ -768,8 +782,10 @@ class XPCShellTests(object):
++             if unwrapped:
++                 def wrap(fn):
++                     def wrapped(*args, **kwargs):
++-                        with LOG_MUTEX:
+++                        LOG_MUTEX.__enter__()
+++                        if 1:
++                             fn(*args, **kwargs)
+++                        LOG_MUTEX.__exit__(0, 0, 0)
++                     return wrapped
++                 setattr(self.log, fun_name, wrap(unwrapped))
++ 
++diff -up comm-esr31/mozilla/testing/xpcshell/selftest.py.python3 comm-esr31/mozilla/testing/xpcshell/selftest.py
++--- comm-esr31/mozilla/testing/xpcshell/selftest.py.python3	2014-07-17 18:05:52.000000000 -0600
+++++ comm-esr31/mozilla/testing/xpcshell/selftest.py	2014-10-24 11:41:35.528879935 -0600
++@@ -4,7 +4,7 @@
++ # http://creativecommons.org/publicdomain/zero/1.0/
++ #
++ 
++-from __future__ import with_statement
+++
++ import sys, os, unittest, tempfile, shutil
++ import mozinfo
++ 
++@@ -243,8 +243,10 @@ class XPCShellTestsTests(unittest.TestCa
++         and return the full path to the file.
++         """
++         fullpath = os.path.join(self.tempdir, name)
++-        with open(fullpath, "w") as f:
+++        f = open(fullpath, "w")
+++        if 1:
++             f.write(contents)
+++        f.close()
++         return fullpath
++ 
++     def writeManifest(self, tests):
++@@ -257,8 +259,7 @@ class XPCShellTestsTests(unittest.TestCa
++         """
++         testlines = []
++         for t in tests:
++-            testlines.append("[%s]" % (t if isinstance(t, basestring)
++-                                       else t[0]))
+++            (testlines.append("[%s]" % (t[0], t)[isinstance(t, basestring)]))
++             if isinstance(t, tuple):
++                 testlines.extend(t[1:])
++         self.manifest = self.writeFile("xpcshell.ini", """
++@@ -286,7 +287,7 @@ tail =
++ ========
++ %s
++ ========
++-""" % ("passed" if expected else "failed", self.log.getvalue()))
+++""" % (("failed", "passed")[expected], self.log.getvalue()))
++ 
++     def _assertLog(self, s, expected):
++         l = self.log.getvalue()
++@@ -294,7 +295,7 @@ tail =
++                          msg="""Value %s %s in log:
++ ========
++ %s
++-========""" % (s, "expected" if expected else "not expected", l))
+++========""" % (s, ("not expected", "expected")[expected], l))
++ 
++     def assertInLog(self, s):
++         """
++diff -up comm-esr31/mozilla/toolkit/components/diskspacewatcher/moz.build.python3 comm-esr31/mozilla/toolkit/components/diskspacewatcher/moz.build
++--- comm-esr31/mozilla/toolkit/components/diskspacewatcher/moz.build.python3	2014-07-17 18:05:52.000000000 -0600
+++++ comm-esr31/mozilla/toolkit/components/diskspacewatcher/moz.build	2014-10-24 11:41:35.528879935 -0600
++@@ -14,9 +14,11 @@ EXPORTS += [
++ 
++ XPIDL_MODULE = 'diskspacewatcher'
++ 
++-SOURCES = [
+++SOURCES += [
++     'DiskSpaceWatcher.cpp',
++ ]
+++print("SOURCES CLASS")
+++print(SOURCES.__class__)
++ 
++ include('/ipc/chromium/chromium-config.mozbuild')
++ 
++diff -up comm-esr31/mozilla/toolkit/components/telemetry/gen-histogram-data.py.python3 comm-esr31/mozilla/toolkit/components/telemetry/gen-histogram-data.py
++--- comm-esr31/mozilla/toolkit/components/telemetry/gen-histogram-data.py.python3	2014-07-17 18:05:53.000000000 -0600
+++++ comm-esr31/mozilla/toolkit/components/telemetry/gen-histogram-data.py	2014-10-24 11:41:35.528879935 -0600
++@@ -5,7 +5,7 @@
++ # Write out histogram information for C++.  The histograms are defined
++ # in a file provided as a command-line argument.
++ 
++-from __future__ import with_statement
+++
++ 
++ import sys
++ import histogram_tools
++@@ -64,7 +64,7 @@ def print_array_entry(histogram, name_in
++         % (histogram.low(), histogram.high(),
++            histogram.n_buckets(), histogram.nsITelemetry_kind(),
++            name_index, exp_index,
++-           "true" if histogram.extended_statistics_ok() else "false")
+++           ("false", "true")[histogram.extended_statistics_ok()])
++     if cpp_guard:
++         print "#endif"
++ 
++diff -up comm-esr31/mozilla/toolkit/components/telemetry/histogram_tools.py.python3 comm-esr31/mozilla/toolkit/components/telemetry/histogram_tools.py
++--- comm-esr31/mozilla/toolkit/components/telemetry/histogram_tools.py.python3	2014-07-17 18:05:53.000000000 -0600
+++++ comm-esr31/mozilla/toolkit/components/telemetry/histogram_tools.py	2014-10-24 11:41:35.529879930 -0600
++@@ -2,20 +2,20 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-import json
++ import math
++ import re
++ 
++-from collections import OrderedDict
+++import simplejson as json
+++from simplejson import OrderedDict
++ 
++ def table_dispatch(kind, table, body):
++     """Call body with table[kind] if it exists.  Raise an error otherwise."""
++     if kind in table:
++         return body(table[kind])
++     else:
++-        raise BaseException, "don't know how to handle a histogram of kind %s" % kind
+++        raise Exception, "don't know how to handle a histogram of kind %s" % kind
++ 
++-class DefinitionException(BaseException):
+++class DefinitionException(Exception):
++     pass
++ 
++ def check_numeric_limits(dmin, dmax, n_buckets):
++@@ -225,7 +225,10 @@ def from_file(filename):
++     """Return an iterator that provides a sequence of Histograms for
++ the histograms defined in filename.
++     """
++-    with open(filename, 'r') as f:
+++    f = open(filename, 'r')
+++    if 1:
++         histograms = json.load(f, object_pairs_hook=OrderedDict)
++         for (name, definition) in histograms.iteritems():
++             yield Histogram(name, definition)
+++    f.close()
+++
++diff -up comm-esr31/mozilla/toolkit/crashreporter/tools/symbolstore.py.python3 comm-esr31/mozilla/toolkit/crashreporter/tools/symbolstore.py
++--- comm-esr31/mozilla/toolkit/crashreporter/tools/symbolstore.py.python3	2014-07-17 18:05:54.000000000 -0600
+++++ comm-esr31/mozilla/toolkit/crashreporter/tools/symbolstore.py	2014-10-24 11:41:35.529879930 -0600
++@@ -388,15 +388,18 @@ class Dumper:
++         """Increments the number of submitted jobs for the specified key file,
++         defined as the original file we processed; note that a single key file
++         can generate up to 1 + len(self.archs) jobs in the Mac case."""
++-        with Dumper.jobs_condition:
+++        Dumper.jobs_condition.__enter__()
+++        if 1:
++             self.jobs_record[file_key] += 1
++             Dumper.jobs_condition.notify_all()
++ 
+++        Dumper.jobs_condition.__exit__(0, 0, 0)
++     def JobFinished(self, file_key):
++         """Decrements the number of submitted jobs for the specified key file,
++         defined as the original file we processed; once the count is back to 0,
++         remove the entry from our record."""
++-        with Dumper.jobs_condition:
+++        Dumper.jobs_condition.__enter__()
+++        if 1:
++             self.jobs_record[file_key] -= 1
++ 
++             if self.jobs_record[file_key] == 0:
++@@ -404,13 +407,16 @@ class Dumper:
++ 
++             Dumper.jobs_condition.notify_all()
++ 
+++        Dumper.jobs_condition.__exit__(0, 0, 0)
++     def output(self, dest, output_str):
++         """Writes |output_str| to |dest|, holding |lock|;
++         terminates with a newline."""
++-        with Dumper.lock:
+++        Dumper.lock.__enter__()
+++        if 1:
++             dest.write(output_str + "\n")
++             dest.flush()
++ 
+++        Dumper.lock.__exit__(0, 0, 0)
++     def output_pid(self, dest, output_str):
++         """Debugging output; prepends the pid to the string."""
++         self.output(dest, "%d: %s" % (os.getpid(), output_str))
++@@ -499,9 +505,11 @@ class Dumper:
++         wait for the pool to finish processing them. By default, will close
++         and clear the pool, but for testcases that need multiple runs, pass
++         stop_pool = False."""
++-        with Dumper.jobs_condition:
+++        Dumper.jobs_condition.__enter__()
+++        if 1:
++             while len(self.jobs_record) != 0:
++                 Dumper.jobs_condition.wait()
+++        Dumper.jobs_condition.__exit__(0, 0, 0)
++         if stop_pool:
++             Dumper.pool.close()
++             Dumper.pool.join()
++@@ -716,7 +724,11 @@ class Dumper_Win32(Dumper):
++         return result
++ 
++ class Dumper_Linux(Dumper):
++-    objcopy = os.environ['OBJCOPY'] if 'OBJCOPY' in os.environ else 'objcopy'
+++    objcopy = None
+++    if 'OBJCOPY' in os.environ:
+++      objcopy = os.environ['OBJCOPY']
+++    else:
+++      objcopy = 'objcopy'
++     def ShouldProcess(self, file):
++         """This function will allow processing of files that are
++         executable, or end with the .so extension, and additionally
++diff -up comm-esr31/mozilla/toolkit/crashreporter/tools/unit-symbolstore.py.python3 comm-esr31/mozilla/toolkit/crashreporter/tools/unit-symbolstore.py
++--- comm-esr31/mozilla/toolkit/crashreporter/tools/unit-symbolstore.py.python3	2014-07-17 18:05:54.000000000 -0600
+++++ comm-esr31/mozilla/toolkit/crashreporter/tools/unit-symbolstore.py	2014-10-24 11:41:35.529879930 -0600
++@@ -68,7 +68,7 @@ class TestExclude(HelperMixin, unittest.
++         processed = []
++         def mock_process_file(filenames):
++             for filename in filenames:
++-                processed.append((filename[len(self.test_dir):] if filename.startswith(self.test_dir) else filename).replace('\\', '/'))
+++                processed.append(((filename, filename[len(self.test_dir):]).replace('\\')[filename.startswith(self.test_dir)], '/'))
++             return True
++         self.add_test_files(add_extension(["foo", "bar", "abc/xyz", "abc/fooxyz", "def/asdf", "def/xyzfoo"]))
++         d = symbolstore.GetPlatformSpecificDumper(dump_syms="dump_syms",
++@@ -89,7 +89,7 @@ class TestExclude(HelperMixin, unittest.
++         processed = []
++         def mock_process_file(filenames):
++             for filename in filenames:
++-                processed.append((filename[len(self.test_dir):] if filename.startswith(self.test_dir) else filename).replace('\\', '/'))
+++                processed.append(((filename, filename[len(self.test_dir):]).replace('\\')[filename.startswith(self.test_dir)], '/'))
++             return True
++         self.add_test_files(add_extension(["foo", "bar", "abc/foo", "abc/bar", "def/foo", "def/bar"]))
++         d = symbolstore.GetPlatformSpecificDumper(dump_syms="dump_syms",
++@@ -165,7 +165,7 @@ class TestCopyDebugUniversal(HelperMixin
++         """
++         copied = []
++         def mock_copy_debug(filename, debug_file, guid):
++-            copied.append(filename[len(self.symbol_dir):] if filename.startswith(self.symbol_dir) else filename)
+++            copied.append((filename, filename[len(self.symbol_dir):])[filename.startswith(self.symbol_dir)]) 
++         self.add_test_files(add_extension(["foo"]))
++         self.stdouts.append(mock_dump_syms("X" * 33, add_extension(["foo"])[0]))
++         self.stdouts.append(mock_dump_syms("Y" * 33, add_extension(["foo"])[0]))
++diff -up comm-esr31/mozilla/toolkit/devtools/acorn/moz.build.python3 comm-esr31/mozilla/toolkit/devtools/acorn/moz.build
++--- comm-esr31/mozilla/toolkit/devtools/acorn/moz.build.python3	2014-07-17 18:05:54.000000000 -0600
+++++ comm-esr31/mozilla/toolkit/devtools/acorn/moz.build	2014-10-24 11:41:35.529879930 -0600
++@@ -1,15 +1,15 @@
++-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
++-# vim: set filetype=python:
++-# This Source Code Form is subject to the terms of the Mozilla Public
++-# License, v. 2.0. If a copy of the MPL was not distributed with this
++-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++-
++-XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
++-
++-JS_MODULES_PATH = 'modules/devtools/acorn'
++-
++-EXTRA_JS_MODULES += [
++-    'acorn.js',
++-    'acorn_loose.js',
++-    'walk.js',
++-]
+++# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+++# vim: set filetype=python:
+++# This Source Code Form is subject to the terms of the Mozilla Public
+++# License, v. 2.0. If a copy of the MPL was not distributed with this
+++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+++
+++XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
+++
+++JS_MODULES_PATH = 'modules/devtools/acorn'
+++
+++EXTRA_JS_MODULES += [
+++    'acorn.js',
+++    'acorn_loose.js',
+++    'walk.js',
+++]
++diff -up comm-esr31/mozilla/toolkit/mozapps/extensions/internal/moz.build.python3 comm-esr31/mozilla/toolkit/mozapps/extensions/internal/moz.build
++--- comm-esr31/mozilla/toolkit/mozapps/extensions/internal/moz.build.python3	2014-07-17 18:05:55.000000000 -0600
+++++ comm-esr31/mozilla/toolkit/mozapps/extensions/internal/moz.build	2014-10-24 11:41:35.529879930 -0600
++@@ -1,31 +1,31 @@
++-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
++-# vim: set filetype=python:
++-# This Source Code Form is subject to the terms of the Mozilla Public
++-# License, v. 2.0. If a copy of the MPL was not distributed with this
++-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++-
++-JS_MODULES_PATH = 'modules/addons'
++-
++-EXTRA_JS_MODULES += [
++-    'AddonLogging.jsm',
++-    'AddonRepository.jsm',
++-    'AddonRepository_SQLiteMigrator.jsm',
++-    'AddonUpdateChecker.jsm',
++-    'Content.js',
++-    'LightweightThemeImageOptimizer.jsm',
++-    'PluginProvider.jsm',
++-    'SpellCheckDictionaryBootstrap.js',
++-]
++-
++-EXTRA_PP_JS_MODULES += [
++-    'XPIProvider.jsm',
++-    'XPIProviderUtils.js',
++-]
++-
++-# This is used in multiple places, so is defined here to avoid it getting
++-# out of sync.
++-DEFINES['MOZ_EXTENSIONS_DB_SCHEMA'] = 16
++-
++-# Additional debugging info is exposed in debug builds
++-if CONFIG['MOZ_EM_DEBUG']:
++-    DEFINES['MOZ_EM_DEBUG'] = 1
+++# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+++# vim: set filetype=python:
+++# This Source Code Form is subject to the terms of the Mozilla Public
+++# License, v. 2.0. If a copy of the MPL was not distributed with this
+++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+++
+++JS_MODULES_PATH = 'modules/addons'
+++
+++EXTRA_JS_MODULES += [
+++    'AddonLogging.jsm',
+++    'AddonRepository.jsm',
+++    'AddonRepository_SQLiteMigrator.jsm',
+++    'AddonUpdateChecker.jsm',
+++    'Content.js',
+++    'LightweightThemeImageOptimizer.jsm',
+++    'PluginProvider.jsm',
+++    'SpellCheckDictionaryBootstrap.js',
+++]
+++
+++EXTRA_PP_JS_MODULES += [
+++    'XPIProvider.jsm',
+++    'XPIProviderUtils.js',
+++]
+++
+++# This is used in multiple places, so is defined here to avoid it getting
+++# out of sync.
+++DEFINES['MOZ_EXTENSIONS_DB_SCHEMA'] = 16
+++
+++# Additional debugging info is exposed in debug builds
+++if CONFIG['MOZ_EM_DEBUG']:
+++    DEFINES['MOZ_EM_DEBUG'] = 1
++diff -up comm-esr31/mozilla/toolkit/mozapps/installer/dozip.py.python3 comm-esr31/mozilla/toolkit/mozapps/installer/dozip.py
++--- comm-esr31/mozilla/toolkit/mozapps/installer/dozip.py.python3	2014-07-17 18:05:55.000000000 -0600
+++++ comm-esr31/mozilla/toolkit/mozapps/installer/dozip.py	2014-10-24 11:41:35.530879926 -0600
++@@ -29,7 +29,8 @@ def main(args):
++ 
++     jarrer = Jarrer(optimize=False)
++ 
++-    with errors.accumulate():
+++    errors.accumulate().__enter__()
+++    if 1:
++         finder = FileFinder(args.base_dir)
++         for i in args.input:
++             path = mozpath.relpath(i, args.base_dir)
++@@ -38,5 +39,6 @@ def main(args):
++         jarrer.copy(args.zip)
++ 
++ 
+++    errors.accumulate().__exit__(0, 0, 0)
++ if __name__ == '__main__':
++     main(sys.argv[1:])
++diff -up comm-esr31/mozilla/toolkit/mozapps/installer/find-dupes.py.python3 comm-esr31/mozilla/toolkit/mozapps/installer/find-dupes.py
++--- comm-esr31/mozilla/toolkit/mozapps/installer/find-dupes.py.python3	2014-07-17 18:05:55.000000000 -0600
+++++ comm-esr31/mozilla/toolkit/mozapps/installer/find-dupes.py	2014-10-24 11:41:35.530879926 -0600
++@@ -3,9 +3,9 @@
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++ import sys
++-import hashlib
+++import md5
++ from mozpack.packager.unpack import UnpackFinder
++-from collections import OrderedDict
+++from ordereddict import OrderedDict
++ 
++ '''
++ Find files duplicated in a given packaged directory, independently of its
++@@ -17,7 +17,7 @@ def find_dupes(source):
++     md5s = OrderedDict()
++     for p, f in UnpackFinder(source):
++         content = f.open().read()
++-        m = hashlib.md5(content).digest()
+++        m = md5.md5(content).digest()
++         if not m in md5s:
++             md5s[m] = (len(content), [])
++         md5s[m][1].append(p)
++@@ -26,7 +26,7 @@ def find_dupes(source):
++     for m, (size, paths) in md5s.iteritems():
++         if len(paths) > 1:
++             print 'Duplicates %d bytes%s:' % (size,
++-                  ' (%d times)' % (len(paths) - 1) if len(paths) > 2 else '')
+++                  ' (%d times)' % ((0, len(paths) - 1)[len(paths) > 2]))
++             print ''.join('  %s\n' % p for p in paths)
++             total += (len(paths) - 1) * size
++             num_dupes += 1
++diff -up comm-esr31/mozilla/toolkit/mozapps/installer/informulate.py.python3 comm-esr31/mozilla/toolkit/mozapps/installer/informulate.py
++--- comm-esr31/mozilla/toolkit/mozapps/installer/informulate.py.python3	2014-07-17 18:05:55.000000000 -0600
+++++ comm-esr31/mozilla/toolkit/mozapps/installer/informulate.py	2014-10-24 11:41:35.530879926 -0600
++@@ -37,10 +37,12 @@ def main():
++     all_key_value_pairs = dict([(x.lower(), buildconfig.substs[x]) for x in important_substitutions])
++     all_key_value_pairs.update(parse_cmdline(sys.argv[2:]))
++ 
++-    with open(sys.argv[1], "w+") as f:
+++    f = open(sys.argv[1], "w+")
+++    if 1:
++         json.dump(all_key_value_pairs, f, indent=2, sort_keys=True)
++         f.write('\n')
++ 
++ 
+++    f.close()
++ if __name__=="__main__":
++     main()
++diff -up comm-esr31/mozilla/toolkit/mozapps/installer/packager.py.python3 comm-esr31/mozilla/toolkit/mozapps/installer/packager.py
++--- comm-esr31/mozilla/toolkit/mozapps/installer/packager.py.python3	2014-07-17 18:05:55.000000000 -0600
+++++ comm-esr31/mozilla/toolkit/mozapps/installer/packager.py	2014-10-24 11:41:35.530879926 -0600
++@@ -2,6 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
+++from rhrebase import all, any
++ from mozpack.packager.formats import (
++     FlatFormatter,
++     JarFormatter,
++@@ -316,7 +317,8 @@ def main():
++     elif not buildconfig.substs['CROSS_COMPILE']:
++         launcher.tooldir = buildconfig.substs['LIBXUL_DIST']
++ 
++-    with errors.accumulate():
+++    errors.accumulate()
+++    if 1:
++         finder_args = dict(
++             minify=args.minify,
++             minify_js=args.minify_js,
++@@ -353,6 +355,7 @@ def main():
++             preprocess(removals_in, removals, defines)
++             copier.add(mozpack.path.join(binpath, 'removed-files'), removals)
++ 
+++    #errors.accumulate().__exit__(0, 0, 0)
++     # shlibsign libraries
++     if launcher.can_launch():
++         for lib in SIGN_LIBS:
++diff -up comm-esr31/mozilla/tools/docs/conf.py.python3 comm-esr31/mozilla/tools/docs/conf.py
++--- comm-esr31/mozilla/tools/docs/conf.py.python3	2014-07-17 18:05:56.000000000 -0600
+++++ comm-esr31/mozilla/tools/docs/conf.py	2014-10-24 11:41:35.530879926 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import os
++ import re
++diff -up comm-esr31/mozilla/tools/docs/mach_commands.py.python3 comm-esr31/mozilla/tools/docs/mach_commands.py
++--- comm-esr31/mozilla/tools/docs/mach_commands.py.python3	2014-07-17 18:05:56.000000000 -0600
+++++ comm-esr31/mozilla/tools/docs/mach_commands.py	2014-10-24 11:41:35.531879922 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, # You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import os
++ 
++diff -up comm-esr31/mozilla/tools/docs/moztreedocs/__init__.py.python3 comm-esr31/mozilla/tools/docs/moztreedocs/__init__.py
++--- comm-esr31/mozilla/tools/docs/moztreedocs/__init__.py.python3	2014-07-17 18:05:56.000000000 -0600
+++++ comm-esr31/mozilla/tools/docs/moztreedocs/__init__.py	2014-10-24 11:41:35.531879922 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, # You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import os
++ 
++@@ -98,9 +98,11 @@ class SphinxManager(object):
++         m.populate_registry(copier)
++         copier.copy(stage_dir)
++ 
++-        with open(self._index_path, 'rb') as fh:
+++        fh = open(self._index_path, 'rb')
+++        if 1:
++             data = fh.read()
++ 
+++        fh.__exit__(0, 0, 0)
++         indexes = ['%s/index' % p for p in sorted(self._trees.keys())]
++         indexes = '\n   '.join(indexes)
++ 
++@@ -109,5 +111,8 @@ class SphinxManager(object):
++         packages = '\n   '.join(sorted(packages))
++         data = data.format(indexes=indexes, python_packages=packages)
++ 
++-        with open(os.path.join(stage_dir, 'index.rst'), 'wb') as fh:
+++        fh = open(os.path.join(stage_dir, 'index.rst'), 'wb').__enter__()
+++        if 1:
++             fh.write(data)
+++        fh.close()
+++
++diff -up comm-esr31/mozilla/tools/mach_commands.py.python3 comm-esr31/mozilla/tools/mach_commands.py
++--- comm-esr31/mozilla/tools/mach_commands.py.python3	2014-07-17 18:05:56.000000000 -0600
+++++ comm-esr31/mozilla/tools/mach_commands.py	2014-10-24 11:41:35.531879922 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, # You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import sys
++ import os
++@@ -247,8 +247,10 @@ class PastebinProvider(object):
++ 
++         if file:
++             try:
++-                with open(file, 'r') as f:
+++                f = open(file, 'r')
+++                if 1:
++                     content = f.read()
+++                f.close()
++                 # TODO: Use mime-types instead of extensions; suprocess('file <f_name>')
++                 # Guess File-type based on file extension
++                 extension = file.split('.')[-1]
++@@ -344,7 +346,7 @@ class FormatProvider(MachCommandBase):
++             if not clang_format_diff:
++                 return 1
++ 
++-        except urllib2.HTTPError as e:
+++        except urllib2.HTTPError, e:
++             print("HTTP error {0}: {1}".format(e.code, e.reason))
++             return 1
++ 
++@@ -360,7 +362,7 @@ class FormatProvider(MachCommandBase):
++                 diff_process = Popen(["filterdiff", "--include=*.h", "--include=*.cpp",
++                                       "--exclude-from-file=.clang-format-ignore"],
++                                      stdin=git_process.stdout, stdout=PIPE)
++-            except OSError as e:
+++            except OSError, e:
++                 if e.errno == errno.ENOENT:
++                     print("Can't find filterdiff. Please install patchutils.")
++                 else:
++@@ -387,9 +389,11 @@ class FormatProvider(MachCommandBase):
++             print("Downloading {0} to {1}".format(u, target))
++             data = urllib2.urlopen(url=u).read()
++             temp = target + ".tmp"
++-            with open(temp, "wb") as fh:
+++            fh = open(temp, "wb")
+++            if 1:
++                 fh.write(data)
++                 fh.close()
+++            fh.close()
++             os.chmod(temp, os.stat(temp).st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
++             os.rename(temp, target)
++         return target
++diff -up comm-esr31/mozilla/tools/mercurial/hgsetup/config.py.python3 comm-esr31/mozilla/tools/mercurial/hgsetup/config.py
++--- comm-esr31/mozilla/tools/mercurial/hgsetup/config.py.python3	2014-07-17 18:05:56.000000000 -0600
+++++ comm-esr31/mozilla/tools/mercurial/hgsetup/config.py	2014-10-24 11:41:35.531879922 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this,
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ from configobj import ConfigObj
++ import re
++diff -up comm-esr31/mozilla/tools/mercurial/hgsetup/wizard.py.python3 comm-esr31/mozilla/tools/mercurial/hgsetup/wizard.py
++--- comm-esr31/mozilla/tools/mercurial/hgsetup/wizard.py.python3	2014-07-17 18:05:56.000000000 -0600
+++++ comm-esr31/mozilla/tools/mercurial/hgsetup/wizard.py	2014-10-24 11:41:35.531879922 -0600
++@@ -2,7 +2,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this,
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import unicode_literals
+++
++ 
++ import difflib
++ import errno
++@@ -19,7 +19,7 @@ from mozversioncontrol.repoupdate import
++     update_git_repo,
++ )
++ 
++-from .config import (
+++from config import (
++     HOST_FINGERPRINTS,
++     MercurialConfig,
++ )
++@@ -102,13 +102,13 @@ class MercurialSetupWizard(object):
++     def run(self, config_paths):
++         try:
++             os.makedirs(self.ext_dir)
++-        except OSError as e:
+++        except OSError, e:
++             if e.errno != errno.EEXIST:
++                 raise
++ 
++         try:
++             hg = which.which('hg')
++-        except which.WhichError as e:
+++        except which.WhichError, e:
++             print(e)
++             print('Try running |mach bootstrap| to ensure your environment is '
++                 'up to date.')
++@@ -116,7 +116,7 @@ class MercurialSetupWizard(object):
++ 
++         try:
++             c = MercurialConfig(config_paths)
++-        except ConfigObjError as e:
+++        except ConfigObjError, e:
++             print('Error importing existing Mercurial config!\n'
++                   '%s\n'
++                   'If using quotes, they must wrap the entire string.' % e)
++@@ -212,9 +212,11 @@ class MercurialSetupWizard(object):
++ 
++         config_path = c.config_path
++         if os.path.exists(config_path):
++-            with open(config_path, 'rt') as fh:
+++            fh = open(config_path, 'rt')
+++            if 1:
++                 old_lines = [line.rstrip() for line in fh.readlines()]
++ 
+++            fh.close()
++         diff = list(difflib.unified_diff(old_lines, new_lines,
++             'hgrc.old', 'hgrc.new'))
++ 
++@@ -228,8 +230,10 @@ class MercurialSetupWizard(object):
++                 print('')
++ 
++             if self._prompt_yn('Would you like me to update your hgrc file'):
++-                with open(config_path, 'wt') as fh:
+++                fh = open(config_path, 'wt')
+++                if 1:
++                     c.write(fh)
+++                fh.close()
++                 print('Wrote changes to %s.' % config_path)
++             else:
++                 print('hgrc changes not written to file. I would have '
++diff -up comm-esr31/mozilla/tools/mercurial/mach_commands.py.python3 comm-esr31/mozilla/tools/mercurial/mach_commands.py
++--- comm-esr31/mozilla/tools/mercurial/mach_commands.py.python3	2014-07-17 18:05:56.000000000 -0600
+++++ comm-esr31/mozilla/tools/mercurial/mach_commands.py	2014-10-24 11:41:35.532879918 -0600
++@@ -2,7 +2,11 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this,
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import print_function, unicode_literals
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
++ 
++ import os
++ import sys
++@@ -34,7 +38,9 @@ class VersionControlCommands(object):
++         # Touch a file so we can periodically prompt to update extensions.
++         state_path = os.path.join(self._context.state_dir,
++             'mercurial/setup.lastcheck')
++-        with open(state_path, 'a'):
+++        open(state_path, 'a').__enter__()
+++        if 1:
++             os.utime(state_path, None)
++ 
+++        open(state_path, 'a').__exit__(0, 0, 0)
++         return result
++diff -up comm-esr31/mozilla/tools/profiler/LulElf.cpp.python3 comm-esr31/mozilla/tools/profiler/LulElf.cpp
++--- comm-esr31/mozilla/tools/profiler/LulElf.cpp.python3	2014-07-17 18:05:56.000000000 -0600
+++++ comm-esr31/mozilla/tools/profiler/LulElf.cpp	2014-10-24 11:41:35.532879918 -0600
++@@ -69,6 +69,11 @@
++ #include "LulElfInt.h"
++ #include "LulMainInt.h"
++ 
+++#ifndef NT_GNU_BUILD_ID
+++#define NT_GNU_BUILD_ID 3
+++#endif
+++
+++
++ 
++ #if defined(LUL_PLAT_arm_android) && !defined(SHT_ARM_EXIDX)
++ // bionic and older glibsc don't define it
++diff -up comm-esr31/mozilla/tools/rb/fix_stack_using_bpsyms.py.python3 comm-esr31/mozilla/tools/rb/fix_stack_using_bpsyms.py
++--- comm-esr31/mozilla/tools/rb/fix_stack_using_bpsyms.py.python3	2014-07-17 18:05:56.000000000 -0600
+++++ comm-esr31/mozilla/tools/rb/fix_stack_using_bpsyms.py	2014-10-24 11:41:35.532879918 -0600
++@@ -4,7 +4,7 @@
++ # License, v. 2.0. If a copy of the MPL was not distributed with this
++ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ 
++-from __future__ import with_statement
+++
++ 
++ import sys
++ import os
++@@ -30,7 +30,8 @@ class SymbolFile:
++     addrs = [] # list of addresses, which will be sorted once we're done initializing
++     funcs = {} # hash: address --> (function name + possible file/line)
++     files = {} # hash: filenum (string) --> prettified filename ready to have a line number appended
++-    with open(fn) as f:
+++    f = open(fn)
+++    if 1:
++       for line in f:
++         line = line.rstrip()
++         # http://code.google.com/p/google-breakpad/wiki/SymbolFiles
++@@ -61,6 +62,7 @@ class SymbolFile:
++           funcs[rva] = name
++           addrs.append(rva)
++         # skip everything else
+++    f.close()
++     #print "Loaded %d functions from symbol file %s" % (len(funcs), os.path.basename(fn))
++     self.addrs = sorted(addrs)
++     self.funcs = funcs
++diff -up comm-esr31/mozilla/xpcom/idl-parser/header.py.python3 comm-esr31/mozilla/xpcom/idl-parser/header.py
++--- comm-esr31/mozilla/xpcom/idl-parser/header.py.python3	2014-07-17 18:05:57.000000000 -0600
+++++ comm-esr31/mozilla/xpcom/idl-parser/header.py	2014-10-24 11:41:35.532879918 -0600
++@@ -159,7 +159,8 @@ forward_decl = """class %(name)s; /* for
++ 
++ def idl_basename(f):
++     """returns the base name of a file with the last extension stripped"""
++-    return os.path.basename(f).rpartition('.')[0]
+++    return ".".join(os.path.basename(f).split('.')[:-1])
+++    #return os.path.basename(f).rpartition('.')[0]
++ 
++ def print_header(idl, fd, filename):
++     fd.write(header % {'filename': filename,
++@@ -333,11 +334,18 @@ def write_interface(iface, fd):
++ 
++         fd.write("  %s = 0;\n" % attributeAsNative(a, True))
++         if a.infallible:
+++            a_args = ''
+++            if a.implicit_jscontext:
+++              a_args = 'JSContext* cx'
+++            a_argnames = ''
+++            if a.implicit_jscontext:
+++              a.implicit_jscontext = 'cx, '
++             fd.write(attr_infallible_tmpl %
+++
++                      {'realtype': a.realtype.nativeType('in'),
++                       'nativename': attributeNativeName(a, getter=True),
++-                      'args': '' if not a.implicit_jscontext else 'JSContext* cx',
++-                      'argnames': '' if not a.implicit_jscontext else 'cx, '})
+++                      'args': a_args, 
+++                      'argnames': a_argnames})
++ 
++         if not a.readonly:
++             fd.write("  %s = 0;\n" % attributeAsNative(a, False))
++@@ -486,7 +494,11 @@ if __name__ == '__main__':
++     o.add_option('--regen', action='store_true', dest='regen', default=False,
++                  help="Regenerate IDL Parser cache")
++     options, args = o.parse_args()
++-    file = args[0] if args else None
+++    file = None
+++    if args:
+++      file = args[0]
+++    else:
+++      file = None
++ 
++     if options.cachedir is not None:
++         if not os.path.isdir(options.cachedir):
++diff -up comm-esr31/mozilla/xpcom/idl-parser/typelib.py.python3 comm-esr31/mozilla/xpcom/idl-parser/typelib.py
++--- comm-esr31/mozilla/xpcom/idl-parser/typelib.py.python3	2014-07-17 18:05:57.000000000 -0600
+++++ comm-esr31/mozilla/xpcom/idl-parser/typelib.py	2014-10-24 11:41:35.533879913 -0600
++@@ -260,7 +260,11 @@ if __name__ == '__main__':
++     o.add_option('--regen', action='store_true', dest='regen', default=False,
++                  help="Regenerate IDL Parser cache")
++     options, args = o.parse_args()
++-    file = args[0] if args else None
+++    file = None
+++    if args:
+++      file = args[0]
+++    else:
+++      file = None
++ 
++     if options.cachedir is not None:
++         if not os.path.isdir(options.cachedir):
++diff -up comm-esr31/mozilla/xpcom/typelib/xpt/tools/xpt.py.python3 comm-esr31/mozilla/xpcom/typelib/xpt/tools/xpt.py
++--- comm-esr31/mozilla/xpcom/typelib/xpt/tools/xpt.py.python3	2014-07-17 18:05:57.000000000 -0600
+++++ comm-esr31/mozilla/xpcom/typelib/xpt/tools/xpt.py	2014-10-24 11:41:35.533879913 -0600
++@@ -65,8 +65,9 @@ InterfaceType()        - construct a new
++ 
++ """
++ 
++-from __future__ import with_statement
+++
++ import os, sys
+++import mystruct
++ import struct
++ import operator
++ 
++@@ -102,7 +103,7 @@ class Type(object):
++     this class directly. Rather, use one of its subclasses.
++     
++     """
++-    _prefixdescriptor = struct.Struct(">B")
+++    _prefixdescriptor = mystruct.Struct(">B")
++     Tags = enum(
++         # The first 18 entries are SimpleTypeDescriptor
++         'int8',
++@@ -263,7 +264,7 @@ class InterfaceType(Type):
++     (InterfaceTypeDescriptor from the typelib specification.)
++ 
++     """
++-    _descriptor = struct.Struct(">H")
+++    _descriptor = mystruct.Struct(">H")
++ 
++     def __init__(self, iface, pointer=True, **kwargs):
++         if not pointer:
++@@ -315,7 +316,7 @@ class InterfaceIsType(Type):
++     typelib specification.)
++     
++     """
++-    _descriptor = struct.Struct(">B")
+++    _descriptor = mystruct.Struct(">B")
++     _cache = {}
++ 
++     def __init__(self, param_index, pointer=True, **kwargs):
++@@ -364,7 +365,7 @@ class ArrayType(Type):
++     (ArrayTypeDescriptor from the typelib specification.)
++     
++     """
++-    _descriptor = struct.Struct(">BB")
+++    _descriptor = mystruct.Struct(">BB")
++ 
++     def __init__(self, element_type, size_is_arg_num, length_is_arg_num,
++                  pointer=True, **kwargs):
++@@ -414,7 +415,7 @@ class StringWithSizeType(Type):
++     from the typelib specification.)
++ 
++     """
++-    _descriptor = struct.Struct(">BB")
+++    _descriptor = mystruct.Struct(">BB")
++ 
++     def __init__(self, size_is_arg_num, length_is_arg_num,
++                  pointer=True, **kwargs):
++@@ -461,7 +462,7 @@ class WideStringWithSizeType(Type):
++     (WideStringWithSizeTypeDescriptor from the typelib specification.)
++ 
++     """
++-    _descriptor = struct.Struct(">BB")
+++    _descriptor = mystruct.Struct(">BB")
++ 
++     def __init__(self, size_is_arg_num, length_is_arg_num,
++                  pointer=True, **kwargs):
++@@ -507,7 +508,7 @@ class Param(object):
++     (ParamDescriptor from the typelib specification.)
++ 
++     """
++-    _descriptorstart = struct.Struct(">B")
+++    _descriptorstart = mystruct.Struct(">B")
++ 
++     def __init__(self, type, in_=True, out=False, retval=False,
++                  shared=False, dipper=False, optional=False):
++@@ -626,7 +627,7 @@ class Method(object):
++     (MethodDescriptor from the typelib specification.)
++     
++     """
++-    _descriptorstart = struct.Struct(">BIB")
+++    _descriptorstart = mystruct.Struct(">BIB")
++ 
++     def __init__(self, name, result,
++                  params=[], getter=False, setter=False, notxpcom=False,
++@@ -767,7 +768,7 @@ class Constant(object):
++     (ConstantDesciptor from the typelib specification.)
++ 
++     """
++-    _descriptorstart = struct.Struct(">I")
+++    _descriptorstart = mystruct.Struct(">I")
++     # Actual value is restricted to this set of types
++     #XXX: the spec lies, the source allows a bunch more
++     # http://hg.mozilla.org/mozilla-central/annotate/9c85f9aaec8c/xpcom/typelib/xpt/src/xpt_struct.c#l689
++@@ -801,7 +802,7 @@ class Constant(object):
++         if isinstance(t, SimpleType) and t.tag in Constant.typemap:
++             tt = Constant.typemap[t.tag]
++             start = data_pool + offset - 1
++-            (val,) = struct.unpack_from(tt, map, start)
+++            (val,) = mystruct.unpack_from(tt, map, start)
++             offset += struct.calcsize(tt)
++             c = Constant(name, t, val)
++         return c, offset
++@@ -840,8 +841,8 @@ class Interface(object):
++     (InterfaceDescriptor from the typelib specification.)
++     
++     """
++-    _direntry = struct.Struct(">16sIII")
++-    _descriptorstart = struct.Struct(">HH")
+++    _direntry = mystruct.Struct(">16sIII")
+++    _descriptorstart = mystruct.Struct(">HH")
++ 
++     UNRESOLVED_IID = "00000000-0000-0000-0000-000000000000"
++ 
++@@ -919,14 +920,14 @@ class Interface(object):
++             self.methods.append(m)
++         # Read constants
++         start = data_pool + offset - 1
++-        (num_constants, ) = struct.unpack_from(">H", map, start)
+++        (num_constants, ) = mystruct.unpack_from(">H", map, start)
++         offset = offset + struct.calcsize(">H")
++         for i in range(num_constants):
++             c, offset = Constant.read(typelib, map, data_pool, offset)
++             self.constants.append(c)
++         # Read flags
++         start = data_pool + offset - 1
++-        (flags, ) = struct.unpack_from(">B", map, start)
+++        (flags, ) = mystruct.unpack_from(">B", map, start)
++         offset = offset + struct.calcsize(">B")
++         # only the first two bits are flags
++         flags &= 0xE0
++@@ -1011,7 +1012,7 @@ class Typelib(object):
++     or the static Typelib.read method may be called to read one from a file.
++ 
++     """
++-    _header = struct.Struct(">16sBBHIII")
+++    _header = mystruct.Struct(">16sBBHIII")
++ 
++     def __init__(self, version=TYPELIB_VERSION, interfaces=[], annotations=[]):
++         """
++@@ -1067,10 +1068,12 @@ class Typelib(object):
++         expected_size = None
++         if isinstance(input_file, basestring):
++             filename = input_file
++-            with open(input_file, "rb") as f:
+++            f = open(input_file, "rb")
+++            if 1:
++                 st = os.fstat(f.fileno())
++                 data = f.read(st.st_size)
++                 expected_size = st.st_size
+++            f.__exit__(0, 0, 0)
++         else:
++             data = input_file.read()
++ 
++@@ -1096,7 +1099,7 @@ class Typelib(object):
++         # make a half-hearted attempt to read Annotations,
++         # since XPIDL doesn't produce any anyway.
++         start = Typelib._header.size
++-        (anno, ) = struct.unpack_from(">B", data, start)
+++        (anno, ) = mystruct.unpack_from(">B", data, start)
++         islast = anno & 0x80
++         tag = anno & 0x7F
++         if tag == 0: # EmptyAnnotation
++@@ -1184,8 +1187,10 @@ class Typelib(object):
++         """
++         self._sanityCheck()
++         if isinstance(output_file, basestring):
++-            with open(output_file, "wb") as f:
+++            f = open(output_file, "wb")
+++            if 1:
++                 self.writefd(f)
+++            f.close()
++         else:
++             self.writefd(output_file)
++ 
diff --cc pango-backport.patch
index 0000000,0000000..d38f542
new file mode 100644
--- /dev/null
+++ b/pango-backport.patch
@@@ -1,0 -1,0 +1,60 @@@
++diff -up mozilla-aurora/configure.in.pango-backport mozilla-aurora/configure.in
++--- mozilla-aurora/configure.in.pango-backport	2014-05-06 13:17:17.000000000 +0200
+++++ mozilla-aurora/configure.in	2014-08-07 12:07:28.000000000 +0200
++@@ -60,7 +60,7 @@ dnl ====================================
++ GLIB_VERSION=1.2.0
++ PERL_VERSION=5.006
++ CAIRO_VERSION=1.10
++-PANGO_VERSION=1.22.0
+++PANGO_VERSION=1.14.0
++ GTK2_VERSION=2.10.0
++ GTK3_VERSION=3.0.0
++ WINDRES_VERSION=2.14.90
++diff -up mozilla-aurora/configure.pango-backport mozilla-aurora/configure
++--- mozilla-aurora/configure.pango-backport	2014-08-07 12:08:55.000000000 +0200
+++++ mozilla-aurora/configure	2014-08-07 12:09:20.000000000 +0200
++@@ -1296,7 +1296,7 @@ NSS_VERSION=3
++ GLIB_VERSION=1.2.0
++ PERL_VERSION=5.006
++ CAIRO_VERSION=1.10
++-PANGO_VERSION=1.22.0
+++PANGO_VERSION=1.14.0
++ GTK2_VERSION=2.10.0
++ GTK3_VERSION=3.0.0
++ WINDRES_VERSION=2.14.90
++diff -up mozilla-aurora/gfx/thebes/gfxPlatform.cpp.pango-backport mozilla-aurora/gfx/thebes/gfxPlatform.cpp
++--- mozilla-aurora/gfx/thebes/gfxPlatform.cpp.pango-backport	2014-05-19 11:43:50.000000000 +0200
+++++ mozilla-aurora/gfx/thebes/gfxPlatform.cpp	2014-08-07 12:07:28.000000000 +0200
++@@ -530,6 +530,14 @@ gfxPlatform::~gfxPlatform()
++     cairo_debug_reset_static_data();
++ #endif
++ #endif
+++
+++#if 0
+++    // It would be nice to do this (although it might need to be after
+++    // the cairo shutdown that happens in ~gfxPlatform).  It even looks
+++    // idempotent.  But it has fatal assertions that fire if stuff is
+++    // leaked, and we hit them.
+++    FcFini();
+++#endif
++ }
++ 
++ bool
++diff -up mozilla-aurora/gfx/thebes/gfxPlatformGtk.cpp.pango-backport mozilla-aurora/gfx/thebes/gfxPlatformGtk.cpp
++--- mozilla-aurora/gfx/thebes/gfxPlatformGtk.cpp.pango-backport	2014-05-06 13:17:14.000000000 +0200
+++++ mozilla-aurora/gfx/thebes/gfxPlatformGtk.cpp	2014-08-07 12:07:28.000000000 +0200
++@@ -77,6 +77,14 @@ gfxPlatformGtk::~gfxPlatformGtk()
++     sFontconfigUtils = nullptr;
++ 
++     gfxPangoFontGroup::Shutdown();
+++
+++#if 0
+++    // It would be nice to do this (although it might need to be after
+++    // the cairo shutdown that happens in ~gfxPlatform).  It even looks
+++    // idempotent.  But it has fatal assertions that fire if stuff is
+++    // leaked, and we hit them.
+++    FcFini();
+++#endif
++ }
++ 
++ already_AddRefed<gfxASurface>
diff --cc rebase-dir.patch
index 0000000,0000000..42af1f6
new file mode 100644
--- /dev/null
+++ b/rebase-dir.patch
@@@ -1,0 -1,0 +1,7577 @@@
++diff -up mozilla-aurora/rebase/abc.py.rebase-dir mozilla-aurora/rebase/abc.py
++--- mozilla-aurora/rebase/abc.py.rebase-dir	2014-07-28 18:25:25.000000000 +0200
+++++ mozilla-aurora/rebase/abc.py	2014-07-28 18:25:25.000000000 +0200
++@@ -0,0 +1,182 @@
+++# Copyright 2007 Google, Inc. All Rights Reserved.
+++# Licensed to PSF under a Contributor Agreement.
+++
+++"""Abstract Base Classes (ABCs) according to PEP 3119."""
+++
+++
+++# Instance of old-style class
+++class _C: pass
+++_InstanceType = type(_C())
+++
+++
+++def abstractmethod(funcobj):
+++    """A decorator indicating abstract methods.
+++
+++    Requires that the metaclass is ABCMeta or derived from it.  A
+++    class that has a metaclass derived from ABCMeta cannot be
+++    instantiated unless all of its abstract methods are overridden.
+++    The abstract methods can be called using any of the normal
+++    'super' call mechanisms.
+++
+++    Usage:
+++
+++        class C:
+++            __metaclass__ = ABCMeta
+++            @abstractmethod
+++            def my_abstract_method(self, ...):
+++                ...
+++    """
+++    funcobj.__isabstractmethod__ = True
+++    return funcobj
+++
+++
+++class abstractproperty(property):
+++    """A decorator indicating abstract properties.
+++
+++    Requires that the metaclass is ABCMeta or derived from it.  A
+++    class that has a metaclass derived from ABCMeta cannot be
+++    instantiated unless all of its abstract properties are overridden.
+++    The abstract properties can be called using any of the normal
+++    'super' call mechanisms.
+++
+++    Usage:
+++
+++        class C:
+++            __metaclass__ = ABCMeta
+++            @abstractproperty
+++            def my_abstract_property(self):
+++                ...
+++
+++    This defines a read-only property; you can also define a read-write
+++    abstract property using the 'long' form of property declaration:
+++
+++        class C:
+++            __metaclass__ = ABCMeta
+++            def getx(self): ...
+++            def setx(self, value): ...
+++            x = abstractproperty(getx, setx)
+++    """
+++    __isabstractmethod__ = True
+++
+++
+++class ABCMeta(type):
+++
+++    """Metaclass for defining Abstract Base Classes (ABCs).
+++
+++    Use this metaclass to create an ABC.  An ABC can be subclassed
+++    directly, and then acts as a mix-in class.  You can also register
+++    unrelated concrete classes (even built-in classes) and unrelated
+++    ABCs as 'virtual subclasses' -- these and their descendants will
+++    be considered subclasses of the registering ABC by the built-in
+++    issubclass() function, but the registering ABC won't show up in
+++    their MRO (Method Resolution Order) nor will method
+++    implementations defined by the registering ABC be callable (not
+++    even via super()).
+++
+++    """
+++
+++    # A global counter that is incremented each time a class is
+++    # registered as a virtual subclass of anything.  It forces the
+++    # negative cache to be cleared before its next use.
+++    _abc_invalidation_counter = 0
+++
+++    def __new__(mcls, name, bases, namespace):
+++        cls = super(ABCMeta, mcls).__new__(mcls, name, bases, namespace)
+++        # Compute set of abstract method names
+++        abstracts = set(name
+++                     for name, value in namespace.items()
+++                     if getattr(value, "__isabstractmethod__", False))
+++        for base in bases:
+++            for name in getattr(base, "__abstractmethods__", set()):
+++                value = getattr(cls, name, None)
+++                if getattr(value, "__isabstractmethod__", False):
+++                    abstracts.add(name)
+++        cls.__abstractmethods__ = frozenset(abstracts)
+++        # Set up inheritance registry
+++        cls._abc_registry = set()
+++        cls._abc_cache = set()
+++        cls._abc_negative_cache = set()
+++        cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
+++        return cls
+++
+++    def register(cls, subclass):
+++        """Register a virtual subclass of an ABC."""
+++        if not isinstance(cls, type):
+++            raise TypeError("Can only register classes")
+++        if issubclass(subclass, cls):
+++            return  # Already a subclass
+++        # Subtle: test for cycles *after* testing for "already a subclass";
+++        # this means we allow X.register(X) and interpret it as a no-op.
+++        if issubclass(cls, subclass):
+++            # This would create a cycle, which is bad for the algorithm below
+++            raise RuntimeError("Refusing to create an inheritance cycle")
+++        cls._abc_registry.add(subclass)
+++        ABCMeta._abc_invalidation_counter += 1  # Invalidate negative cache
+++
+++    def _dump_registry(cls, file=None):
+++        """Debug helper to print the ABC registry."""
+++        print >> file, "Class: %s.%s" % (cls.__module__, cls.__name__)
+++        print >> file, "Inv.counter: %s" % ABCMeta._abc_invalidation_counter
+++        for name in sorted(cls.__dict__.keys()):
+++            if name.startswith("_abc_"):
+++                value = getattr(cls, name)
+++                print >> file, "%s: %r" % (name, value)
+++
+++    def __instancecheck__(cls, instance):
+++        """Override for isinstance(instance, cls)."""
+++        # Inline the cache checking when it's simple.
+++        subclass = getattr(instance, '__class__', None)
+++        if subclass in cls._abc_cache:
+++            return True
+++        subtype = type(instance)
+++        # Old-style instances
+++        if subtype is _InstanceType:
+++            subtype = subclass
+++        if subtype is subclass or subclass is None:
+++            if (cls._abc_negative_cache_version ==
+++                ABCMeta._abc_invalidation_counter and
+++                subtype in cls._abc_negative_cache):
+++                return False
+++            # Fall back to the subclass check.
+++            return cls.__subclasscheck__(subtype)
+++        return (cls.__subclasscheck__(subclass) or
+++                cls.__subclasscheck__(subtype))
+++
+++    def __subclasscheck__(cls, subclass):
+++        """Override for issubclass(subclass, cls)."""
+++        # Check cache
+++        if subclass in cls._abc_cache:
+++            return True
+++        # Check negative cache; may have to invalidate
+++        if cls._abc_negative_cache_version < ABCMeta._abc_invalidation_counter:
+++            # Invalidate the negative cache
+++            cls._abc_negative_cache = set()
+++            cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
+++        elif subclass in cls._abc_negative_cache:
+++            return False
+++        # Check the subclass hook
+++        ok = cls.__subclasshook__(subclass)
+++        if ok is not NotImplemented:
+++            assert isinstance(ok, bool)
+++            if ok:
+++                cls._abc_cache.add(subclass)
+++            else:
+++                cls._abc_negative_cache.add(subclass)
+++            return ok
+++        # Check if it's a direct subclass
+++        if cls in getattr(subclass, '__mro__', ()):
+++            cls._abc_cache.add(subclass)
+++            return True
+++        # Check if it's a subclass of a registered class (recursive)
+++        for rcls in cls._abc_registry:
+++            if issubclass(subclass, rcls):
+++                cls._abc_cache.add(subclass)
+++                return True
+++        # Check if it's a subclass of a subclass (recursive)
+++        for scls in cls.__subclasses__():
+++            if issubclass(subclass, scls):
+++                cls._abc_cache.add(subclass)
+++                return True
+++        # No dice; update negative cache
+++        cls._abc_negative_cache.add(subclass)
+++        return False
++diff -up mozilla-aurora/rebase/argparse.py.rebase-dir mozilla-aurora/rebase/argparse.py
++--- mozilla-aurora/rebase/argparse.py.rebase-dir	2014-07-28 18:25:25.000000000 +0200
+++++ mozilla-aurora/rebase/argparse.py	2014-07-28 18:25:25.000000000 +0200
++@@ -0,0 +1,4724 @@
+++# Author: Steven J. Bethard <steven.bethard at gmail.com>.
+++
+++"""Command-line parsing library
+++
+++This module is an optparse-inspired command-line parsing library that:
+++
+++    - handles both optional and positional arguments
+++    - produces highly informative usage messages
+++    - supports parsers that dispatch to sub-parsers
+++
+++The following is a simple usage example that sums integers from the
+++command-line and writes the result to a file::
+++
+++    parser = argparse.ArgumentParser(
+++        description='sum the integers at the command line')
+++    parser.add_argument(
+++        'integers', metavar='int', nargs='+', type=int,
+++        help='an integer to be summed')
+++    parser.add_argument(
+++        '--log', default=sys.stdout, type=argparse.FileType('w'),
+++        help='the file where the sum should be written')
+++    args = parser.parse_args()
+++    args.log.write('%s' % sum(args.integers))
+++    args.log.close()
+++
+++The module contains the following public classes:
+++
+++    - ArgumentParser -- The main entry point for command-line parsing. As the
+++        example above shows, the add_argument() method is used to populate
+++        the parser with actions for optional and positional arguments. Then
+++        the parse_args() method is invoked to convert the args at the
+++        command-line into an object with attributes.
+++
+++    - ArgumentError -- The exception raised by ArgumentParser objects when
+++        there are errors with the parser's actions. Errors raised while
+++        parsing the command-line are caught by ArgumentParser and emitted
+++        as command-line messages.
+++
+++    - FileType -- A factory for defining types of files to be created. As the
+++        example above shows, instances of FileType are typically passed as
+++        the type= argument of add_argument() calls.
+++
+++    - Action -- The base class for parser actions. Typically actions are
+++        selected by passing strings like 'store_true' or 'append_const' to
+++        the action= argument of add_argument(). However, for greater
+++        customization of ArgumentParser actions, subclasses of Action may
+++        be defined and passed as the action= argument.
+++
+++    - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter,
+++        ArgumentDefaultsHelpFormatter -- Formatter classes which
+++        may be passed as the formatter_class= argument to the
+++        ArgumentParser constructor. HelpFormatter is the default,
+++        RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser
+++        not to change the formatting for help text, and
+++        ArgumentDefaultsHelpFormatter adds information about argument defaults
+++        to the help.
+++
+++All other classes in this module are considered implementation details.
+++(Also note that HelpFormatter and RawDescriptionHelpFormatter are only
+++considered public as object names -- the API of the formatter objects is
+++still considered an implementation detail.)
+++"""
+++
+++__version__ = '1.2.1'
+++__all__ = [
+++    'ArgumentParser',
+++    'ArgumentError',
+++    'ArgumentTypeError',
+++    'FileType',
+++    'HelpFormatter',
+++    'ArgumentDefaultsHelpFormatter',
+++    'RawDescriptionHelpFormatter',
+++    'RawTextHelpFormatter',
+++    'Namespace',
+++    'Action',
+++    'ONE_OR_MORE',
+++    'OPTIONAL',
+++    'PARSER',
+++    'REMAINDER',
+++    'SUPPRESS',
+++    'ZERO_OR_MORE',
+++]
+++
+++
+++import copy as _copy
+++import os as _os
+++import re as _re
+++import sys as _sys
+++import textwrap as _textwrap
+++
+++from gettext import gettext as _
+++
+++try:
+++    set
+++except NameError:
+++    # for python < 2.4 compatibility (sets module is there since 2.3):
+++    from sets import Set as set
+++
+++try:
+++    basestring
+++except NameError:
+++    basestring = str
+++
+++try:
+++    sorted
+++except NameError:
+++    # for python < 2.4 compatibility:
+++    def sorted(iterable, reverse=False):
+++        result = list(iterable)
+++        result.sort()
+++        if reverse:
+++            result.reverse()
+++        return result
+++
+++
+++def _callable(obj):
+++    return hasattr(obj, '__call__') or hasattr(obj, '__bases__')
+++
+++
+++SUPPRESS = '==SUPPRESS=='
+++
+++OPTIONAL = '?'
+++ZERO_OR_MORE = '*'
+++ONE_OR_MORE = '+'
+++PARSER = 'A...'
+++REMAINDER = '...'
+++_UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'
+++
+++# =============================
+++# Utility functions and classes
+++# =============================
+++
+++class _AttributeHolder(object):
+++    """Abstract base class that provides __repr__.
+++
+++    The __repr__ method returns a string in the format::
+++        ClassName(attr=name, attr=name, ...)
+++    The attributes are determined either by a class-level attribute,
+++    '_kwarg_names', or by inspecting the instance __dict__.
+++    """
+++
+++    def __repr__(self):
+++        type_name = type(self).__name__
+++        arg_strings = []
+++        for arg in self._get_args():
+++            arg_strings.append(repr(arg))
+++        for name, value in self._get_kwargs():
+++            arg_strings.append('%s=%r' % (name, value))
+++        return '%s(%s)' % (type_name, ', '.join(arg_strings))
+++
+++    def _get_kwargs(self):
+++        return sorted(self.__dict__.items())
+++
+++    def _get_args(self):
+++        return []
+++
+++
+++def _ensure_value(namespace, name, value):
+++    if getattr(namespace, name, None) is None:
+++        setattr(namespace, name, value)
+++    return getattr(namespace, name)
+++
+++
+++# ===============
+++# Formatting Help
+++# ===============
+++
+++class HelpFormatter(object):
+++    """Formatter for generating usage messages and argument help strings.
+++
+++    Only the name of this class is considered a public API. All the methods
+++    provided by the class are considered an implementation detail.
+++    """
+++
+++    def __init__(self,
+++                 prog,
+++                 indent_increment=2,
+++                 max_help_position=24,
+++                 width=None):
+++
+++        # default setting for width
+++        if width is None:
+++            try:
+++                width = int(_os.environ['COLUMNS'])
+++            except (KeyError, ValueError):
+++                width = 80
+++            width -= 2
+++
+++        self._prog = prog
+++        self._indent_increment = indent_increment
+++        self._max_help_position = max_help_position
+++        self._width = width
+++
+++        self._current_indent = 0
+++        self._level = 0
+++        self._action_max_length = 0
+++
+++        self._root_section = self._Section(self, None)
+++        self._current_section = self._root_section
+++
+++        self._whitespace_matcher = _re.compile(r'\s+')
+++        self._long_break_matcher = _re.compile(r'\n\n\n+')
+++
+++    # ===============================
+++    # Section and indentation methods
+++    # ===============================
+++    def _indent(self):
+++        self._current_indent += self._indent_increment
+++        self._level += 1
+++
+++    def _dedent(self):
+++        self._current_indent -= self._indent_increment
+++        assert self._current_indent >= 0, 'Indent decreased below 0.'
+++        self._level -= 1
+++
+++    class _Section(object):
+++
+++        def __init__(self, formatter, parent, heading=None):
+++            self.formatter = formatter
+++            self.parent = parent
+++            self.heading = heading
+++            self.items = []
+++
+++        def format_help(self):
+++            # format the indented section
+++            if self.parent is not None:
+++                self.formatter._indent()
+++            join = self.formatter._join_parts
+++            for func, args in self.items:
+++                func(*args)
+++            item_help = join([func(*args) for func, args in self.items])
+++            if self.parent is not None:
+++                self.formatter._dedent()
+++
+++            # return nothing if the section was empty
+++            if not item_help:
+++                return ''
+++
+++            # add the heading if the section was non-empty
+++            if self.heading is not SUPPRESS and self.heading is not None:
+++                current_indent = self.formatter._current_indent
+++                heading = '%*s%s:\n' % (current_indent, '', self.heading)
+++            else:
+++                heading = ''
+++
+++            # join the section-initial newline, the heading and the help
+++            return join(['\n', heading, item_help, '\n'])
+++
+++    def _add_item(self, func, args):
+++        self._current_section.items.append((func, args))
+++
+++    # ========================
+++    # Message building methods
+++    # ========================
+++    def start_section(self, heading):
+++        self._indent()
+++        section = self._Section(self, self._current_section, heading)
+++        self._add_item(section.format_help, [])
+++        self._current_section = section
+++
+++    def end_section(self):
+++        self._current_section = self._current_section.parent
+++        self._dedent()
+++
+++    def add_text(self, text):
+++        if text is not SUPPRESS and text is not None:
+++            self._add_item(self._format_text, [text])
+++
+++    def add_usage(self, usage, actions, groups, prefix=None):
+++        if usage is not SUPPRESS:
+++            args = usage, actions, groups, prefix
+++            self._add_item(self._format_usage, args)
+++
+++    def add_argument(self, action):
+++        if action.help is not SUPPRESS:
+++
+++            # find all invocations
+++            get_invocation = self._format_action_invocation
+++            invocations = [get_invocation(action)]
+++            for subaction in self._iter_indented_subactions(action):
+++                invocations.append(get_invocation(subaction))
+++
+++            # update the maximum item length
+++            invocation_length = max([len(s) for s in invocations])
+++            action_length = invocation_length + self._current_indent
+++            self._action_max_length = max(self._action_max_length,
+++                                          action_length)
+++
+++            # add the item to the list
+++            self._add_item(self._format_action, [action])
+++
+++    def add_arguments(self, actions):
+++        for action in actions:
+++            self.add_argument(action)
+++
+++    # =======================
+++    # Help-formatting methods
+++    # =======================
+++    def format_help(self):
+++        help = self._root_section.format_help()
+++        if help:
+++            help = self._long_break_matcher.sub('\n\n', help)
+++            help = help.strip('\n') + '\n'
+++        return help
+++
+++    def _join_parts(self, part_strings):
+++        return ''.join([part
+++                        for part in part_strings
+++                        if part and part is not SUPPRESS])
+++
+++    def _format_usage(self, usage, actions, groups, prefix):
+++        if prefix is None:
+++            prefix = _('usage: ')
+++
+++        # if usage is specified, use that
+++        if usage is not None:
+++            usage = usage % dict(prog=self._prog)
+++
+++        # if no optionals or positionals are available, usage is just prog
+++        elif usage is None and not actions:
+++            usage = '%(prog)s' % dict(prog=self._prog)
+++
+++        # if optionals and positionals are available, calculate usage
+++        elif usage is None:
+++            prog = '%(prog)s' % dict(prog=self._prog)
+++
+++            # split optionals from positionals
+++            optionals = []
+++            positionals = []
+++            for action in actions:
+++                if action.option_strings:
+++                    optionals.append(action)
+++                else:
+++                    positionals.append(action)
+++
+++            # build full usage string
+++            format = self._format_actions_usage
+++            action_usage = format(optionals + positionals, groups)
+++            usage = ' '.join([s for s in [prog, action_usage] if s])
+++
+++            # wrap the usage parts if it's too long
+++            text_width = self._width - self._current_indent
+++            if len(prefix) + len(usage) > text_width:
+++
+++                # break usage into wrappable parts
+++                part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'
+++                opt_usage = format(optionals, groups)
+++                pos_usage = format(positionals, groups)
+++                opt_parts = _re.findall(part_regexp, opt_usage)
+++                pos_parts = _re.findall(part_regexp, pos_usage)
+++                assert ' '.join(opt_parts) == opt_usage
+++                assert ' '.join(pos_parts) == pos_usage
+++
+++                # helper for wrapping lines
+++                def get_lines(parts, indent, prefix=None):
+++                    lines = []
+++                    line = []
+++                    if prefix is not None:
+++                        line_len = len(prefix) - 1
+++                    else:
+++                        line_len = len(indent) - 1
+++                    for part in parts:
+++                        if line_len + 1 + len(part) > text_width:
+++                            lines.append(indent + ' '.join(line))
+++                            line = []
+++                            line_len = len(indent) - 1
+++                        line.append(part)
+++                        line_len += len(part) + 1
+++                    if line:
+++                        lines.append(indent + ' '.join(line))
+++                    if prefix is not None:
+++                        lines[0] = lines[0][len(indent):]
+++                    return lines
+++
+++                # if prog is short, follow it with optionals or positionals
+++                if len(prefix) + len(prog) <= 0.75 * text_width:
+++                    indent = ' ' * (len(prefix) + len(prog) + 1)
+++                    if opt_parts:
+++                        lines = get_lines([prog] + opt_parts, indent, prefix)
+++                        lines.extend(get_lines(pos_parts, indent))
+++                    elif pos_parts:
+++                        lines = get_lines([prog] + pos_parts, indent, prefix)
+++                    else:
+++                        lines = [prog]
+++
+++                # if prog is long, put it on its own line
+++                else:
+++                    indent = ' ' * len(prefix)
+++                    parts = opt_parts + pos_parts
+++                    lines = get_lines(parts, indent)
+++                    if len(lines) > 1:
+++                        lines = []
+++                        lines.extend(get_lines(opt_parts, indent))
+++                        lines.extend(get_lines(pos_parts, indent))
+++                    lines = [prog] + lines
+++
+++                # join lines into usage
+++                usage = '\n'.join(lines)
+++
+++        # prefix with 'usage:'
+++        return '%s%s\n\n' % (prefix, usage)
+++
+++    def _format_actions_usage(self, actions, groups):
+++        # find group indices and identify actions in groups
+++        group_actions = set()
+++        inserts = {}
+++        for group in groups:
+++            try:
+++                start = actions.index(group._group_actions[0])
+++            except ValueError:
+++                continue
+++            else:
+++                end = start + len(group._group_actions)
+++                if actions[start:end] == group._group_actions:
+++                    for action in group._group_actions:
+++                        group_actions.add(action)
+++                    if not group.required:
+++                        if start in inserts:
+++                            inserts[start] += ' ['
+++                        else:
+++                            inserts[start] = '['
+++                        inserts[end] = ']'
+++                    else:
+++                        if start in inserts:
+++                            inserts[start] += ' ('
+++                        else:
+++                            inserts[start] = '('
+++                        inserts[end] = ')'
+++                    for i in range(start + 1, end):
+++                        inserts[i] = '|'
+++
+++        # collect all actions format strings
+++        parts = []
+++        for i, action in enumerate(actions):
+++
+++            # suppressed arguments are marked with None
+++            # remove | separators for suppressed arguments
+++            if action.help is SUPPRESS:
+++                parts.append(None)
+++                if inserts.get(i) == '|':
+++                    inserts.pop(i)
+++                elif inserts.get(i + 1) == '|':
+++                    inserts.pop(i + 1)
+++
+++            # produce all arg strings
+++            elif not action.option_strings:
+++                part = self._format_args(action, action.dest)
+++
+++                # if it's in a group, strip the outer []
+++                if action in group_actions:
+++                    if part[0] == '[' and part[-1] == ']':
+++                        part = part[1:-1]
+++
+++                # add the action string to the list
+++                parts.append(part)
+++
+++            # produce the first way to invoke the option in brackets
+++            else:
+++                option_string = action.option_strings[0]
+++
+++                # if the Optional doesn't take a value, format is:
+++                #    -s or --long
+++                if action.nargs == 0:
+++                    part = '%s' % option_string
+++
+++                # if the Optional takes a value, format is:
+++                #    -s ARGS or --long ARGS
+++                else:
+++                    default = action.dest.upper()
+++                    args_string = self._format_args(action, default)
+++                    part = '%s %s' % (option_string, args_string)
+++
+++                # make it look optional if it's not required or in a group
+++                if not action.required and action not in group_actions:
+++                    part = '[%s]' % part
+++
+++                # add the action string to the list
+++                parts.append(part)
+++
+++        # insert things at the necessary indices
+++        for i in sorted(inserts, reverse=True):
+++            parts[i:i] = [inserts[i]]
+++
+++        # join all the action items with spaces
+++        text = ' '.join([item for item in parts if item is not None])
+++
+++        # clean up separators for mutually exclusive groups
+++        open = r'[\[(]'
+++        close = r'[\])]'
+++        text = _re.sub(r'(%s) ' % open, r'\1', text)
+++        text = _re.sub(r' (%s)' % close, r'\1', text)
+++        text = _re.sub(r'%s *%s' % (open, close), r'', text)
+++        text = _re.sub(r'\(([^|]*)\)', r'\1', text)
+++        text = text.strip()
+++
+++        # return the text
+++        return text
+++
+++    def _format_text(self, text):
+++        if '%(prog)' in text:
+++            text = text % dict(prog=self._prog)
+++        text_width = self._width - self._current_indent
+++        indent = ' ' * self._current_indent
+++        return self._fill_text(text, text_width, indent) + '\n\n'
+++
+++    def _format_action(self, action):
+++        # determine the required width and the entry label
+++        help_position = min(self._action_max_length + 2,
+++                            self._max_help_position)
+++        help_width = self._width - help_position
+++        action_width = help_position - self._current_indent - 2
+++        action_header = self._format_action_invocation(action)
+++
+++        # ho nelp; start on same line and add a final newline
+++        if not action.help:
+++            tup = self._current_indent, '', action_header
+++            action_header = '%*s%s\n' % tup
+++
+++        # short action name; start on the same line and pad two spaces
+++        elif len(action_header) <= action_width:
+++            tup = self._current_indent, '', action_width, action_header
+++            action_header = '%*s%-*s  ' % tup
+++            indent_first = 0
+++
+++        # long action name; start on the next line
+++        else:
+++            tup = self._current_indent, '', action_header
+++            action_header = '%*s%s\n' % tup
+++            indent_first = help_position
+++
+++        # collect the pieces of the action help
+++        parts = [action_header]
+++
+++        # if there was help for the action, add lines of help text
+++        if action.help:
+++            help_text = self._expand_help(action)
+++            help_lines = self._split_lines(help_text, help_width)
+++            parts.append('%*s%s\n' % (indent_first, '', help_lines[0]))
+++            for line in help_lines[1:]:
+++                parts.append('%*s%s\n' % (help_position, '', line))
+++
+++        # or add a newline if the description doesn't end with one
+++        elif not action_header.endswith('\n'):
+++            parts.append('\n')
+++
+++        # if there are any sub-actions, add their help as well
+++        for subaction in self._iter_indented_subactions(action):
+++            parts.append(self._format_action(subaction))
+++
+++        # return a single string
+++        return self._join_parts(parts)
+++
+++    def _format_action_invocation(self, action):
+++        if not action.option_strings:
+++            metavar, = self._metavar_formatter(action, action.dest)(1)
+++            return metavar
+++
+++        else:
+++            parts = []
+++
+++            # if the Optional doesn't take a value, format is:
+++            #    -s, --long
+++            if action.nargs == 0:
+++                parts.extend(action.option_strings)
+++
+++            # if the Optional takes a value, format is:
+++            #    -s ARGS, --long ARGS
+++            else:
+++                default = action.dest.upper()
+++                args_string = self._format_args(action, default)
+++                for option_string in action.option_strings:
+++                    parts.append('%s %s' % (option_string, args_string))
+++
+++            return ', '.join(parts)
+++
+++    def _metavar_formatter(self, action, default_metavar):
+++        if action.metavar is not None:
+++            result = action.metavar
+++        elif action.choices is not None:
+++            choice_strs = [str(choice) for choice in action.choices]
+++            result = '{%s}' % ','.join(choice_strs)
+++        else:
+++            result = default_metavar
+++
+++        def format(tuple_size):
+++            if isinstance(result, tuple):
+++                return result
+++            else:
+++                return (result, ) * tuple_size
+++        return format
+++
+++    def _format_args(self, action, default_metavar):
+++        get_metavar = self._metavar_formatter(action, default_metavar)
+++        if action.nargs is None:
+++            result = '%s' % get_metavar(1)
+++        elif action.nargs == OPTIONAL:
+++            result = '[%s]' % get_metavar(1)
+++        elif action.nargs == ZERO_OR_MORE:
+++            result = '[%s [%s ...]]' % get_metavar(2)
+++        elif action.nargs == ONE_OR_MORE:
+++            result = '%s [%s ...]' % get_metavar(2)
+++        elif action.nargs == REMAINDER:
+++            result = '...'
+++        elif action.nargs == PARSER:
+++            result = '%s ...' % get_metavar(1)
+++        else:
+++            formats = ['%s' for _ in range(action.nargs)]
+++            result = ' '.join(formats) % get_metavar(action.nargs)
+++        return result
+++
+++    def _expand_help(self, action):
+++        params = dict(vars(action), prog=self._prog)
+++        for name in list(params):
+++            if params[name] is SUPPRESS:
+++                del params[name]
+++        for name in list(params):
+++            if hasattr(params[name], '__name__'):
+++                params[name] = params[name].__name__
+++        if params.get('choices') is not None:
+++            choices_str = ', '.join([str(c) for c in params['choices']])
+++            params['choices'] = choices_str
+++        return self._get_help_string(action) % params
+++
+++    def _iter_indented_subactions(self, action):
+++        try:
+++            get_subactions = action._get_subactions
+++        except AttributeError:
+++            pass
+++        else:
+++            self._indent()
+++            for subaction in get_subactions():
+++                yield subaction
+++            self._dedent()
+++
+++    def _split_lines(self, text, width):
+++        text = self._whitespace_matcher.sub(' ', text).strip()
+++        return _textwrap.wrap(text, width)
+++
+++    def _fill_text(self, text, width, indent):
+++        text = self._whitespace_matcher.sub(' ', text).strip()
+++        return _textwrap.fill(text, width, initial_indent=indent,
+++                                           subsequent_indent=indent)
+++
+++    def _get_help_string(self, action):
+++        return action.help
+++
+++
+++class RawDescriptionHelpFormatter(HelpFormatter):
+++    """Help message formatter which retains any formatting in descriptions.
+++
+++    Only the name of this class is considered a public API. All the methods
+++    provided by the class are considered an implementation detail.
+++    """
+++
+++    def _fill_text(self, text, width, indent):
+++        return ''.join([indent + line for line in text.splitlines(True)])
+++
+++
+++class RawTextHelpFormatter(RawDescriptionHelpFormatter):
+++    """Help message formatter which retains formatting of all help text.
+++
+++    Only the name of this class is considered a public API. All the methods
+++    provided by the class are considered an implementation detail.
+++    """
+++
+++    def _split_lines(self, text, width):
+++        return text.splitlines()
+++
+++
+++class ArgumentDefaultsHelpFormatter(HelpFormatter):
+++    """Help message formatter which adds default values to argument help.
+++
+++    Only the name of this class is considered a public API. All the methods
+++    provided by the class are considered an implementation detail.
+++    """
+++
+++    def _get_help_string(self, action):
+++        help = action.help
+++        if '%(default)' not in action.help:
+++            if action.default is not SUPPRESS:
+++                defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
+++                if action.option_strings or action.nargs in defaulting_nargs:
+++                    help += ' (default: %(default)s)'
+++        return help
+++
+++
+++# =====================
+++# Options and Arguments
+++# =====================
+++
+++def _get_action_name(argument):
+++    if argument is None:
+++        return None
+++    elif argument.option_strings:
+++        return  '/'.join(argument.option_strings)
+++    elif argument.metavar not in (None, SUPPRESS):
+++        return argument.metavar
+++    elif argument.dest not in (None, SUPPRESS):
+++        return argument.dest
+++    else:
+++        return None
+++
+++
+++class ArgumentError(Exception):
+++    """An error from creating or using an argument (optional or positional).
+++
+++    The string value of this exception is the message, augmented with
+++    information about the argument that caused it.
+++    """
+++
+++    def __init__(self, argument, message):
+++        self.argument_name = _get_action_name(argument)
+++        self.message = message
+++
+++    def __str__(self):
+++        if self.argument_name is None:
+++            format = '%(message)s'
+++        else:
+++            format = 'argument %(argument_name)s: %(message)s'
+++        return format % dict(message=self.message,
+++                             argument_name=self.argument_name)
+++
+++
+++class ArgumentTypeError(Exception):
+++    """An error from trying to convert a command line string to a type."""
+++    pass
+++
+++
+++# ==============
+++# Action classes
+++# ==============
+++
+++class Action(_AttributeHolder):
+++    """Information about how to convert command line strings to Python objects.
+++
+++    Action objects are used by an ArgumentParser to represent the information
+++    needed to parse a single argument from one or more strings from the
+++    command line. The keyword arguments to the Action constructor are also
+++    all attributes of Action instances.
+++
+++    Keyword Arguments:
+++
+++        - option_strings -- A list of command-line option strings which
+++            should be associated with this action.
+++
+++        - dest -- The name of the attribute to hold the created object(s)
+++
+++        - nargs -- The number of command-line arguments that should be
+++            consumed. By default, one argument will be consumed and a single
+++            value will be produced.  Other values include:
+++                - N (an integer) consumes N arguments (and produces a list)
+++                - '?' consumes zero or one arguments
+++                - '*' consumes zero or more arguments (and produces a list)
+++                - '+' consumes one or more arguments (and produces a list)
+++            Note that the difference between the default and nargs=1 is that
+++            with the default, a single value will be produced, while with
+++            nargs=1, a list containing a single value will be produced.
+++
+++        - const -- The value to be produced if the option is specified and the
+++            option uses an action that takes no values.
+++
+++        - default -- The value to be produced if the option is not specified.
+++
+++        - type -- The type which the command-line arguments should be converted
+++            to, should be one of 'string', 'int', 'float', 'complex' or a
+++            callable object that accepts a single string argument. If None,
+++            'string' is assumed.
+++
+++        - choices -- A container of values that should be allowed. If not None,
+++            after a command-line argument has been converted to the appropriate
+++            type, an exception will be raised if it is not a member of this
+++            collection.
+++
+++        - required -- True if the action must always be specified at the
+++            command line. This is only meaningful for optional command-line
+++            arguments.
+++
+++        - help -- The help string describing the argument.
+++
+++        - metavar -- The name to be used for the option's argument with the
+++            help string. If None, the 'dest' value will be used as the name.
+++    """
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest,
+++                 nargs=None,
+++                 const=None,
+++                 default=None,
+++                 type=None,
+++                 choices=None,
+++                 required=False,
+++                 help=None,
+++                 metavar=None):
+++        self.option_strings = option_strings
+++        self.dest = dest
+++        self.nargs = nargs
+++        self.const = const
+++        self.default = default
+++        self.type = type
+++        self.choices = choices
+++        self.required = required
+++        self.help = help
+++        self.metavar = metavar
+++
+++    def _get_kwargs(self):
+++        names = [
+++            'option_strings',
+++            'dest',
+++            'nargs',
+++            'const',
+++            'default',
+++            'type',
+++            'choices',
+++            'help',
+++            'metavar',
+++        ]
+++        return [(name, getattr(self, name)) for name in names]
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        raise NotImplementedError(_('.__call__() not defined'))
+++
+++
+++class _StoreAction(Action):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest,
+++                 nargs=None,
+++                 const=None,
+++                 default=None,
+++                 type=None,
+++                 choices=None,
+++                 required=False,
+++                 help=None,
+++                 metavar=None):
+++        if nargs == 0:
+++            raise ValueError('nargs for store actions must be > 0; if you '
+++                             'have nothing to store, actions such as store '
+++                             'true or store const may be more appropriate')
+++        if const is not None and nargs != OPTIONAL:
+++            raise ValueError('nargs must be %r to supply const' % OPTIONAL)
+++        super(_StoreAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            nargs=nargs,
+++            const=const,
+++            default=default,
+++            type=type,
+++            choices=choices,
+++            required=required,
+++            help=help,
+++            metavar=metavar)
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        setattr(namespace, self.dest, values)
+++
+++
+++class _StoreConstAction(Action):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest,
+++                 const,
+++                 default=None,
+++                 required=False,
+++                 help=None,
+++                 metavar=None):
+++        super(_StoreConstAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            nargs=0,
+++            const=const,
+++            default=default,
+++            required=required,
+++            help=help)
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        setattr(namespace, self.dest, self.const)
+++
+++
+++class _StoreTrueAction(_StoreConstAction):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest,
+++                 default=False,
+++                 required=False,
+++                 help=None):
+++        super(_StoreTrueAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            const=True,
+++            default=default,
+++            required=required,
+++            help=help)
+++
+++
+++class _StoreFalseAction(_StoreConstAction):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest,
+++                 default=True,
+++                 required=False,
+++                 help=None):
+++        super(_StoreFalseAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            const=False,
+++            default=default,
+++            required=required,
+++            help=help)
+++
+++
+++class _AppendAction(Action):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest,
+++                 nargs=None,
+++                 const=None,
+++                 default=None,
+++                 type=None,
+++                 choices=None,
+++                 required=False,
+++                 help=None,
+++                 metavar=None):
+++        if nargs == 0:
+++            raise ValueError('nargs for append actions must be > 0; if arg '
+++                             'strings are not supplying the value to append, '
+++                             'the append const action may be more appropriate')
+++        if const is not None and nargs != OPTIONAL:
+++            raise ValueError('nargs must be %r to supply const' % OPTIONAL)
+++        super(_AppendAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            nargs=nargs,
+++            const=const,
+++            default=default,
+++            type=type,
+++            choices=choices,
+++            required=required,
+++            help=help,
+++            metavar=metavar)
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        items = _copy.copy(_ensure_value(namespace, self.dest, []))
+++        items.append(values)
+++        setattr(namespace, self.dest, items)
+++
+++
+++class _AppendConstAction(Action):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest,
+++                 const,
+++                 default=None,
+++                 required=False,
+++                 help=None,
+++                 metavar=None):
+++        super(_AppendConstAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            nargs=0,
+++            const=const,
+++            default=default,
+++            required=required,
+++            help=help,
+++            metavar=metavar)
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        items = _copy.copy(_ensure_value(namespace, self.dest, []))
+++        items.append(self.const)
+++        setattr(namespace, self.dest, items)
+++
+++
+++class _CountAction(Action):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest,
+++                 default=None,
+++                 required=False,
+++                 help=None):
+++        super(_CountAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            nargs=0,
+++            default=default,
+++            required=required,
+++            help=help)
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        new_count = _ensure_value(namespace, self.dest, 0) + 1
+++        setattr(namespace, self.dest, new_count)
+++
+++
+++class _HelpAction(Action):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest=SUPPRESS,
+++                 default=SUPPRESS,
+++                 help=None):
+++        super(_HelpAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            default=default,
+++            nargs=0,
+++            help=help)
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        parser.print_help()
+++        parser.exit()
+++
+++
+++class _VersionAction(Action):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 version=None,
+++                 dest=SUPPRESS,
+++                 default=SUPPRESS,
+++                 help="show program's version number and exit"):
+++        super(_VersionAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            default=default,
+++            nargs=0,
+++            help=help)
+++        self.version = version
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        version = self.version
+++        if version is None:
+++            version = parser.version
+++        formatter = parser._get_formatter()
+++        formatter.add_text(version)
+++        parser.exit(message=formatter.format_help())
+++
+++
+++class _SubParsersAction(Action):
+++
+++    class _ChoicesPseudoAction(Action):
+++
+++        def __init__(self, name, help):
+++            sup = super(_SubParsersAction._ChoicesPseudoAction, self)
+++            sup.__init__(option_strings=[], dest=name, help=help)
+++
+++    def __init__(self,
+++                 option_strings,
+++                 prog,
+++                 parser_class,
+++                 dest=SUPPRESS,
+++                 help=None,
+++                 metavar=None):
+++
+++        self._prog_prefix = prog
+++        self._parser_class = parser_class
+++        self._name_parser_map = {}
+++        self._choices_actions = []
+++
+++        super(_SubParsersAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            nargs=PARSER,
+++            choices=self._name_parser_map,
+++            help=help,
+++            metavar=metavar)
+++
+++    def add_parser(self, name, **kwargs):
+++        # set prog from the existing prefix
+++        if kwargs.get('prog') is None:
+++            kwargs['prog'] = '%s %s' % (self._prog_prefix, name)
+++
+++        # create a pseudo-action to hold the choice help
+++        if 'help' in kwargs:
+++            help = kwargs.pop('help')
+++            choice_action = self._ChoicesPseudoAction(name, help)
+++            self._choices_actions.append(choice_action)
+++
+++        # create the parser and add it to the map
+++        parser = self._parser_class(**kwargs)
+++        self._name_parser_map[name] = parser
+++        return parser
+++
+++    def _get_subactions(self):
+++        return self._choices_actions
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        parser_name = values[0]
+++        arg_strings = values[1:]
+++
+++        # set the parser name if requested
+++        if self.dest is not SUPPRESS:
+++            setattr(namespace, self.dest, parser_name)
+++
+++        # select the parser
+++        try:
+++            parser = self._name_parser_map[parser_name]
+++        except KeyError:
+++            tup = parser_name, ', '.join(self._name_parser_map)
+++            msg = _('unknown parser %r (choices: %s)' % tup)
+++            raise ArgumentError(self, msg)
+++
+++        # parse all the remaining options into the namespace
+++        # store any unrecognized options on the object, so that the top
+++        # level parser can decide what to do with them
+++        namespace, arg_strings = parser.parse_known_args(arg_strings, namespace)
+++        if arg_strings:
+++            vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, [])
+++            getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings)
+++
+++
+++# ==============
+++# Type classes
+++# ==============
+++
+++class FileType(object):
+++    """Factory for creating file object types
+++
+++    Instances of FileType are typically passed as type= arguments to the
+++    ArgumentParser add_argument() method.
+++
+++    Keyword Arguments:
+++        - mode -- A string indicating how the file is to be opened. Accepts the
+++            same values as the builtin open() function.
+++        - bufsize -- The file's desired buffer size. Accepts the same values as
+++            the builtin open() function.
+++    """
+++
+++    def __init__(self, mode='r', bufsize=None):
+++        self._mode = mode
+++        self._bufsize = bufsize
+++
+++    def __call__(self, string):
+++        # the special argument "-" means sys.std{in,out}
+++        if string == '-':
+++            if 'r' in self._mode:
+++                return _sys.stdin
+++            elif 'w' in self._mode:
+++                return _sys.stdout
+++            else:
+++                msg = _('argument "-" with mode %r' % self._mode)
+++                raise ValueError(msg)
+++
+++        # all other arguments are used as file names
+++        if self._bufsize:
+++            return open(string, self._mode, self._bufsize)
+++        else:
+++            return open(string, self._mode)
+++
+++    def __repr__(self):
+++        args = [self._mode, self._bufsize]
+++        args_str = ', '.join([repr(arg) for arg in args if arg is not None])
+++        return '%s(%s)' % (type(self).__name__, args_str)
+++
+++# ===========================
+++# Optional and Positional Parsing
+++# ===========================
+++
+++class Namespace(_AttributeHolder):
+++    """Simple object for storing attributes.
+++
+++    Implements equality by attribute names and values, and provides a simple
+++    string representation.
+++    """
+++
+++    def __init__(self, **kwargs):
+++        for name in kwargs:
+++            setattr(self, name, kwargs[name])
+++
+++    __hash__ = None
+++
+++    def __eq__(self, other):
+++        return vars(self) == vars(other)
+++
+++    def __ne__(self, other):
+++        return not (self == other)
+++
+++    def __contains__(self, key):
+++        return key in self.__dict__
+++
+++
+++class _ActionsContainer(object):
+++
+++    def __init__(self,
+++                 description,
+++                 prefix_chars,
+++                 argument_default,
+++                 conflict_handler):
+++        super(_ActionsContainer, self).__init__()
+++
+++        self.description = description
+++        self.argument_default = argument_default
+++        self.prefix_chars = prefix_chars
+++        self.conflict_handler = conflict_handler
+++
+++        # set up registries
+++        self._registries = {}
+++
+++        # register actions
+++        self.register('action', None, _StoreAction)
+++        self.register('action', 'store', _StoreAction)
+++        self.register('action', 'store_const', _StoreConstAction)
+++        self.register('action', 'store_true', _StoreTrueAction)
+++        self.register('action', 'store_false', _StoreFalseAction)
+++        self.register('action', 'append', _AppendAction)
+++        self.register('action', 'append_const', _AppendConstAction)
+++        self.register('action', 'count', _CountAction)
+++        self.register('action', 'help', _HelpAction)
+++        self.register('action', 'version', _VersionAction)
+++        self.register('action', 'parsers', _SubParsersAction)
+++
+++        # raise an exception if the conflict handler is invalid
+++        self._get_handler()
+++
+++        # action storage
+++        self._actions = []
+++        self._option_string_actions = {}
+++
+++        # groups
+++        self._action_groups = []
+++        self._mutually_exclusive_groups = []
+++
+++        # defaults storage
+++        self._defaults = {}
+++
+++        # determines whether an "option" looks like a negative number
+++        self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$')
+++
+++        # whether or not there are any optionals that look like negative
+++        # numbers -- uses a list so it can be shared and edited
+++        self._has_negative_number_optionals = []
+++
+++    # ====================
+++    # Registration methods
+++    # ====================
+++    def register(self, registry_name, value, object):
+++        registry = self._registries.setdefault(registry_name, {})
+++        registry[value] = object
+++
+++    def _registry_get(self, registry_name, value, default=None):
+++        return self._registries[registry_name].get(value, default)
+++
+++    # ==================================
+++    # Namespace default accessor methods
+++    # ==================================
+++    def set_defaults(self, **kwargs):
+++        self._defaults.update(kwargs)
+++
+++        # if these defaults match any existing arguments, replace
+++        # the previous default on the object with the new one
+++        for action in self._actions:
+++            if action.dest in kwargs:
+++                action.default = kwargs[action.dest]
+++
+++    def get_default(self, dest):
+++        for action in self._actions:
+++            if action.dest == dest and action.default is not None:
+++                return action.default
+++        return self._defaults.get(dest, None)
+++
+++
+++    # =======================
+++    # Adding argument actions
+++    # =======================
+++    def add_argument(self, *args, **kwargs):
+++        """
+++        add_argument(dest, ..., name=value, ...)
+++        add_argument(option_string, option_string, ..., name=value, ...)
+++        """
+++
+++        # if no positional args are supplied or only one is supplied and
+++        # it doesn't look like an option string, parse a positional
+++        # argument
+++        chars = self.prefix_chars
+++        if not args or len(args) == 1 and args[0][0] not in chars:
+++            if args and 'dest' in kwargs:
+++                raise ValueError('dest supplied twice for positional argument')
+++            kwargs = self._get_positional_kwargs(*args, **kwargs)
+++
+++        # otherwise, we're adding an optional argument
+++        else:
+++            kwargs = self._get_optional_kwargs(*args, **kwargs)
+++
+++        # if no default was supplied, use the parser-level default
+++        if 'default' not in kwargs:
+++            dest = kwargs['dest']
+++            if dest in self._defaults:
+++                kwargs['default'] = self._defaults[dest]
+++            elif self.argument_default is not None:
+++                kwargs['default'] = self.argument_default
+++
+++        # create the action object, and add it to the parser
+++        action_class = self._pop_action_class(kwargs)
+++        if not _callable(action_class):
+++            raise ValueError('unknown action "%s"' % action_class)
+++        action = action_class(**kwargs)
+++
+++        # raise an error if the action type is not callable
+++        type_func = self._registry_get('type', action.type, action.type)
+++        if not _callable(type_func):
+++            raise ValueError('%r is not callable' % type_func)
+++
+++        return self._add_action(action)
+++
+++    def add_argument_group(self, *args, **kwargs):
+++        group = _ArgumentGroup(self, *args, **kwargs)
+++        self._action_groups.append(group)
+++        return group
+++
+++    def add_mutually_exclusive_group(self, **kwargs):
+++        group = _MutuallyExclusiveGroup(self, **kwargs)
+++        self._mutually_exclusive_groups.append(group)
+++        return group
+++
+++    def _add_action(self, action):
+++        # resolve any conflicts
+++        self._check_conflict(action)
+++
+++        # add to actions list
+++        self._actions.append(action)
+++        action.container = self
+++
+++        # index the action by any option strings it has
+++        for option_string in action.option_strings:
+++            self._option_string_actions[option_string] = action
+++
+++        # set the flag if any option strings look like negative numbers
+++        for option_string in action.option_strings:
+++            if self._negative_number_matcher.match(option_string):
+++                if not self._has_negative_number_optionals:
+++                    self._has_negative_number_optionals.append(True)
+++
+++        # return the created action
+++        return action
+++
+++    def _remove_action(self, action):
+++        self._actions.remove(action)
+++
+++    def _add_container_actions(self, container):
+++        # collect groups by titles
+++        title_group_map = {}
+++        for group in self._action_groups:
+++            if group.title in title_group_map:
+++                msg = _('cannot merge actions - two groups are named %r')
+++                raise ValueError(msg % (group.title))
+++            title_group_map[group.title] = group
+++
+++        # map each action to its group
+++        group_map = {}
+++        for group in container._action_groups:
+++
+++            # if a group with the title exists, use that, otherwise
+++            # create a new group matching the container's group
+++            if group.title not in title_group_map:
+++                title_group_map[group.title] = self.add_argument_group(
+++                    title=group.title,
+++                    description=group.description,
+++                    conflict_handler=group.conflict_handler)
+++
+++            # map the actions to their new group
+++            for action in group._group_actions:
+++                group_map[action] = title_group_map[group.title]
+++
+++        # add container's mutually exclusive groups
+++        # NOTE: if add_mutually_exclusive_group ever gains title= and
+++        # description= then this code will need to be expanded as above
+++        for group in container._mutually_exclusive_groups:
+++            mutex_group = self.add_mutually_exclusive_group(
+++                required=group.required)
+++
+++            # map the actions to their new mutex group
+++            for action in group._group_actions:
+++                group_map[action] = mutex_group
+++
+++        # add all actions to this container or their group
+++        for action in container._actions:
+++            group_map.get(action, self)._add_action(action)
+++
+++    def _get_positional_kwargs(self, dest, **kwargs):
+++        # make sure required is not specified
+++        if 'required' in kwargs:
+++            msg = _("'required' is an invalid argument for positionals")
+++            raise TypeError(msg)
+++
+++        # mark positional arguments as required if at least one is
+++        # always required
+++        if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]:
+++            kwargs['required'] = True
+++        if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:
+++            kwargs['required'] = True
+++
+++        # return the keyword arguments with no option strings
+++        return dict(kwargs, dest=dest, option_strings=[])
+++
+++    def _get_optional_kwargs(self, *args, **kwargs):
+++        # determine short and long option strings
+++        option_strings = []
+++        long_option_strings = []
+++        for option_string in args:
+++            # error on strings that don't start with an appropriate prefix
+++            if not option_string[0] in self.prefix_chars:
+++                msg = _('invalid option string %r: '
+++                        'must start with a character %r')
+++                tup = option_string, self.prefix_chars
+++                raise ValueError(msg % tup)
+++
+++            # strings starting with two prefix characters are long options
+++            option_strings.append(option_string)
+++            if option_string[0] in self.prefix_chars:
+++                if len(option_string) > 1:
+++                    if option_string[1] in self.prefix_chars:
+++                        long_option_strings.append(option_string)
+++
+++        # infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x'
+++        dest = kwargs.pop('dest', None)
+++        if dest is None:
+++            if long_option_strings:
+++                dest_option_string = long_option_strings[0]
+++            else:
+++                dest_option_string = option_strings[0]
+++            dest = dest_option_string.lstrip(self.prefix_chars)
+++            if not dest:
+++                msg = _('dest= is required for options like %r')
+++                raise ValueError(msg % option_string)
+++            dest = dest.replace('-', '_')
+++
+++        # return the updated keyword arguments
+++        return dict(kwargs, dest=dest, option_strings=option_strings)
+++
+++    def _pop_action_class(self, kwargs, default=None):
+++        action = kwargs.pop('action', default)
+++        return self._registry_get('action', action, action)
+++
+++    def _get_handler(self):
+++        # determine function from conflict handler string
+++        handler_func_name = '_handle_conflict_%s' % self.conflict_handler
+++        try:
+++            return getattr(self, handler_func_name)
+++        except AttributeError:
+++            msg = _('invalid conflict_resolution value: %r')
+++            raise ValueError(msg % self.conflict_handler)
+++
+++    def _check_conflict(self, action):
+++
+++        # find all options that conflict with this option
+++        confl_optionals = []
+++        for option_string in action.option_strings:
+++            if option_string in self._option_string_actions:
+++                confl_optional = self._option_string_actions[option_string]
+++                confl_optionals.append((option_string, confl_optional))
+++
+++        # resolve any conflicts
+++        if confl_optionals:
+++            conflict_handler = self._get_handler()
+++            conflict_handler(action, confl_optionals)
+++
+++    def _handle_conflict_error(self, action, conflicting_actions):
+++        message = _('conflicting option string(s): %s')
+++        conflict_string = ', '.join([option_string
+++                                     for option_string, action
+++                                     in conflicting_actions])
+++        raise ArgumentError(action, message % conflict_string)
+++
+++    def _handle_conflict_resolve(self, action, conflicting_actions):
+++
+++        # remove all conflicting options
+++        for option_string, action in conflicting_actions:
+++
+++            # remove the conflicting option
+++            action.option_strings.remove(option_string)
+++            self._option_string_actions.pop(option_string, None)
+++
+++            # if the option now has no option string, remove it from the
+++            # container holding it
+++            if not action.option_strings:
+++                action.container._remove_action(action)
+++
+++
+++class _ArgumentGroup(_ActionsContainer):
+++
+++    def __init__(self, container, title=None, description=None, **kwargs):
+++        # add any missing keyword arguments by checking the container
+++        update = kwargs.setdefault
+++        update('conflict_handler', container.conflict_handler)
+++        update('prefix_chars', container.prefix_chars)
+++        update('argument_default', container.argument_default)
+++        super_init = super(_ArgumentGroup, self).__init__
+++        super_init(description=description, **kwargs)
+++
+++        # group attributes
+++        self.title = title
+++        self._group_actions = []
+++
+++        # share most attributes with the container
+++        self._registries = container._registries
+++        self._actions = container._actions
+++        self._option_string_actions = container._option_string_actions
+++        self._defaults = container._defaults
+++        self._has_negative_number_optionals = \
+++            container._has_negative_number_optionals
+++
+++    def _add_action(self, action):
+++        action = super(_ArgumentGroup, self)._add_action(action)
+++        self._group_actions.append(action)
+++        return action
+++
+++    def _remove_action(self, action):
+++        super(_ArgumentGroup, self)._remove_action(action)
+++        self._group_actions.remove(action)
+++
+++
+++class _MutuallyExclusiveGroup(_ArgumentGroup):
+++
+++    def __init__(self, container, required=False):
+++        super(_MutuallyExclusiveGroup, self).__init__(container)
+++        self.required = required
+++        self._container = container
+++
+++    def _add_action(self, action):
+++        if action.required:
+++            msg = _('mutually exclusive arguments must be optional')
+++            raise ValueError(msg)
+++        action = self._container._add_action(action)
+++        self._group_actions.append(action)
+++        return action
+++
+++    def _remove_action(self, action):
+++        self._container._remove_action(action)
+++        self._group_actions.remove(action)
+++
+++
+++class ArgumentParser(_AttributeHolder, _ActionsContainer):
+++    """Object for parsing command line strings into Python objects.
+++
+++    Keyword Arguments:
+++        - prog -- The name of the program (default: sys.argv[0])
+++        - usage -- A usage message (default: auto-generated from arguments)
+++        - description -- A description of what the program does
+++        - epilog -- Text following the argument descriptions
+++        - parents -- Parsers whose arguments should be copied into this one
+++        - formatter_class -- HelpFormatter class for printing help messages
+++        - prefix_chars -- Characters that prefix optional arguments
+++        - fromfile_prefix_chars -- Characters that prefix files containing
+++            additional arguments
+++        - argument_default -- The default value for all arguments
+++        - conflict_handler -- String indicating how to handle conflicts
+++        - add_help -- Add a -h/-help option
+++    """
+++
+++    def __init__(self,
+++                 prog=None,
+++                 usage=None,
+++                 description=None,
+++                 epilog=None,
+++                 version=None,
+++                 parents=[],
+++                 formatter_class=HelpFormatter,
+++                 prefix_chars='-',
+++                 fromfile_prefix_chars=None,
+++                 argument_default=None,
+++                 conflict_handler='error',
+++                 add_help=True):
+++
+++        if version is not None:
+++            import warnings
+++            warnings.warn(
+++                """The "version" argument to ArgumentParser is deprecated. """
+++                """Please use """
+++                """"add_argument(..., action='version', version="N", ...)" """
+++                """instead""", DeprecationWarning)
+++
+++        superinit = super(ArgumentParser, self).__init__
+++        superinit(description=description,
+++                  prefix_chars=prefix_chars,
+++                  argument_default=argument_default,
+++                  conflict_handler=conflict_handler)
+++
+++        # default setting for prog
+++        if prog is None:
+++            prog = _os.path.basename(_sys.argv[0])
+++
+++        self.prog = prog
+++        self.usage = usage
+++        self.epilog = epilog
+++        self.version = version
+++        self.formatter_class = formatter_class
+++        self.fromfile_prefix_chars = fromfile_prefix_chars
+++        self.add_help = add_help
+++
+++        add_group = self.add_argument_group
+++        self._positionals = add_group(_('positional arguments'))
+++        self._optionals = add_group(_('optional arguments'))
+++        self._subparsers = None
+++
+++        # register types
+++        def identity(string):
+++            return string
+++        self.register('type', None, identity)
+++
+++        # add help and version arguments if necessary
+++        # (using explicit default to override global argument_default)
+++        if '-' in prefix_chars:
+++            default_prefix = '-'
+++        else:
+++            default_prefix = prefix_chars[0]
+++        if self.add_help:
+++            self.add_argument(
+++                default_prefix+'h', default_prefix*2+'help',
+++                action='help', default=SUPPRESS,
+++                help=_('show this help message and exit'))
+++        if self.version:
+++            self.add_argument(
+++                default_prefix+'v', default_prefix*2+'version',
+++                action='version', default=SUPPRESS,
+++                version=self.version,
+++                help=_("show program's version number and exit"))
+++
+++        # add parent arguments and defaults
+++        for parent in parents:
+++            self._add_container_actions(parent)
+++            try:
+++                defaults = parent._defaults
+++            except AttributeError:
+++                pass
+++            else:
+++                self._defaults.update(defaults)
+++
+++    # =======================
+++    # Pretty __repr__ methods
+++    # =======================
+++    def _get_kwargs(self):
+++        names = [
+++            'prog',
+++            'usage',
+++            'description',
+++            'version',
+++            'formatter_class',
+++            'conflict_handler',
+++            'add_help',
+++        ]
+++        return [(name, getattr(self, name)) for name in names]
+++
+++    # ==================================
+++    # Optional/Positional adding methods
+++    # ==================================
+++    def add_subparsers(self, **kwargs):
+++        if self._subparsers is not None:
+++            self.error(_('cannot have multiple subparser arguments'))
+++
+++        # add the parser class to the arguments if it's not present
+++        kwargs.setdefault('parser_class', type(self))
+++
+++        if 'title' in kwargs or 'description' in kwargs:
+++            title = _(kwargs.pop('title', 'subcommands'))
+++            description = _(kwargs.pop('description', None))
+++            self._subparsers = self.add_argument_group(title, description)
+++        else:
+++            self._subparsers = self._positionals
+++
+++        # prog defaults to the usage message of this parser, skipping
+++        # optional arguments and with no "usage:" prefix
+++        if kwargs.get('prog') is None:
+++            formatter = self._get_formatter()
+++            positionals = self._get_positional_actions()
+++            groups = self._mutually_exclusive_groups
+++            formatter.add_usage(self.usage, positionals, groups, '')
+++            kwargs['prog'] = formatter.format_help().strip()
+++
+++        # create the parsers action and add it to the positionals list
+++        parsers_class = self._pop_action_class(kwargs, 'parsers')
+++        action = parsers_class(option_strings=[], **kwargs)
+++        self._subparsers._add_action(action)
+++
+++        # return the created parsers action
+++        return action
+++
+++    def _add_action(self, action):
+++        if action.option_strings:
+++            self._optionals._add_action(action)
+++        else:
+++            self._positionals._add_action(action)
+++        return action
+++
+++    def _get_optional_actions(self):
+++        return [action
+++                for action in self._actions
+++                if action.option_strings]
+++
+++    def _get_positional_actions(self):
+++        return [action
+++                for action in self._actions
+++                if not action.option_strings]
+++
+++    # =====================================
+++    # Command line argument parsing methods
+++    # =====================================
+++    def parse_args(self, args=None, namespace=None):
+++        args, argv = self.parse_known_args(args, namespace)
+++        if argv:
+++            msg = _('unrecognized arguments: %s')
+++            self.error(msg % ' '.join(argv))
+++        return args
+++
+++    def parse_known_args(self, args=None, namespace=None):
+++        # args default to the system args
+++        if args is None:
+++            args = _sys.argv[1:]
+++
+++        # default Namespace built from parser defaults
+++        if namespace is None:
+++            namespace = Namespace()
+++
+++        # add any action defaults that aren't present
+++        for action in self._actions:
+++            if action.dest is not SUPPRESS:
+++                if not hasattr(namespace, action.dest):
+++                    if action.default is not SUPPRESS:
+++                        default = action.default
+++                        if isinstance(action.default, basestring):
+++                            default = self._get_value(action, default)
+++                        setattr(namespace, action.dest, default)
+++
+++        # add any parser defaults that aren't present
+++        for dest in self._defaults:
+++            if not hasattr(namespace, dest):
+++                setattr(namespace, dest, self._defaults[dest])
+++
+++        # parse the arguments and exit if there are any errors
+++        try:
+++            namespace, args = self._parse_known_args(args, namespace)
+++            if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR):
+++                args.extend(getattr(namespace, _UNRECOGNIZED_ARGS_ATTR))
+++                delattr(namespace, _UNRECOGNIZED_ARGS_ATTR)
+++            return namespace, args
+++        except ArgumentError:
+++            err = _sys.exc_info()[1]
+++            self.error(str(err))
+++
+++    def _parse_known_args(self, arg_strings, namespace):
+++        # replace arg strings that are file references
+++        if self.fromfile_prefix_chars is not None:
+++            arg_strings = self._read_args_from_files(arg_strings)
+++
+++        # map all mutually exclusive arguments to the other arguments
+++        # they can't occur with
+++        action_conflicts = {}
+++        for mutex_group in self._mutually_exclusive_groups:
+++            group_actions = mutex_group._group_actions
+++            for i, mutex_action in enumerate(mutex_group._group_actions):
+++                conflicts = action_conflicts.setdefault(mutex_action, [])
+++                conflicts.extend(group_actions[:i])
+++                conflicts.extend(group_actions[i + 1:])
+++
+++        # find all option indices, and determine the arg_string_pattern
+++        # which has an 'O' if there is an option at an index,
+++        # an 'A' if there is an argument, or a '-' if there is a '--'
+++        option_string_indices = {}
+++        arg_string_pattern_parts = []
+++        arg_strings_iter = iter(arg_strings)
+++        for i, arg_string in enumerate(arg_strings_iter):
+++
+++            # all args after -- are non-options
+++            if arg_string == '--':
+++                arg_string_pattern_parts.append('-')
+++                for arg_string in arg_strings_iter:
+++                    arg_string_pattern_parts.append('A')
+++
+++            # otherwise, add the arg to the arg strings
+++            # and note the index if it was an option
+++            else:
+++                option_tuple = self._parse_optional(arg_string)
+++                if option_tuple is None:
+++                    pattern = 'A'
+++                else:
+++                    option_string_indices[i] = option_tuple
+++                    pattern = 'O'
+++                arg_string_pattern_parts.append(pattern)
+++
+++        # join the pieces together to form the pattern
+++        arg_strings_pattern = ''.join(arg_string_pattern_parts)
+++
+++        # converts arg strings to the appropriate and then takes the action
+++        seen_actions = set()
+++        seen_non_default_actions = set()
+++
+++        def take_action(action, argument_strings, option_string=None):
+++            seen_actions.add(action)
+++            argument_values = self._get_values(action, argument_strings)
+++
+++            # error if this argument is not allowed with other previously
+++            # seen arguments, assuming that actions that use the default
+++            # value don't really count as "present"
+++            if argument_values is not action.default:
+++                seen_non_default_actions.add(action)
+++                for conflict_action in action_conflicts.get(action, []):
+++                    if conflict_action in seen_non_default_actions:
+++                        msg = _('not allowed with argument %s')
+++                        action_name = _get_action_name(conflict_action)
+++                        raise ArgumentError(action, msg % action_name)
+++
+++            # take the action if we didn't receive a SUPPRESS value
+++            # (e.g. from a default)
+++            if argument_values is not SUPPRESS:
+++                action(self, namespace, argument_values, option_string)
+++
+++        # function to convert arg_strings into an optional action
+++        def consume_optional(start_index):
+++
+++            # get the optional identified at this index
+++            option_tuple = option_string_indices[start_index]
+++            action, option_string, explicit_arg = option_tuple
+++
+++            # identify additional optionals in the same arg string
+++            # (e.g. -xyz is the same as -x -y -z if no args are required)
+++            match_argument = self._match_argument
+++            action_tuples = []
+++            while True:
+++
+++                # if we found no optional action, skip it
+++                if action is None:
+++                    extras.append(arg_strings[start_index])
+++                    return start_index + 1
+++
+++                # if there is an explicit argument, try to match the
+++                # optional's string arguments to only this
+++                if explicit_arg is not None:
+++                    arg_count = match_argument(action, 'A')
+++
+++                    # if the action is a single-dash option and takes no
+++                    # arguments, try to parse more single-dash options out
+++                    # of the tail of the option string
+++                    chars = self.prefix_chars
+++                    if arg_count == 0 and option_string[1] not in chars:
+++                        action_tuples.append((action, [], option_string))
+++                        char = option_string[0]
+++                        option_string = char + explicit_arg[0]
+++                        new_explicit_arg = explicit_arg[1:] or None
+++                        optionals_map = self._option_string_actions
+++                        if option_string in optionals_map:
+++                            action = optionals_map[option_string]
+++                            explicit_arg = new_explicit_arg
+++                        else:
+++                            msg = _('ignored explicit argument %r')
+++                            raise ArgumentError(action, msg % explicit_arg)
+++
+++                    # if the action expect exactly one argument, we've
+++                    # successfully matched the option; exit the loop
+++                    elif arg_count == 1:
+++                        stop = start_index + 1
+++                        args = [explicit_arg]
+++                        action_tuples.append((action, args, option_string))
+++                        break
+++
+++                    # error if a double-dash option did not use the
+++                    # explicit argument
+++                    else:
+++                        msg = _('ignored explicit argument %r')
+++                        raise ArgumentError(action, msg % explicit_arg)
+++
+++                # if there is no explicit argument, try to match the
+++                # optional's string arguments with the following strings
+++                # if successful, exit the loop
+++                else:
+++                    start = start_index + 1
+++                    selected_patterns = arg_strings_pattern[start:]
+++                    arg_count = match_argument(action, selected_patterns)
+++                    stop = start + arg_count
+++                    args = arg_strings[start:stop]
+++                    action_tuples.append((action, args, option_string))
+++                    break
+++
+++            # add the Optional to the list and return the index at which
+++            # the Optional's string args stopped
+++            assert action_tuples
+++            for action, args, option_string in action_tuples:
+++                take_action(action, args, option_string)
+++            return stop
+++
+++        # the list of Positionals left to be parsed; this is modified
+++        # by consume_positionals()
+++        positionals = self._get_positional_actions()
+++
+++        # function to convert arg_strings into positional actions
+++        def consume_positionals(start_index):
+++            # match as many Positionals as possible
+++            match_partial = self._match_arguments_partial
+++            selected_pattern = arg_strings_pattern[start_index:]
+++            arg_counts = match_partial(positionals, selected_pattern)
+++
+++            # slice off the appropriate arg strings for each Positional
+++            # and add the Positional and its args to the list
+++            for action, arg_count in zip(positionals, arg_counts):
+++                args = arg_strings[start_index: start_index + arg_count]
+++                start_index += arg_count
+++                take_action(action, args)
+++
+++            # slice off the Positionals that we just parsed and return the
+++            # index at which the Positionals' string args stopped
+++            positionals[:] = positionals[len(arg_counts):]
+++            return start_index
+++
+++        # consume Positionals and Optionals alternately, until we have
+++        # passed the last option string
+++        extras = []
+++        start_index = 0
+++        if option_string_indices:
+++            max_option_string_index = max(option_string_indices)
+++        else:
+++            max_option_string_index = -1
+++        while start_index <= max_option_string_index:
+++
+++            # consume any Positionals preceding the next option
+++            next_option_string_index = min([
+++                index
+++                for index in option_string_indices
+++                if index >= start_index])
+++            if start_index != next_option_string_index:
+++                positionals_end_index = consume_positionals(start_index)
+++
+++                # only try to parse the next optional if we didn't consume
+++                # the option string during the positionals parsing
+++                if positionals_end_index > start_index:
+++                    start_index = positionals_end_index
+++                    continue
+++                else:
+++                    start_index = positionals_end_index
+++
+++            # if we consumed all the positionals we could and we're not
+++            # at the index of an option string, there were extra arguments
+++            if start_index not in option_string_indices:
+++                strings = arg_strings[start_index:next_option_string_index]
+++                extras.extend(strings)
+++                start_index = next_option_string_index
+++
+++            # consume the next optional and any arguments for it
+++            start_index = consume_optional(start_index)
+++
+++        # consume any positionals following the last Optional
+++        stop_index = consume_positionals(start_index)
+++
+++        # if we didn't consume all the argument strings, there were extras
+++        extras.extend(arg_strings[stop_index:])
+++
+++        # if we didn't use all the Positional objects, there were too few
+++        # arg strings supplied.
+++        if positionals:
+++            self.error(_('too few arguments'))
+++
+++        # make sure all required actions were present
+++        for action in self._actions:
+++            if action.required:
+++                if action not in seen_actions:
+++                    name = _get_action_name(action)
+++                    self.error(_('argument %s is required') % name)
+++
+++        # make sure all required groups had one option present
+++        for group in self._mutually_exclusive_groups:
+++            if group.required:
+++                for action in group._group_actions:
+++                    if action in seen_non_default_actions:
+++                        break
+++
+++                # if no actions were used, report the error
+++                else:
+++                    names = [_get_action_name(action)
+++                             for action in group._group_actions
+++                             if action.help is not SUPPRESS]
+++                    msg = _('one of the arguments %s is required')
+++                    self.error(msg % ' '.join(names))
+++
+++        # return the updated namespace and the extra arguments
+++        return namespace, extras
+++
+++    def _read_args_from_files(self, arg_strings):
+++        # expand arguments referencing files
+++        new_arg_strings = []
+++        for arg_string in arg_strings:
+++
+++            # for regular arguments, just add them back into the list
+++            if arg_string[0] not in self.fromfile_prefix_chars:
+++                new_arg_strings.append(arg_string)
+++
+++            # replace arguments referencing files with the file content
+++            else:
+++                try:
+++                    args_file = open(arg_string[1:])
+++                    try:
+++                        arg_strings = []
+++                        for arg_line in args_file.read().splitlines():
+++                            for arg in self.convert_arg_line_to_args(arg_line):
+++                                arg_strings.append(arg)
+++                        arg_strings = self._read_args_from_files(arg_strings)
+++                        new_arg_strings.extend(arg_strings)
+++                    finally:
+++                        args_file.close()
+++                except IOError:
+++                    err = _sys.exc_info()[1]
+++                    self.error(str(err))
+++
+++        # return the modified argument list
+++        return new_arg_strings
+++
+++    def convert_arg_line_to_args(self, arg_line):
+++        return [arg_line]
+++
+++    def _match_argument(self, action, arg_strings_pattern):
+++        # match the pattern for this action to the arg strings
+++        nargs_pattern = self._get_nargs_pattern(action)
+++        match = _re.match(nargs_pattern, arg_strings_pattern)
+++
+++        # raise an exception if we weren't able to find a match
+++        if match is None:
+++            nargs_errors = {
+++                None: _('expected one argument'),
+++                OPTIONAL: _('expected at most one argument'),
+++                ONE_OR_MORE: _('expected at least one argument'),
+++            }
+++            default = _('expected %s argument(s)') % action.nargs
+++            msg = nargs_errors.get(action.nargs, default)
+++            raise ArgumentError(action, msg)
+++
+++        # return the number of arguments matched
+++        return len(match.group(1))
+++
+++    def _match_arguments_partial(self, actions, arg_strings_pattern):
+++        # progressively shorten the actions list by slicing off the
+++        # final actions until we find a match
+++        result = []
+++        for i in range(len(actions), 0, -1):
+++            actions_slice = actions[:i]
+++            pattern = ''.join([self._get_nargs_pattern(action)
+++                               for action in actions_slice])
+++            match = _re.match(pattern, arg_strings_pattern)
+++            if match is not None:
+++                result.extend([len(string) for string in match.groups()])
+++                break
+++
+++        # return the list of arg string counts
+++        return result
+++
+++    def _parse_optional(self, arg_string):
+++        # if it's an empty string, it was meant to be a positional
+++        if not arg_string:
+++            return None
+++
+++        # if it doesn't start with a prefix, it was meant to be positional
+++        if not arg_string[0] in self.prefix_chars:
+++            return None
+++
+++        # if the option string is present in the parser, return the action
+++        if arg_string in self._option_string_actions:
+++            action = self._option_string_actions[arg_string]
+++            return action, arg_string, None
+++
+++        # if it's just a single character, it was meant to be positional
+++        if len(arg_string) == 1:
+++            return None
+++
+++        # if the option string before the "=" is present, return the action
+++        if '=' in arg_string:
+++            option_string, explicit_arg = arg_string.split('=', 1)
+++            if option_string in self._option_string_actions:
+++                action = self._option_string_actions[option_string]
+++                return action, option_string, explicit_arg
+++
+++        # search through all possible prefixes of the option string
+++        # and all actions in the parser for possible interpretations
+++        option_tuples = self._get_option_tuples(arg_string)
+++
+++        # if multiple actions match, the option string was ambiguous
+++        if len(option_tuples) > 1:
+++            options = ', '.join([option_string
+++                for action, option_string, explicit_arg in option_tuples])
+++            tup = arg_string, options
+++            self.error(_('ambiguous option: %s could match %s') % tup)
+++
+++        # if exactly one action matched, this segmentation is good,
+++        # so return the parsed action
+++        elif len(option_tuples) == 1:
+++            option_tuple, = option_tuples
+++            return option_tuple
+++
+++        # if it was not found as an option, but it looks like a negative
+++        # number, it was meant to be positional
+++        # unless there are negative-number-like options
+++        if self._negative_number_matcher.match(arg_string):
+++            if not self._has_negative_number_optionals:
+++                return None
+++
+++        # if it contains a space, it was meant to be a positional
+++        if ' ' in arg_string:
+++            return None
+++
+++        # it was meant to be an optional but there is no such option
+++        # in this parser (though it might be a valid option in a subparser)
+++        return None, arg_string, None
+++
+++    def _get_option_tuples(self, option_string):
+++        result = []
+++
+++        # option strings starting with two prefix characters are only
+++        # split at the '='
+++        chars = self.prefix_chars
+++        if option_string[0] in chars and option_string[1] in chars:
+++            if '=' in option_string:
+++                option_prefix, explicit_arg = option_string.split('=', 1)
+++            else:
+++                option_prefix = option_string
+++                explicit_arg = None
+++            for option_string in self._option_string_actions:
+++                if option_string.startswith(option_prefix):
+++                    action = self._option_string_actions[option_string]
+++                    tup = action, option_string, explicit_arg
+++                    result.append(tup)
+++
+++        # single character options can be concatenated with their arguments
+++        # but multiple character options always have to have their argument
+++        # separate
+++        elif option_string[0] in chars and option_string[1] not in chars:
+++            option_prefix = option_string
+++            explicit_arg = None
+++            short_option_prefix = option_string[:2]
+++            short_explicit_arg = option_string[2:]
+++
+++            for option_string in self._option_string_actions:
+++                if option_string == short_option_prefix:
+++                    action = self._option_string_actions[option_string]
+++                    tup = action, option_string, short_explicit_arg
+++                    result.append(tup)
+++                elif option_string.startswith(option_prefix):
+++                    action = self._option_string_actions[option_string]
+++                    tup = action, option_string, explicit_arg
+++                    result.append(tup)
+++
+++        # shouldn't ever get here
+++        else:
+++            self.error(_('unexpected option string: %s') % option_string)
+++
+++        # return the collected option tuples
+++        return result
+++
+++    def _get_nargs_pattern(self, action):
+++        # in all examples below, we have to allow for '--' args
+++        # which are represented as '-' in the pattern
+++        nargs = action.nargs
+++
+++        # the default (None) is assumed to be a single argument
+++        if nargs is None:
+++            nargs_pattern = '(-*A-*)'
+++
+++        # allow zero or one arguments
+++        elif nargs == OPTIONAL:
+++            nargs_pattern = '(-*A?-*)'
+++
+++        # allow zero or more arguments
+++        elif nargs == ZERO_OR_MORE:
+++            nargs_pattern = '(-*[A-]*)'
+++
+++        # allow one or more arguments
+++        elif nargs == ONE_OR_MORE:
+++            nargs_pattern = '(-*A[A-]*)'
+++
+++        # allow any number of options or arguments
+++        elif nargs == REMAINDER:
+++            nargs_pattern = '([-AO]*)'
+++
+++        # allow one argument followed by any number of options or arguments
+++        elif nargs == PARSER:
+++            nargs_pattern = '(-*A[-AO]*)'
+++
+++        # all others should be integers
+++        else:
+++            nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
+++
+++        # if this is an optional action, -- is not allowed
+++        if action.option_strings:
+++            nargs_pattern = nargs_pattern.replace('-*', '')
+++            nargs_pattern = nargs_pattern.replace('-', '')
+++
+++        # return the pattern
+++        return nargs_pattern
+++
+++    # ========================
+++    # Value conversion methods
+++    # ========================
+++    def _get_values(self, action, arg_strings):
+++        # for everything but PARSER args, strip out '--'
+++        if action.nargs not in [PARSER, REMAINDER]:
+++            arg_strings = [s for s in arg_strings if s != '--']
+++
+++        # optional argument produces a default when not present
+++        if not arg_strings and action.nargs == OPTIONAL:
+++            if action.option_strings:
+++                value = action.const
+++            else:
+++                value = action.default
+++            if isinstance(value, basestring):
+++                value = self._get_value(action, value)
+++                self._check_value(action, value)
+++
+++        # when nargs='*' on a positional, if there were no command-line
+++        # args, use the default if it is anything other than None
+++        elif (not arg_strings and action.nargs == ZERO_OR_MORE and
+++              not action.option_strings):
+++            if action.default is not None:
+++                value = action.default
+++            else:
+++                value = arg_strings
+++            self._check_value(action, value)
+++
+++        # single argument or optional argument produces a single value
+++        elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:
+++            arg_string, = arg_strings
+++            value = self._get_value(action, arg_string)
+++            self._check_value(action, value)
+++
+++        # REMAINDER arguments convert all values, checking none
+++        elif action.nargs == REMAINDER:
+++            value = [self._get_value(action, v) for v in arg_strings]
+++
+++        # PARSER arguments convert all values, but check only the first
+++        elif action.nargs == PARSER:
+++            value = [self._get_value(action, v) for v in arg_strings]
+++            self._check_value(action, value[0])
+++
+++        # all other types of nargs produce a list
+++        else:
+++            value = [self._get_value(action, v) for v in arg_strings]
+++            for v in value:
+++                self._check_value(action, v)
+++
+++        # return the converted value
+++        return value
+++
+++    def _get_value(self, action, arg_string):
+++        type_func = self._registry_get('type', action.type, action.type)
+++        if not _callable(type_func):
+++            msg = _('%r is not callable')
+++            raise ArgumentError(action, msg % type_func)
+++
+++        # convert the value to the appropriate type
+++        try:
+++            result = type_func(arg_string)
+++
+++        # ArgumentTypeErrors indicate errors
+++        except ArgumentTypeError:
+++            name = getattr(action.type, '__name__', repr(action.type))
+++            msg = str(_sys.exc_info()[1])
+++            raise ArgumentError(action, msg)
+++
+++        # TypeErrors or ValueErrors also indicate errors
+++        except (TypeError, ValueError):
+++            name = getattr(action.type, '__name__', repr(action.type))
+++            msg = _('invalid %s value: %r')
+++            raise ArgumentError(action, msg % (name, arg_string))
+++
+++        # return the converted value
+++        return result
+++
+++    def _check_value(self, action, value):
+++        # converted value must be one of the choices (if specified)
+++        if action.choices is not None and value not in action.choices:
+++            tup = value, ', '.join(map(repr, action.choices))
+++            msg = _('invalid choice: %r (choose from %s)') % tup
+++            raise ArgumentError(action, msg)
+++
+++    # =======================
+++    # Help-formatting methods
+++    # =======================
+++    def format_usage(self):
+++        formatter = self._get_formatter()
+++        formatter.add_usage(self.usage, self._actions,
+++                            self._mutually_exclusive_groups)
+++        return formatter.format_help()
+++
+++    def format_help(self):
+++        formatter = self._get_formatter()
+++
+++        # usage
+++        formatter.add_usage(self.usage, self._actions,
+++                            self._mutually_exclusive_groups)
+++
+++        # description
+++        formatter.add_text(self.description)
+++
+++        # positionals, optionals and user-defined groups
+++        for action_group in self._action_groups:
+++            formatter.start_section(action_group.title)
+++            formatter.add_text(action_group.description)
+++            formatter.add_arguments(action_group._group_actions)
+++            formatter.end_section()
+++
+++        # epilog
+++        formatter.add_text(self.epilog)
+++
+++        # determine help from format above
+++        return formatter.format_help()
+++
+++    def format_version(self):
+++        import warnings
+++        warnings.warn(
+++            'The format_version method is deprecated -- the "version" '
+++            'argument to ArgumentParser is no longer supported.',
+++            DeprecationWarning)
+++        formatter = self._get_formatter()
+++        formatter.add_text(self.version)
+++        return formatter.format_help()
+++
+++    def _get_formatter(self):
+++        return self.formatter_class(prog=self.prog)
+++
+++    # =====================
+++    # Help-printing methods
+++    # =====================
+++    def print_usage(self, file=None):
+++        if file is None:
+++            file = _sys.stdout
+++        self._print_message(self.format_usage(), file)
+++
+++    def print_help(self, file=None):
+++        if file is None:
+++            file = _sys.stdout
+++        self._print_message(self.format_help(), file)
+++
+++    def print_version(self, file=None):
+++        import warnings
+++        warnings.warn(
+++            'The print_version method is deprecated -- the "version" '
+++            'argument to ArgumentParser is no longer supported.',
+++            DeprecationWarning)
+++        self._print_message(self.format_version(), file)
+++
+++    def _print_message(self, message, file=None):
+++        if message:
+++            if file is None:
+++                file = _sys.stderr
+++            file.write(message)
+++
+++    # ===============
+++    # Exiting methods
+++    # ===============
+++    def exit(self, status=0, message=None):
+++        if message:
+++            self._print_message(message, _sys.stderr)
+++        _sys.exit(status)
+++
+++    def error(self, message):
+++        """error(message: string)
+++
+++        Prints a usage message incorporating the message to stderr and
+++        exits.
+++
+++        If you override this in a subclass, it should not return -- it
+++        should either exit or raise an exception.
+++        """
+++        self.print_usage(_sys.stderr)
+++        self.exit(2, _('%s: error: %s\n') % (self.prog, message))
+++# Author: Steven J. Bethard <steven.bethard at gmail.com>.
+++
+++"""Command-line parsing library
+++
+++This module is an optparse-inspired command-line parsing library that:
+++
+++    - handles both optional and positional arguments
+++    - produces highly informative usage messages
+++    - supports parsers that dispatch to sub-parsers
+++
+++The following is a simple usage example that sums integers from the
+++command-line and writes the result to a file::
+++
+++    parser = argparse.ArgumentParser(
+++        description='sum the integers at the command line')
+++    parser.add_argument(
+++        'integers', metavar='int', nargs='+', type=int,
+++        help='an integer to be summed')
+++    parser.add_argument(
+++        '--log', default=sys.stdout, type=argparse.FileType('w'),
+++        help='the file where the sum should be written')
+++    args = parser.parse_args()
+++    args.log.write('%s' % sum(args.integers))
+++    args.log.close()
+++
+++The module contains the following public classes:
+++
+++    - ArgumentParser -- The main entry point for command-line parsing. As the
+++        example above shows, the add_argument() method is used to populate
+++        the parser with actions for optional and positional arguments. Then
+++        the parse_args() method is invoked to convert the args at the
+++        command-line into an object with attributes.
+++
+++    - ArgumentError -- The exception raised by ArgumentParser objects when
+++        there are errors with the parser's actions. Errors raised while
+++        parsing the command-line are caught by ArgumentParser and emitted
+++        as command-line messages.
+++
+++    - FileType -- A factory for defining types of files to be created. As the
+++        example above shows, instances of FileType are typically passed as
+++        the type= argument of add_argument() calls.
+++
+++    - Action -- The base class for parser actions. Typically actions are
+++        selected by passing strings like 'store_true' or 'append_const' to
+++        the action= argument of add_argument(). However, for greater
+++        customization of ArgumentParser actions, subclasses of Action may
+++        be defined and passed as the action= argument.
+++
+++    - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter,
+++        ArgumentDefaultsHelpFormatter -- Formatter classes which
+++        may be passed as the formatter_class= argument to the
+++        ArgumentParser constructor. HelpFormatter is the default,
+++        RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser
+++        not to change the formatting for help text, and
+++        ArgumentDefaultsHelpFormatter adds information about argument defaults
+++        to the help.
+++
+++All other classes in this module are considered implementation details.
+++(Also note that HelpFormatter and RawDescriptionHelpFormatter are only
+++considered public as object names -- the API of the formatter objects is
+++still considered an implementation detail.)
+++"""
+++
+++__version__ = '1.2.1'
+++__all__ = [
+++    'ArgumentParser',
+++    'ArgumentError',
+++    'ArgumentTypeError',
+++    'FileType',
+++    'HelpFormatter',
+++    'ArgumentDefaultsHelpFormatter',
+++    'RawDescriptionHelpFormatter',
+++    'RawTextHelpFormatter',
+++    'Namespace',
+++    'Action',
+++    'ONE_OR_MORE',
+++    'OPTIONAL',
+++    'PARSER',
+++    'REMAINDER',
+++    'SUPPRESS',
+++    'ZERO_OR_MORE',
+++]
+++
+++
+++import copy as _copy
+++import os as _os
+++import re as _re
+++import sys as _sys
+++import textwrap as _textwrap
+++
+++from gettext import gettext as _
+++
+++try:
+++    set
+++except NameError:
+++    # for python < 2.4 compatibility (sets module is there since 2.3):
+++    from sets import Set as set
+++
+++try:
+++    basestring
+++except NameError:
+++    basestring = str
+++
+++try:
+++    sorted
+++except NameError:
+++    # for python < 2.4 compatibility:
+++    def sorted(iterable, reverse=False):
+++        result = list(iterable)
+++        result.sort()
+++        if reverse:
+++            result.reverse()
+++        return result
+++
+++
+++def _callable(obj):
+++    return hasattr(obj, '__call__') or hasattr(obj, '__bases__')
+++
+++
+++SUPPRESS = '==SUPPRESS=='
+++
+++OPTIONAL = '?'
+++ZERO_OR_MORE = '*'
+++ONE_OR_MORE = '+'
+++PARSER = 'A...'
+++REMAINDER = '...'
+++_UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'
+++
+++# =============================
+++# Utility functions and classes
+++# =============================
+++
+++class _AttributeHolder(object):
+++    """Abstract base class that provides __repr__.
+++
+++    The __repr__ method returns a string in the format::
+++        ClassName(attr=name, attr=name, ...)
+++    The attributes are determined either by a class-level attribute,
+++    '_kwarg_names', or by inspecting the instance __dict__.
+++    """
+++
+++    def __repr__(self):
+++        type_name = type(self).__name__
+++        arg_strings = []
+++        for arg in self._get_args():
+++            arg_strings.append(repr(arg))
+++        for name, value in self._get_kwargs():
+++            arg_strings.append('%s=%r' % (name, value))
+++        return '%s(%s)' % (type_name, ', '.join(arg_strings))
+++
+++    def _get_kwargs(self):
+++        return sorted(self.__dict__.items())
+++
+++    def _get_args(self):
+++        return []
+++
+++
+++def _ensure_value(namespace, name, value):
+++    if getattr(namespace, name, None) is None:
+++        setattr(namespace, name, value)
+++    return getattr(namespace, name)
+++
+++
+++# ===============
+++# Formatting Help
+++# ===============
+++
+++class HelpFormatter(object):
+++    """Formatter for generating usage messages and argument help strings.
+++
+++    Only the name of this class is considered a public API. All the methods
+++    provided by the class are considered an implementation detail.
+++    """
+++
+++    def __init__(self,
+++                 prog,
+++                 indent_increment=2,
+++                 max_help_position=24,
+++                 width=None):
+++
+++        # default setting for width
+++        if width is None:
+++            try:
+++                width = int(_os.environ['COLUMNS'])
+++            except (KeyError, ValueError):
+++                width = 80
+++            width -= 2
+++
+++        self._prog = prog
+++        self._indent_increment = indent_increment
+++        self._max_help_position = max_help_position
+++        self._width = width
+++
+++        self._current_indent = 0
+++        self._level = 0
+++        self._action_max_length = 0
+++
+++        self._root_section = self._Section(self, None)
+++        self._current_section = self._root_section
+++
+++        self._whitespace_matcher = _re.compile(r'\s+')
+++        self._long_break_matcher = _re.compile(r'\n\n\n+')
+++
+++    # ===============================
+++    # Section and indentation methods
+++    # ===============================
+++    def _indent(self):
+++        self._current_indent += self._indent_increment
+++        self._level += 1
+++
+++    def _dedent(self):
+++        self._current_indent -= self._indent_increment
+++        assert self._current_indent >= 0, 'Indent decreased below 0.'
+++        self._level -= 1
+++
+++    class _Section(object):
+++
+++        def __init__(self, formatter, parent, heading=None):
+++            self.formatter = formatter
+++            self.parent = parent
+++            self.heading = heading
+++            self.items = []
+++
+++        def format_help(self):
+++            # format the indented section
+++            if self.parent is not None:
+++                self.formatter._indent()
+++            join = self.formatter._join_parts
+++            for func, args in self.items:
+++                func(*args)
+++            item_help = join([func(*args) for func, args in self.items])
+++            if self.parent is not None:
+++                self.formatter._dedent()
+++
+++            # return nothing if the section was empty
+++            if not item_help:
+++                return ''
+++
+++            # add the heading if the section was non-empty
+++            if self.heading is not SUPPRESS and self.heading is not None:
+++                current_indent = self.formatter._current_indent
+++                heading = '%*s%s:\n' % (current_indent, '', self.heading)
+++            else:
+++                heading = ''
+++
+++            # join the section-initial newline, the heading and the help
+++            return join(['\n', heading, item_help, '\n'])
+++
+++    def _add_item(self, func, args):
+++        self._current_section.items.append((func, args))
+++
+++    # ========================
+++    # Message building methods
+++    # ========================
+++    def start_section(self, heading):
+++        self._indent()
+++        section = self._Section(self, self._current_section, heading)
+++        self._add_item(section.format_help, [])
+++        self._current_section = section
+++
+++    def end_section(self):
+++        self._current_section = self._current_section.parent
+++        self._dedent()
+++
+++    def add_text(self, text):
+++        if text is not SUPPRESS and text is not None:
+++            self._add_item(self._format_text, [text])
+++
+++    def add_usage(self, usage, actions, groups, prefix=None):
+++        if usage is not SUPPRESS:
+++            args = usage, actions, groups, prefix
+++            self._add_item(self._format_usage, args)
+++
+++    def add_argument(self, action):
+++        if action.help is not SUPPRESS:
+++
+++            # find all invocations
+++            get_invocation = self._format_action_invocation
+++            invocations = [get_invocation(action)]
+++            for subaction in self._iter_indented_subactions(action):
+++                invocations.append(get_invocation(subaction))
+++
+++            # update the maximum item length
+++            invocation_length = max([len(s) for s in invocations])
+++            action_length = invocation_length + self._current_indent
+++            self._action_max_length = max(self._action_max_length,
+++                                          action_length)
+++
+++            # add the item to the list
+++            self._add_item(self._format_action, [action])
+++
+++    def add_arguments(self, actions):
+++        for action in actions:
+++            self.add_argument(action)
+++
+++    # =======================
+++    # Help-formatting methods
+++    # =======================
+++    def format_help(self):
+++        help = self._root_section.format_help()
+++        if help:
+++            help = self._long_break_matcher.sub('\n\n', help)
+++            help = help.strip('\n') + '\n'
+++        return help
+++
+++    def _join_parts(self, part_strings):
+++        return ''.join([part
+++                        for part in part_strings
+++                        if part and part is not SUPPRESS])
+++
+++    def _format_usage(self, usage, actions, groups, prefix):
+++        if prefix is None:
+++            prefix = _('usage: ')
+++
+++        # if usage is specified, use that
+++        if usage is not None:
+++            usage = usage % dict(prog=self._prog)
+++
+++        # if no optionals or positionals are available, usage is just prog
+++        elif usage is None and not actions:
+++            usage = '%(prog)s' % dict(prog=self._prog)
+++
+++        # if optionals and positionals are available, calculate usage
+++        elif usage is None:
+++            prog = '%(prog)s' % dict(prog=self._prog)
+++
+++            # split optionals from positionals
+++            optionals = []
+++            positionals = []
+++            for action in actions:
+++                if action.option_strings:
+++                    optionals.append(action)
+++                else:
+++                    positionals.append(action)
+++
+++            # build full usage string
+++            format = self._format_actions_usage
+++            action_usage = format(optionals + positionals, groups)
+++            usage = ' '.join([s for s in [prog, action_usage] if s])
+++
+++            # wrap the usage parts if it's too long
+++            text_width = self._width - self._current_indent
+++            if len(prefix) + len(usage) > text_width:
+++
+++                # break usage into wrappable parts
+++                part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'
+++                opt_usage = format(optionals, groups)
+++                pos_usage = format(positionals, groups)
+++                opt_parts = _re.findall(part_regexp, opt_usage)
+++                pos_parts = _re.findall(part_regexp, pos_usage)
+++                assert ' '.join(opt_parts) == opt_usage
+++                assert ' '.join(pos_parts) == pos_usage
+++
+++                # helper for wrapping lines
+++                def get_lines(parts, indent, prefix=None):
+++                    lines = []
+++                    line = []
+++                    if prefix is not None:
+++                        line_len = len(prefix) - 1
+++                    else:
+++                        line_len = len(indent) - 1
+++                    for part in parts:
+++                        if line_len + 1 + len(part) > text_width:
+++                            lines.append(indent + ' '.join(line))
+++                            line = []
+++                            line_len = len(indent) - 1
+++                        line.append(part)
+++                        line_len += len(part) + 1
+++                    if line:
+++                        lines.append(indent + ' '.join(line))
+++                    if prefix is not None:
+++                        lines[0] = lines[0][len(indent):]
+++                    return lines
+++
+++                # if prog is short, follow it with optionals or positionals
+++                if len(prefix) + len(prog) <= 0.75 * text_width:
+++                    indent = ' ' * (len(prefix) + len(prog) + 1)
+++                    if opt_parts:
+++                        lines = get_lines([prog] + opt_parts, indent, prefix)
+++                        lines.extend(get_lines(pos_parts, indent))
+++                    elif pos_parts:
+++                        lines = get_lines([prog] + pos_parts, indent, prefix)
+++                    else:
+++                        lines = [prog]
+++
+++                # if prog is long, put it on its own line
+++                else:
+++                    indent = ' ' * len(prefix)
+++                    parts = opt_parts + pos_parts
+++                    lines = get_lines(parts, indent)
+++                    if len(lines) > 1:
+++                        lines = []
+++                        lines.extend(get_lines(opt_parts, indent))
+++                        lines.extend(get_lines(pos_parts, indent))
+++                    lines = [prog] + lines
+++
+++                # join lines into usage
+++                usage = '\n'.join(lines)
+++
+++        # prefix with 'usage:'
+++        return '%s%s\n\n' % (prefix, usage)
+++
+++    def _format_actions_usage(self, actions, groups):
+++        # find group indices and identify actions in groups
+++        group_actions = set()
+++        inserts = {}
+++        for group in groups:
+++            try:
+++                start = actions.index(group._group_actions[0])
+++            except ValueError:
+++                continue
+++            else:
+++                end = start + len(group._group_actions)
+++                if actions[start:end] == group._group_actions:
+++                    for action in group._group_actions:
+++                        group_actions.add(action)
+++                    if not group.required:
+++                        if start in inserts:
+++                            inserts[start] += ' ['
+++                        else:
+++                            inserts[start] = '['
+++                        inserts[end] = ']'
+++                    else:
+++                        if start in inserts:
+++                            inserts[start] += ' ('
+++                        else:
+++                            inserts[start] = '('
+++                        inserts[end] = ')'
+++                    for i in range(start + 1, end):
+++                        inserts[i] = '|'
+++
+++        # collect all actions format strings
+++        parts = []
+++        for i, action in enumerate(actions):
+++
+++            # suppressed arguments are marked with None
+++            # remove | separators for suppressed arguments
+++            if action.help is SUPPRESS:
+++                parts.append(None)
+++                if inserts.get(i) == '|':
+++                    inserts.pop(i)
+++                elif inserts.get(i + 1) == '|':
+++                    inserts.pop(i + 1)
+++
+++            # produce all arg strings
+++            elif not action.option_strings:
+++                part = self._format_args(action, action.dest)
+++
+++                # if it's in a group, strip the outer []
+++                if action in group_actions:
+++                    if part[0] == '[' and part[-1] == ']':
+++                        part = part[1:-1]
+++
+++                # add the action string to the list
+++                parts.append(part)
+++
+++            # produce the first way to invoke the option in brackets
+++            else:
+++                option_string = action.option_strings[0]
+++
+++                # if the Optional doesn't take a value, format is:
+++                #    -s or --long
+++                if action.nargs == 0:
+++                    part = '%s' % option_string
+++
+++                # if the Optional takes a value, format is:
+++                #    -s ARGS or --long ARGS
+++                else:
+++                    default = action.dest.upper()
+++                    args_string = self._format_args(action, default)
+++                    part = '%s %s' % (option_string, args_string)
+++
+++                # make it look optional if it's not required or in a group
+++                if not action.required and action not in group_actions:
+++                    part = '[%s]' % part
+++
+++                # add the action string to the list
+++                parts.append(part)
+++
+++        # insert things at the necessary indices
+++        for i in sorted(inserts, reverse=True):
+++            parts[i:i] = [inserts[i]]
+++
+++        # join all the action items with spaces
+++        text = ' '.join([item for item in parts if item is not None])
+++
+++        # clean up separators for mutually exclusive groups
+++        open = r'[\[(]'
+++        close = r'[\])]'
+++        text = _re.sub(r'(%s) ' % open, r'\1', text)
+++        text = _re.sub(r' (%s)' % close, r'\1', text)
+++        text = _re.sub(r'%s *%s' % (open, close), r'', text)
+++        text = _re.sub(r'\(([^|]*)\)', r'\1', text)
+++        text = text.strip()
+++
+++        # return the text
+++        return text
+++
+++    def _format_text(self, text):
+++        if '%(prog)' in text:
+++            text = text % dict(prog=self._prog)
+++        text_width = self._width - self._current_indent
+++        indent = ' ' * self._current_indent
+++        return self._fill_text(text, text_width, indent) + '\n\n'
+++
+++    def _format_action(self, action):
+++        # determine the required width and the entry label
+++        help_position = min(self._action_max_length + 2,
+++                            self._max_help_position)
+++        help_width = self._width - help_position
+++        action_width = help_position - self._current_indent - 2
+++        action_header = self._format_action_invocation(action)
+++
+++        # ho nelp; start on same line and add a final newline
+++        if not action.help:
+++            tup = self._current_indent, '', action_header
+++            action_header = '%*s%s\n' % tup
+++
+++        # short action name; start on the same line and pad two spaces
+++        elif len(action_header) <= action_width:
+++            tup = self._current_indent, '', action_width, action_header
+++            action_header = '%*s%-*s  ' % tup
+++            indent_first = 0
+++
+++        # long action name; start on the next line
+++        else:
+++            tup = self._current_indent, '', action_header
+++            action_header = '%*s%s\n' % tup
+++            indent_first = help_position
+++
+++        # collect the pieces of the action help
+++        parts = [action_header]
+++
+++        # if there was help for the action, add lines of help text
+++        if action.help:
+++            help_text = self._expand_help(action)
+++            help_lines = self._split_lines(help_text, help_width)
+++            parts.append('%*s%s\n' % (indent_first, '', help_lines[0]))
+++            for line in help_lines[1:]:
+++                parts.append('%*s%s\n' % (help_position, '', line))
+++
+++        # or add a newline if the description doesn't end with one
+++        elif not action_header.endswith('\n'):
+++            parts.append('\n')
+++
+++        # if there are any sub-actions, add their help as well
+++        for subaction in self._iter_indented_subactions(action):
+++            parts.append(self._format_action(subaction))
+++
+++        # return a single string
+++        return self._join_parts(parts)
+++
+++    def _format_action_invocation(self, action):
+++        if not action.option_strings:
+++            metavar, = self._metavar_formatter(action, action.dest)(1)
+++            return metavar
+++
+++        else:
+++            parts = []
+++
+++            # if the Optional doesn't take a value, format is:
+++            #    -s, --long
+++            if action.nargs == 0:
+++                parts.extend(action.option_strings)
+++
+++            # if the Optional takes a value, format is:
+++            #    -s ARGS, --long ARGS
+++            else:
+++                default = action.dest.upper()
+++                args_string = self._format_args(action, default)
+++                for option_string in action.option_strings:
+++                    parts.append('%s %s' % (option_string, args_string))
+++
+++            return ', '.join(parts)
+++
+++    def _metavar_formatter(self, action, default_metavar):
+++        if action.metavar is not None:
+++            result = action.metavar
+++        elif action.choices is not None:
+++            choice_strs = [str(choice) for choice in action.choices]
+++            result = '{%s}' % ','.join(choice_strs)
+++        else:
+++            result = default_metavar
+++
+++        def format(tuple_size):
+++            if isinstance(result, tuple):
+++                return result
+++            else:
+++                return (result, ) * tuple_size
+++        return format
+++
+++    def _format_args(self, action, default_metavar):
+++        get_metavar = self._metavar_formatter(action, default_metavar)
+++        if action.nargs is None:
+++            result = '%s' % get_metavar(1)
+++        elif action.nargs == OPTIONAL:
+++            result = '[%s]' % get_metavar(1)
+++        elif action.nargs == ZERO_OR_MORE:
+++            result = '[%s [%s ...]]' % get_metavar(2)
+++        elif action.nargs == ONE_OR_MORE:
+++            result = '%s [%s ...]' % get_metavar(2)
+++        elif action.nargs == REMAINDER:
+++            result = '...'
+++        elif action.nargs == PARSER:
+++            result = '%s ...' % get_metavar(1)
+++        else:
+++            formats = ['%s' for _ in range(action.nargs)]
+++            result = ' '.join(formats) % get_metavar(action.nargs)
+++        return result
+++
+++    def _expand_help(self, action):
+++        params = dict(vars(action), prog=self._prog)
+++        for name in list(params):
+++            if params[name] is SUPPRESS:
+++                del params[name]
+++        for name in list(params):
+++            if hasattr(params[name], '__name__'):
+++                params[name] = params[name].__name__
+++        if params.get('choices') is not None:
+++            choices_str = ', '.join([str(c) for c in params['choices']])
+++            params['choices'] = choices_str
+++        return self._get_help_string(action) % params
+++
+++    def _iter_indented_subactions(self, action):
+++        try:
+++            get_subactions = action._get_subactions
+++        except AttributeError:
+++            pass
+++        else:
+++            self._indent()
+++            for subaction in get_subactions():
+++                yield subaction
+++            self._dedent()
+++
+++    def _split_lines(self, text, width):
+++        text = self._whitespace_matcher.sub(' ', text).strip()
+++        return _textwrap.wrap(text, width)
+++
+++    def _fill_text(self, text, width, indent):
+++        text = self._whitespace_matcher.sub(' ', text).strip()
+++        return _textwrap.fill(text, width, initial_indent=indent,
+++                                           subsequent_indent=indent)
+++
+++    def _get_help_string(self, action):
+++        return action.help
+++
+++
+++class RawDescriptionHelpFormatter(HelpFormatter):
+++    """Help message formatter which retains any formatting in descriptions.
+++
+++    Only the name of this class is considered a public API. All the methods
+++    provided by the class are considered an implementation detail.
+++    """
+++
+++    def _fill_text(self, text, width, indent):
+++        return ''.join([indent + line for line in text.splitlines(True)])
+++
+++
+++class RawTextHelpFormatter(RawDescriptionHelpFormatter):
+++    """Help message formatter which retains formatting of all help text.
+++
+++    Only the name of this class is considered a public API. All the methods
+++    provided by the class are considered an implementation detail.
+++    """
+++
+++    def _split_lines(self, text, width):
+++        return text.splitlines()
+++
+++
+++class ArgumentDefaultsHelpFormatter(HelpFormatter):
+++    """Help message formatter which adds default values to argument help.
+++
+++    Only the name of this class is considered a public API. All the methods
+++    provided by the class are considered an implementation detail.
+++    """
+++
+++    def _get_help_string(self, action):
+++        help = action.help
+++        if '%(default)' not in action.help:
+++            if action.default is not SUPPRESS:
+++                defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
+++                if action.option_strings or action.nargs in defaulting_nargs:
+++                    help += ' (default: %(default)s)'
+++        return help
+++
+++
+++# =====================
+++# Options and Arguments
+++# =====================
+++
+++def _get_action_name(argument):
+++    if argument is None:
+++        return None
+++    elif argument.option_strings:
+++        return  '/'.join(argument.option_strings)
+++    elif argument.metavar not in (None, SUPPRESS):
+++        return argument.metavar
+++    elif argument.dest not in (None, SUPPRESS):
+++        return argument.dest
+++    else:
+++        return None
+++
+++
+++class ArgumentError(Exception):
+++    """An error from creating or using an argument (optional or positional).
+++
+++    The string value of this exception is the message, augmented with
+++    information about the argument that caused it.
+++    """
+++
+++    def __init__(self, argument, message):
+++        self.argument_name = _get_action_name(argument)
+++        self.message = message
+++
+++    def __str__(self):
+++        if self.argument_name is None:
+++            format = '%(message)s'
+++        else:
+++            format = 'argument %(argument_name)s: %(message)s'
+++        return format % dict(message=self.message,
+++                             argument_name=self.argument_name)
+++
+++
+++class ArgumentTypeError(Exception):
+++    """An error from trying to convert a command line string to a type."""
+++    pass
+++
+++
+++# ==============
+++# Action classes
+++# ==============
+++
+++class Action(_AttributeHolder):
+++    """Information about how to convert command line strings to Python objects.
+++
+++    Action objects are used by an ArgumentParser to represent the information
+++    needed to parse a single argument from one or more strings from the
+++    command line. The keyword arguments to the Action constructor are also
+++    all attributes of Action instances.
+++
+++    Keyword Arguments:
+++
+++        - option_strings -- A list of command-line option strings which
+++            should be associated with this action.
+++
+++        - dest -- The name of the attribute to hold the created object(s)
+++
+++        - nargs -- The number of command-line arguments that should be
+++            consumed. By default, one argument will be consumed and a single
+++            value will be produced.  Other values include:
+++                - N (an integer) consumes N arguments (and produces a list)
+++                - '?' consumes zero or one arguments
+++                - '*' consumes zero or more arguments (and produces a list)
+++                - '+' consumes one or more arguments (and produces a list)
+++            Note that the difference between the default and nargs=1 is that
+++            with the default, a single value will be produced, while with
+++            nargs=1, a list containing a single value will be produced.
+++
+++        - const -- The value to be produced if the option is specified and the
+++            option uses an action that takes no values.
+++
+++        - default -- The value to be produced if the option is not specified.
+++
+++        - type -- The type which the command-line arguments should be converted
+++            to, should be one of 'string', 'int', 'float', 'complex' or a
+++            callable object that accepts a single string argument. If None,
+++            'string' is assumed.
+++
+++        - choices -- A container of values that should be allowed. If not None,
+++            after a command-line argument has been converted to the appropriate
+++            type, an exception will be raised if it is not a member of this
+++            collection.
+++
+++        - required -- True if the action must always be specified at the
+++            command line. This is only meaningful for optional command-line
+++            arguments.
+++
+++        - help -- The help string describing the argument.
+++
+++        - metavar -- The name to be used for the option's argument with the
+++            help string. If None, the 'dest' value will be used as the name.
+++    """
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest,
+++                 nargs=None,
+++                 const=None,
+++                 default=None,
+++                 type=None,
+++                 choices=None,
+++                 required=False,
+++                 help=None,
+++                 metavar=None):
+++        self.option_strings = option_strings
+++        self.dest = dest
+++        self.nargs = nargs
+++        self.const = const
+++        self.default = default
+++        self.type = type
+++        self.choices = choices
+++        self.required = required
+++        self.help = help
+++        self.metavar = metavar
+++
+++    def _get_kwargs(self):
+++        names = [
+++            'option_strings',
+++            'dest',
+++            'nargs',
+++            'const',
+++            'default',
+++            'type',
+++            'choices',
+++            'help',
+++            'metavar',
+++        ]
+++        return [(name, getattr(self, name)) for name in names]
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        raise NotImplementedError(_('.__call__() not defined'))
+++
+++
+++class _StoreAction(Action):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest,
+++                 nargs=None,
+++                 const=None,
+++                 default=None,
+++                 type=None,
+++                 choices=None,
+++                 required=False,
+++                 help=None,
+++                 metavar=None):
+++        if nargs == 0:
+++            raise ValueError('nargs for store actions must be > 0; if you '
+++                             'have nothing to store, actions such as store '
+++                             'true or store const may be more appropriate')
+++        if const is not None and nargs != OPTIONAL:
+++            raise ValueError('nargs must be %r to supply const' % OPTIONAL)
+++        super(_StoreAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            nargs=nargs,
+++            const=const,
+++            default=default,
+++            type=type,
+++            choices=choices,
+++            required=required,
+++            help=help,
+++            metavar=metavar)
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        setattr(namespace, self.dest, values)
+++
+++
+++class _StoreConstAction(Action):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest,
+++                 const,
+++                 default=None,
+++                 required=False,
+++                 help=None,
+++                 metavar=None):
+++        super(_StoreConstAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            nargs=0,
+++            const=const,
+++            default=default,
+++            required=required,
+++            help=help)
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        setattr(namespace, self.dest, self.const)
+++
+++
+++class _StoreTrueAction(_StoreConstAction):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest,
+++                 default=False,
+++                 required=False,
+++                 help=None):
+++        super(_StoreTrueAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            const=True,
+++            default=default,
+++            required=required,
+++            help=help)
+++
+++
+++class _StoreFalseAction(_StoreConstAction):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest,
+++                 default=True,
+++                 required=False,
+++                 help=None):
+++        super(_StoreFalseAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            const=False,
+++            default=default,
+++            required=required,
+++            help=help)
+++
+++
+++class _AppendAction(Action):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest,
+++                 nargs=None,
+++                 const=None,
+++                 default=None,
+++                 type=None,
+++                 choices=None,
+++                 required=False,
+++                 help=None,
+++                 metavar=None):
+++        if nargs == 0:
+++            raise ValueError('nargs for append actions must be > 0; if arg '
+++                             'strings are not supplying the value to append, '
+++                             'the append const action may be more appropriate')
+++        if const is not None and nargs != OPTIONAL:
+++            raise ValueError('nargs must be %r to supply const' % OPTIONAL)
+++        super(_AppendAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            nargs=nargs,
+++            const=const,
+++            default=default,
+++            type=type,
+++            choices=choices,
+++            required=required,
+++            help=help,
+++            metavar=metavar)
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        items = _copy.copy(_ensure_value(namespace, self.dest, []))
+++        items.append(values)
+++        setattr(namespace, self.dest, items)
+++
+++
+++class _AppendConstAction(Action):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest,
+++                 const,
+++                 default=None,
+++                 required=False,
+++                 help=None,
+++                 metavar=None):
+++        super(_AppendConstAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            nargs=0,
+++            const=const,
+++            default=default,
+++            required=required,
+++            help=help,
+++            metavar=metavar)
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        items = _copy.copy(_ensure_value(namespace, self.dest, []))
+++        items.append(self.const)
+++        setattr(namespace, self.dest, items)
+++
+++
+++class _CountAction(Action):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest,
+++                 default=None,
+++                 required=False,
+++                 help=None):
+++        super(_CountAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            nargs=0,
+++            default=default,
+++            required=required,
+++            help=help)
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        new_count = _ensure_value(namespace, self.dest, 0) + 1
+++        setattr(namespace, self.dest, new_count)
+++
+++
+++class _HelpAction(Action):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 dest=SUPPRESS,
+++                 default=SUPPRESS,
+++                 help=None):
+++        super(_HelpAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            default=default,
+++            nargs=0,
+++            help=help)
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        parser.print_help()
+++        parser.exit()
+++
+++
+++class _VersionAction(Action):
+++
+++    def __init__(self,
+++                 option_strings,
+++                 version=None,
+++                 dest=SUPPRESS,
+++                 default=SUPPRESS,
+++                 help="show program's version number and exit"):
+++        super(_VersionAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            default=default,
+++            nargs=0,
+++            help=help)
+++        self.version = version
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        version = self.version
+++        if version is None:
+++            version = parser.version
+++        formatter = parser._get_formatter()
+++        formatter.add_text(version)
+++        parser.exit(message=formatter.format_help())
+++
+++
+++class _SubParsersAction(Action):
+++
+++    class _ChoicesPseudoAction(Action):
+++
+++        def __init__(self, name, help):
+++            sup = super(_SubParsersAction._ChoicesPseudoAction, self)
+++            sup.__init__(option_strings=[], dest=name, help=help)
+++
+++    def __init__(self,
+++                 option_strings,
+++                 prog,
+++                 parser_class,
+++                 dest=SUPPRESS,
+++                 help=None,
+++                 metavar=None):
+++
+++        self._prog_prefix = prog
+++        self._parser_class = parser_class
+++        self._name_parser_map = {}
+++        self._choices_actions = []
+++
+++        super(_SubParsersAction, self).__init__(
+++            option_strings=option_strings,
+++            dest=dest,
+++            nargs=PARSER,
+++            choices=self._name_parser_map,
+++            help=help,
+++            metavar=metavar)
+++
+++    def add_parser(self, name, **kwargs):
+++        # set prog from the existing prefix
+++        if kwargs.get('prog') is None:
+++            kwargs['prog'] = '%s %s' % (self._prog_prefix, name)
+++
+++        # create a pseudo-action to hold the choice help
+++        if 'help' in kwargs:
+++            help = kwargs.pop('help')
+++            choice_action = self._ChoicesPseudoAction(name, help)
+++            self._choices_actions.append(choice_action)
+++
+++        # create the parser and add it to the map
+++        parser = self._parser_class(**kwargs)
+++        self._name_parser_map[name] = parser
+++        return parser
+++
+++    def _get_subactions(self):
+++        return self._choices_actions
+++
+++    def __call__(self, parser, namespace, values, option_string=None):
+++        parser_name = values[0]
+++        arg_strings = values[1:]
+++
+++        # set the parser name if requested
+++        if self.dest is not SUPPRESS:
+++            setattr(namespace, self.dest, parser_name)
+++
+++        # select the parser
+++        try:
+++            parser = self._name_parser_map[parser_name]
+++        except KeyError:
+++            tup = parser_name, ', '.join(self._name_parser_map)
+++            msg = _('unknown parser %r (choices: %s)' % tup)
+++            raise ArgumentError(self, msg)
+++
+++        # parse all the remaining options into the namespace
+++        # store any unrecognized options on the object, so that the top
+++        # level parser can decide what to do with them
+++        namespace, arg_strings = parser.parse_known_args(arg_strings, namespace)
+++        if arg_strings:
+++            vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, [])
+++            getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings)
+++
+++
+++# ==============
+++# Type classes
+++# ==============
+++
+++class FileType(object):
+++    """Factory for creating file object types
+++
+++    Instances of FileType are typically passed as type= arguments to the
+++    ArgumentParser add_argument() method.
+++
+++    Keyword Arguments:
+++        - mode -- A string indicating how the file is to be opened. Accepts the
+++            same values as the builtin open() function.
+++        - bufsize -- The file's desired buffer size. Accepts the same values as
+++            the builtin open() function.
+++    """
+++
+++    def __init__(self, mode='r', bufsize=None):
+++        self._mode = mode
+++        self._bufsize = bufsize
+++
+++    def __call__(self, string):
+++        # the special argument "-" means sys.std{in,out}
+++        if string == '-':
+++            if 'r' in self._mode:
+++                return _sys.stdin
+++            elif 'w' in self._mode:
+++                return _sys.stdout
+++            else:
+++                msg = _('argument "-" with mode %r' % self._mode)
+++                raise ValueError(msg)
+++
+++        # all other arguments are used as file names
+++        if self._bufsize:
+++            return open(string, self._mode, self._bufsize)
+++        else:
+++            return open(string, self._mode)
+++
+++    def __repr__(self):
+++        args = [self._mode, self._bufsize]
+++        args_str = ', '.join([repr(arg) for arg in args if arg is not None])
+++        return '%s(%s)' % (type(self).__name__, args_str)
+++
+++# ===========================
+++# Optional and Positional Parsing
+++# ===========================
+++
+++class Namespace(_AttributeHolder):
+++    """Simple object for storing attributes.
+++
+++    Implements equality by attribute names and values, and provides a simple
+++    string representation.
+++    """
+++
+++    def __init__(self, **kwargs):
+++        for name in kwargs:
+++            setattr(self, name, kwargs[name])
+++
+++    __hash__ = None
+++
+++    def __eq__(self, other):
+++        return vars(self) == vars(other)
+++
+++    def __ne__(self, other):
+++        return not (self == other)
+++
+++    def __contains__(self, key):
+++        return key in self.__dict__
+++
+++
+++class _ActionsContainer(object):
+++
+++    def __init__(self,
+++                 description,
+++                 prefix_chars,
+++                 argument_default,
+++                 conflict_handler):
+++        super(_ActionsContainer, self).__init__()
+++
+++        self.description = description
+++        self.argument_default = argument_default
+++        self.prefix_chars = prefix_chars
+++        self.conflict_handler = conflict_handler
+++
+++        # set up registries
+++        self._registries = {}
+++
+++        # register actions
+++        self.register('action', None, _StoreAction)
+++        self.register('action', 'store', _StoreAction)
+++        self.register('action', 'store_const', _StoreConstAction)
+++        self.register('action', 'store_true', _StoreTrueAction)
+++        self.register('action', 'store_false', _StoreFalseAction)
+++        self.register('action', 'append', _AppendAction)
+++        self.register('action', 'append_const', _AppendConstAction)
+++        self.register('action', 'count', _CountAction)
+++        self.register('action', 'help', _HelpAction)
+++        self.register('action', 'version', _VersionAction)
+++        self.register('action', 'parsers', _SubParsersAction)
+++
+++        # raise an exception if the conflict handler is invalid
+++        self._get_handler()
+++
+++        # action storage
+++        self._actions = []
+++        self._option_string_actions = {}
+++
+++        # groups
+++        self._action_groups = []
+++        self._mutually_exclusive_groups = []
+++
+++        # defaults storage
+++        self._defaults = {}
+++
+++        # determines whether an "option" looks like a negative number
+++        self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$')
+++
+++        # whether or not there are any optionals that look like negative
+++        # numbers -- uses a list so it can be shared and edited
+++        self._has_negative_number_optionals = []
+++
+++    # ====================
+++    # Registration methods
+++    # ====================
+++    def register(self, registry_name, value, object):
+++        registry = self._registries.setdefault(registry_name, {})
+++        registry[value] = object
+++
+++    def _registry_get(self, registry_name, value, default=None):
+++        return self._registries[registry_name].get(value, default)
+++
+++    # ==================================
+++    # Namespace default accessor methods
+++    # ==================================
+++    def set_defaults(self, **kwargs):
+++        self._defaults.update(kwargs)
+++
+++        # if these defaults match any existing arguments, replace
+++        # the previous default on the object with the new one
+++        for action in self._actions:
+++            if action.dest in kwargs:
+++                action.default = kwargs[action.dest]
+++
+++    def get_default(self, dest):
+++        for action in self._actions:
+++            if action.dest == dest and action.default is not None:
+++                return action.default
+++        return self._defaults.get(dest, None)
+++
+++
+++    # =======================
+++    # Adding argument actions
+++    # =======================
+++    def add_argument(self, *args, **kwargs):
+++        """
+++        add_argument(dest, ..., name=value, ...)
+++        add_argument(option_string, option_string, ..., name=value, ...)
+++        """
+++
+++        # if no positional args are supplied or only one is supplied and
+++        # it doesn't look like an option string, parse a positional
+++        # argument
+++        chars = self.prefix_chars
+++        if not args or len(args) == 1 and args[0][0] not in chars:
+++            if args and 'dest' in kwargs:
+++                raise ValueError('dest supplied twice for positional argument')
+++            kwargs = self._get_positional_kwargs(*args, **kwargs)
+++
+++        # otherwise, we're adding an optional argument
+++        else:
+++            kwargs = self._get_optional_kwargs(*args, **kwargs)
+++
+++        # if no default was supplied, use the parser-level default
+++        if 'default' not in kwargs:
+++            dest = kwargs['dest']
+++            if dest in self._defaults:
+++                kwargs['default'] = self._defaults[dest]
+++            elif self.argument_default is not None:
+++                kwargs['default'] = self.argument_default
+++
+++        # create the action object, and add it to the parser
+++        action_class = self._pop_action_class(kwargs)
+++        if not _callable(action_class):
+++            raise ValueError('unknown action "%s"' % action_class)
+++        action = action_class(**kwargs)
+++
+++        # raise an error if the action type is not callable
+++        type_func = self._registry_get('type', action.type, action.type)
+++        if not _callable(type_func):
+++            raise ValueError('%r is not callable' % type_func)
+++
+++        return self._add_action(action)
+++
+++    def add_argument_group(self, *args, **kwargs):
+++        group = _ArgumentGroup(self, *args, **kwargs)
+++        self._action_groups.append(group)
+++        return group
+++
+++    def add_mutually_exclusive_group(self, **kwargs):
+++        group = _MutuallyExclusiveGroup(self, **kwargs)
+++        self._mutually_exclusive_groups.append(group)
+++        return group
+++
+++    def _add_action(self, action):
+++        # resolve any conflicts
+++        self._check_conflict(action)
+++
+++        # add to actions list
+++        self._actions.append(action)
+++        action.container = self
+++
+++        # index the action by any option strings it has
+++        for option_string in action.option_strings:
+++            self._option_string_actions[option_string] = action
+++
+++        # set the flag if any option strings look like negative numbers
+++        for option_string in action.option_strings:
+++            if self._negative_number_matcher.match(option_string):
+++                if not self._has_negative_number_optionals:
+++                    self._has_negative_number_optionals.append(True)
+++
+++        # return the created action
+++        return action
+++
+++    def _remove_action(self, action):
+++        self._actions.remove(action)
+++
+++    def _add_container_actions(self, container):
+++        # collect groups by titles
+++        title_group_map = {}
+++        for group in self._action_groups:
+++            if group.title in title_group_map:
+++                msg = _('cannot merge actions - two groups are named %r')
+++                raise ValueError(msg % (group.title))
+++            title_group_map[group.title] = group
+++
+++        # map each action to its group
+++        group_map = {}
+++        for group in container._action_groups:
+++
+++            # if a group with the title exists, use that, otherwise
+++            # create a new group matching the container's group
+++            if group.title not in title_group_map:
+++                title_group_map[group.title] = self.add_argument_group(
+++                    title=group.title,
+++                    description=group.description,
+++                    conflict_handler=group.conflict_handler)
+++
+++            # map the actions to their new group
+++            for action in group._group_actions:
+++                group_map[action] = title_group_map[group.title]
+++
+++        # add container's mutually exclusive groups
+++        # NOTE: if add_mutually_exclusive_group ever gains title= and
+++        # description= then this code will need to be expanded as above
+++        for group in container._mutually_exclusive_groups:
+++            mutex_group = self.add_mutually_exclusive_group(
+++                required=group.required)
+++
+++            # map the actions to their new mutex group
+++            for action in group._group_actions:
+++                group_map[action] = mutex_group
+++
+++        # add all actions to this container or their group
+++        for action in container._actions:
+++            group_map.get(action, self)._add_action(action)
+++
+++    def _get_positional_kwargs(self, dest, **kwargs):
+++        # make sure required is not specified
+++        if 'required' in kwargs:
+++            msg = _("'required' is an invalid argument for positionals")
+++            raise TypeError(msg)
+++
+++        # mark positional arguments as required if at least one is
+++        # always required
+++        if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]:
+++            kwargs['required'] = True
+++        if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:
+++            kwargs['required'] = True
+++
+++        # return the keyword arguments with no option strings
+++        return dict(kwargs, dest=dest, option_strings=[])
+++
+++    def _get_optional_kwargs(self, *args, **kwargs):
+++        # determine short and long option strings
+++        option_strings = []
+++        long_option_strings = []
+++        for option_string in args:
+++            # error on strings that don't start with an appropriate prefix
+++            if not option_string[0] in self.prefix_chars:
+++                msg = _('invalid option string %r: '
+++                        'must start with a character %r')
+++                tup = option_string, self.prefix_chars
+++                raise ValueError(msg % tup)
+++
+++            # strings starting with two prefix characters are long options
+++            option_strings.append(option_string)
+++            if option_string[0] in self.prefix_chars:
+++                if len(option_string) > 1:
+++                    if option_string[1] in self.prefix_chars:
+++                        long_option_strings.append(option_string)
+++
+++        # infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x'
+++        dest = kwargs.pop('dest', None)
+++        if dest is None:
+++            if long_option_strings:
+++                dest_option_string = long_option_strings[0]
+++            else:
+++                dest_option_string = option_strings[0]
+++            dest = dest_option_string.lstrip(self.prefix_chars)
+++            if not dest:
+++                msg = _('dest= is required for options like %r')
+++                raise ValueError(msg % option_string)
+++            dest = dest.replace('-', '_')
+++
+++        # return the updated keyword arguments
+++        return dict(kwargs, dest=dest, option_strings=option_strings)
+++
+++    def _pop_action_class(self, kwargs, default=None):
+++        action = kwargs.pop('action', default)
+++        return self._registry_get('action', action, action)
+++
+++    def _get_handler(self):
+++        # determine function from conflict handler string
+++        handler_func_name = '_handle_conflict_%s' % self.conflict_handler
+++        try:
+++            return getattr(self, handler_func_name)
+++        except AttributeError:
+++            msg = _('invalid conflict_resolution value: %r')
+++            raise ValueError(msg % self.conflict_handler)
+++
+++    def _check_conflict(self, action):
+++
+++        # find all options that conflict with this option
+++        confl_optionals = []
+++        for option_string in action.option_strings:
+++            if option_string in self._option_string_actions:
+++                confl_optional = self._option_string_actions[option_string]
+++                confl_optionals.append((option_string, confl_optional))
+++
+++        # resolve any conflicts
+++        if confl_optionals:
+++            conflict_handler = self._get_handler()
+++            conflict_handler(action, confl_optionals)
+++
+++    def _handle_conflict_error(self, action, conflicting_actions):
+++        message = _('conflicting option string(s): %s')
+++        conflict_string = ', '.join([option_string
+++                                     for option_string, action
+++                                     in conflicting_actions])
+++        raise ArgumentError(action, message % conflict_string)
+++
+++    def _handle_conflict_resolve(self, action, conflicting_actions):
+++
+++        # remove all conflicting options
+++        for option_string, action in conflicting_actions:
+++
+++            # remove the conflicting option
+++            action.option_strings.remove(option_string)
+++            self._option_string_actions.pop(option_string, None)
+++
+++            # if the option now has no option string, remove it from the
+++            # container holding it
+++            if not action.option_strings:
+++                action.container._remove_action(action)
+++
+++
+++class _ArgumentGroup(_ActionsContainer):
+++
+++    def __init__(self, container, title=None, description=None, **kwargs):
+++        # add any missing keyword arguments by checking the container
+++        update = kwargs.setdefault
+++        update('conflict_handler', container.conflict_handler)
+++        update('prefix_chars', container.prefix_chars)
+++        update('argument_default', container.argument_default)
+++        super_init = super(_ArgumentGroup, self).__init__
+++        super_init(description=description, **kwargs)
+++
+++        # group attributes
+++        self.title = title
+++        self._group_actions = []
+++
+++        # share most attributes with the container
+++        self._registries = container._registries
+++        self._actions = container._actions
+++        self._option_string_actions = container._option_string_actions
+++        self._defaults = container._defaults
+++        self._has_negative_number_optionals = \
+++            container._has_negative_number_optionals
+++
+++    def _add_action(self, action):
+++        action = super(_ArgumentGroup, self)._add_action(action)
+++        self._group_actions.append(action)
+++        return action
+++
+++    def _remove_action(self, action):
+++        super(_ArgumentGroup, self)._remove_action(action)
+++        self._group_actions.remove(action)
+++
+++
+++class _MutuallyExclusiveGroup(_ArgumentGroup):
+++
+++    def __init__(self, container, required=False):
+++        super(_MutuallyExclusiveGroup, self).__init__(container)
+++        self.required = required
+++        self._container = container
+++
+++    def _add_action(self, action):
+++        if action.required:
+++            msg = _('mutually exclusive arguments must be optional')
+++            raise ValueError(msg)
+++        action = self._container._add_action(action)
+++        self._group_actions.append(action)
+++        return action
+++
+++    def _remove_action(self, action):
+++        self._container._remove_action(action)
+++        self._group_actions.remove(action)
+++
+++
+++class ArgumentParser(_AttributeHolder, _ActionsContainer):
+++    """Object for parsing command line strings into Python objects.
+++
+++    Keyword Arguments:
+++        - prog -- The name of the program (default: sys.argv[0])
+++        - usage -- A usage message (default: auto-generated from arguments)
+++        - description -- A description of what the program does
+++        - epilog -- Text following the argument descriptions
+++        - parents -- Parsers whose arguments should be copied into this one
+++        - formatter_class -- HelpFormatter class for printing help messages
+++        - prefix_chars -- Characters that prefix optional arguments
+++        - fromfile_prefix_chars -- Characters that prefix files containing
+++            additional arguments
+++        - argument_default -- The default value for all arguments
+++        - conflict_handler -- String indicating how to handle conflicts
+++        - add_help -- Add a -h/-help option
+++    """
+++
+++    def __init__(self,
+++                 prog=None,
+++                 usage=None,
+++                 description=None,
+++                 epilog=None,
+++                 version=None,
+++                 parents=[],
+++                 formatter_class=HelpFormatter,
+++                 prefix_chars='-',
+++                 fromfile_prefix_chars=None,
+++                 argument_default=None,
+++                 conflict_handler='error',
+++                 add_help=True):
+++
+++        if version is not None:
+++            import warnings
+++            warnings.warn(
+++                """The "version" argument to ArgumentParser is deprecated. """
+++                """Please use """
+++                """"add_argument(..., action='version', version="N", ...)" """
+++                """instead""", DeprecationWarning)
+++
+++        superinit = super(ArgumentParser, self).__init__
+++        superinit(description=description,
+++                  prefix_chars=prefix_chars,
+++                  argument_default=argument_default,
+++                  conflict_handler=conflict_handler)
+++
+++        # default setting for prog
+++        if prog is None:
+++            prog = _os.path.basename(_sys.argv[0])
+++
+++        self.prog = prog
+++        self.usage = usage
+++        self.epilog = epilog
+++        self.version = version
+++        self.formatter_class = formatter_class
+++        self.fromfile_prefix_chars = fromfile_prefix_chars
+++        self.add_help = add_help
+++
+++        add_group = self.add_argument_group
+++        self._positionals = add_group(_('positional arguments'))
+++        self._optionals = add_group(_('optional arguments'))
+++        self._subparsers = None
+++
+++        # register types
+++        def identity(string):
+++            return string
+++        self.register('type', None, identity)
+++
+++        # add help and version arguments if necessary
+++        # (using explicit default to override global argument_default)
+++        if '-' in prefix_chars:
+++            default_prefix = '-'
+++        else:
+++            default_prefix = prefix_chars[0]
+++        if self.add_help:
+++            self.add_argument(
+++                default_prefix+'h', default_prefix*2+'help',
+++                action='help', default=SUPPRESS,
+++                help=_('show this help message and exit'))
+++        if self.version:
+++            self.add_argument(
+++                default_prefix+'v', default_prefix*2+'version',
+++                action='version', default=SUPPRESS,
+++                version=self.version,
+++                help=_("show program's version number and exit"))
+++
+++        # add parent arguments and defaults
+++        for parent in parents:
+++            self._add_container_actions(parent)
+++            try:
+++                defaults = parent._defaults
+++            except AttributeError:
+++                pass
+++            else:
+++                self._defaults.update(defaults)
+++
+++    # =======================
+++    # Pretty __repr__ methods
+++    # =======================
+++    def _get_kwargs(self):
+++        names = [
+++            'prog',
+++            'usage',
+++            'description',
+++            'version',
+++            'formatter_class',
+++            'conflict_handler',
+++            'add_help',
+++        ]
+++        return [(name, getattr(self, name)) for name in names]
+++
+++    # ==================================
+++    # Optional/Positional adding methods
+++    # ==================================
+++    def add_subparsers(self, **kwargs):
+++        if self._subparsers is not None:
+++            self.error(_('cannot have multiple subparser arguments'))
+++
+++        # add the parser class to the arguments if it's not present
+++        kwargs.setdefault('parser_class', type(self))
+++
+++        if 'title' in kwargs or 'description' in kwargs:
+++            title = _(kwargs.pop('title', 'subcommands'))
+++            description = _(kwargs.pop('description', None))
+++            self._subparsers = self.add_argument_group(title, description)
+++        else:
+++            self._subparsers = self._positionals
+++
+++        # prog defaults to the usage message of this parser, skipping
+++        # optional arguments and with no "usage:" prefix
+++        if kwargs.get('prog') is None:
+++            formatter = self._get_formatter()
+++            positionals = self._get_positional_actions()
+++            groups = self._mutually_exclusive_groups
+++            formatter.add_usage(self.usage, positionals, groups, '')
+++            kwargs['prog'] = formatter.format_help().strip()
+++
+++        # create the parsers action and add it to the positionals list
+++        parsers_class = self._pop_action_class(kwargs, 'parsers')
+++        action = parsers_class(option_strings=[], **kwargs)
+++        self._subparsers._add_action(action)
+++
+++        # return the created parsers action
+++        return action
+++
+++    def _add_action(self, action):
+++        if action.option_strings:
+++            self._optionals._add_action(action)
+++        else:
+++            self._positionals._add_action(action)
+++        return action
+++
+++    def _get_optional_actions(self):
+++        return [action
+++                for action in self._actions
+++                if action.option_strings]
+++
+++    def _get_positional_actions(self):
+++        return [action
+++                for action in self._actions
+++                if not action.option_strings]
+++
+++    # =====================================
+++    # Command line argument parsing methods
+++    # =====================================
+++    def parse_args(self, args=None, namespace=None):
+++        args, argv = self.parse_known_args(args, namespace)
+++        if argv:
+++            msg = _('unrecognized arguments: %s')
+++            self.error(msg % ' '.join(argv))
+++        return args
+++
+++    def parse_known_args(self, args=None, namespace=None):
+++        # args default to the system args
+++        if args is None:
+++            args = _sys.argv[1:]
+++
+++        # default Namespace built from parser defaults
+++        if namespace is None:
+++            namespace = Namespace()
+++
+++        # add any action defaults that aren't present
+++        for action in self._actions:
+++            if action.dest is not SUPPRESS:
+++                if not hasattr(namespace, action.dest):
+++                    if action.default is not SUPPRESS:
+++                        default = action.default
+++                        if isinstance(action.default, basestring):
+++                            default = self._get_value(action, default)
+++                        setattr(namespace, action.dest, default)
+++
+++        # add any parser defaults that aren't present
+++        for dest in self._defaults:
+++            if not hasattr(namespace, dest):
+++                setattr(namespace, dest, self._defaults[dest])
+++
+++        # parse the arguments and exit if there are any errors
+++        try:
+++            namespace, args = self._parse_known_args(args, namespace)
+++            if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR):
+++                args.extend(getattr(namespace, _UNRECOGNIZED_ARGS_ATTR))
+++                delattr(namespace, _UNRECOGNIZED_ARGS_ATTR)
+++            return namespace, args
+++        except ArgumentError:
+++            err = _sys.exc_info()[1]
+++            self.error(str(err))
+++
+++    def _parse_known_args(self, arg_strings, namespace):
+++        # replace arg strings that are file references
+++        if self.fromfile_prefix_chars is not None:
+++            arg_strings = self._read_args_from_files(arg_strings)
+++
+++        # map all mutually exclusive arguments to the other arguments
+++        # they can't occur with
+++        action_conflicts = {}
+++        for mutex_group in self._mutually_exclusive_groups:
+++            group_actions = mutex_group._group_actions
+++            for i, mutex_action in enumerate(mutex_group._group_actions):
+++                conflicts = action_conflicts.setdefault(mutex_action, [])
+++                conflicts.extend(group_actions[:i])
+++                conflicts.extend(group_actions[i + 1:])
+++
+++        # find all option indices, and determine the arg_string_pattern
+++        # which has an 'O' if there is an option at an index,
+++        # an 'A' if there is an argument, or a '-' if there is a '--'
+++        option_string_indices = {}
+++        arg_string_pattern_parts = []
+++        arg_strings_iter = iter(arg_strings)
+++        for i, arg_string in enumerate(arg_strings_iter):
+++
+++            # all args after -- are non-options
+++            if arg_string == '--':
+++                arg_string_pattern_parts.append('-')
+++                for arg_string in arg_strings_iter:
+++                    arg_string_pattern_parts.append('A')
+++
+++            # otherwise, add the arg to the arg strings
+++            # and note the index if it was an option
+++            else:
+++                option_tuple = self._parse_optional(arg_string)
+++                if option_tuple is None:
+++                    pattern = 'A'
+++                else:
+++                    option_string_indices[i] = option_tuple
+++                    pattern = 'O'
+++                arg_string_pattern_parts.append(pattern)
+++
+++        # join the pieces together to form the pattern
+++        arg_strings_pattern = ''.join(arg_string_pattern_parts)
+++
+++        # converts arg strings to the appropriate and then takes the action
+++        seen_actions = set()
+++        seen_non_default_actions = set()
+++
+++        def take_action(action, argument_strings, option_string=None):
+++            seen_actions.add(action)
+++            argument_values = self._get_values(action, argument_strings)
+++
+++            # error if this argument is not allowed with other previously
+++            # seen arguments, assuming that actions that use the default
+++            # value don't really count as "present"
+++            if argument_values is not action.default:
+++                seen_non_default_actions.add(action)
+++                for conflict_action in action_conflicts.get(action, []):
+++                    if conflict_action in seen_non_default_actions:
+++                        msg = _('not allowed with argument %s')
+++                        action_name = _get_action_name(conflict_action)
+++                        raise ArgumentError(action, msg % action_name)
+++
+++            # take the action if we didn't receive a SUPPRESS value
+++            # (e.g. from a default)
+++            if argument_values is not SUPPRESS:
+++                action(self, namespace, argument_values, option_string)
+++
+++        # function to convert arg_strings into an optional action
+++        def consume_optional(start_index):
+++
+++            # get the optional identified at this index
+++            option_tuple = option_string_indices[start_index]
+++            action, option_string, explicit_arg = option_tuple
+++
+++            # identify additional optionals in the same arg string
+++            # (e.g. -xyz is the same as -x -y -z if no args are required)
+++            match_argument = self._match_argument
+++            action_tuples = []
+++            while True:
+++
+++                # if we found no optional action, skip it
+++                if action is None:
+++                    extras.append(arg_strings[start_index])
+++                    return start_index + 1
+++
+++                # if there is an explicit argument, try to match the
+++                # optional's string arguments to only this
+++                if explicit_arg is not None:
+++                    arg_count = match_argument(action, 'A')
+++
+++                    # if the action is a single-dash option and takes no
+++                    # arguments, try to parse more single-dash options out
+++                    # of the tail of the option string
+++                    chars = self.prefix_chars
+++                    if arg_count == 0 and option_string[1] not in chars:
+++                        action_tuples.append((action, [], option_string))
+++                        char = option_string[0]
+++                        option_string = char + explicit_arg[0]
+++                        new_explicit_arg = explicit_arg[1:] or None
+++                        optionals_map = self._option_string_actions
+++                        if option_string in optionals_map:
+++                            action = optionals_map[option_string]
+++                            explicit_arg = new_explicit_arg
+++                        else:
+++                            msg = _('ignored explicit argument %r')
+++                            raise ArgumentError(action, msg % explicit_arg)
+++
+++                    # if the action expect exactly one argument, we've
+++                    # successfully matched the option; exit the loop
+++                    elif arg_count == 1:
+++                        stop = start_index + 1
+++                        args = [explicit_arg]
+++                        action_tuples.append((action, args, option_string))
+++                        break
+++
+++                    # error if a double-dash option did not use the
+++                    # explicit argument
+++                    else:
+++                        msg = _('ignored explicit argument %r')
+++                        raise ArgumentError(action, msg % explicit_arg)
+++
+++                # if there is no explicit argument, try to match the
+++                # optional's string arguments with the following strings
+++                # if successful, exit the loop
+++                else:
+++                    start = start_index + 1
+++                    selected_patterns = arg_strings_pattern[start:]
+++                    arg_count = match_argument(action, selected_patterns)
+++                    stop = start + arg_count
+++                    args = arg_strings[start:stop]
+++                    action_tuples.append((action, args, option_string))
+++                    break
+++
+++            # add the Optional to the list and return the index at which
+++            # the Optional's string args stopped
+++            assert action_tuples
+++            for action, args, option_string in action_tuples:
+++                take_action(action, args, option_string)
+++            return stop
+++
+++        # the list of Positionals left to be parsed; this is modified
+++        # by consume_positionals()
+++        positionals = self._get_positional_actions()
+++
+++        # function to convert arg_strings into positional actions
+++        def consume_positionals(start_index):
+++            # match as many Positionals as possible
+++            match_partial = self._match_arguments_partial
+++            selected_pattern = arg_strings_pattern[start_index:]
+++            arg_counts = match_partial(positionals, selected_pattern)
+++
+++            # slice off the appropriate arg strings for each Positional
+++            # and add the Positional and its args to the list
+++            for action, arg_count in zip(positionals, arg_counts):
+++                args = arg_strings[start_index: start_index + arg_count]
+++                start_index += arg_count
+++                take_action(action, args)
+++
+++            # slice off the Positionals that we just parsed and return the
+++            # index at which the Positionals' string args stopped
+++            positionals[:] = positionals[len(arg_counts):]
+++            return start_index
+++
+++        # consume Positionals and Optionals alternately, until we have
+++        # passed the last option string
+++        extras = []
+++        start_index = 0
+++        if option_string_indices:
+++            max_option_string_index = max(option_string_indices)
+++        else:
+++            max_option_string_index = -1
+++        while start_index <= max_option_string_index:
+++
+++            # consume any Positionals preceding the next option
+++            next_option_string_index = min([
+++                index
+++                for index in option_string_indices
+++                if index >= start_index])
+++            if start_index != next_option_string_index:
+++                positionals_end_index = consume_positionals(start_index)
+++
+++                # only try to parse the next optional if we didn't consume
+++                # the option string during the positionals parsing
+++                if positionals_end_index > start_index:
+++                    start_index = positionals_end_index
+++                    continue
+++                else:
+++                    start_index = positionals_end_index
+++
+++            # if we consumed all the positionals we could and we're not
+++            # at the index of an option string, there were extra arguments
+++            if start_index not in option_string_indices:
+++                strings = arg_strings[start_index:next_option_string_index]
+++                extras.extend(strings)
+++                start_index = next_option_string_index
+++
+++            # consume the next optional and any arguments for it
+++            start_index = consume_optional(start_index)
+++
+++        # consume any positionals following the last Optional
+++        stop_index = consume_positionals(start_index)
+++
+++        # if we didn't consume all the argument strings, there were extras
+++        extras.extend(arg_strings[stop_index:])
+++
+++        # if we didn't use all the Positional objects, there were too few
+++        # arg strings supplied.
+++        if positionals:
+++            self.error(_('too few arguments'))
+++
+++        # make sure all required actions were present
+++        for action in self._actions:
+++            if action.required:
+++                if action not in seen_actions:
+++                    name = _get_action_name(action)
+++                    self.error(_('argument %s is required') % name)
+++
+++        # make sure all required groups had one option present
+++        for group in self._mutually_exclusive_groups:
+++            if group.required:
+++                for action in group._group_actions:
+++                    if action in seen_non_default_actions:
+++                        break
+++
+++                # if no actions were used, report the error
+++                else:
+++                    names = [_get_action_name(action)
+++                             for action in group._group_actions
+++                             if action.help is not SUPPRESS]
+++                    msg = _('one of the arguments %s is required')
+++                    self.error(msg % ' '.join(names))
+++
+++        # return the updated namespace and the extra arguments
+++        return namespace, extras
+++
+++    def _read_args_from_files(self, arg_strings):
+++        # expand arguments referencing files
+++        new_arg_strings = []
+++        for arg_string in arg_strings:
+++
+++            # for regular arguments, just add them back into the list
+++            if arg_string[0] not in self.fromfile_prefix_chars:
+++                new_arg_strings.append(arg_string)
+++
+++            # replace arguments referencing files with the file content
+++            else:
+++                try:
+++                    args_file = open(arg_string[1:])
+++                    try:
+++                        arg_strings = []
+++                        for arg_line in args_file.read().splitlines():
+++                            for arg in self.convert_arg_line_to_args(arg_line):
+++                                arg_strings.append(arg)
+++                        arg_strings = self._read_args_from_files(arg_strings)
+++                        new_arg_strings.extend(arg_strings)
+++                    finally:
+++                        args_file.close()
+++                except IOError:
+++                    err = _sys.exc_info()[1]
+++                    self.error(str(err))
+++
+++        # return the modified argument list
+++        return new_arg_strings
+++
+++    def convert_arg_line_to_args(self, arg_line):
+++        return [arg_line]
+++
+++    def _match_argument(self, action, arg_strings_pattern):
+++        # match the pattern for this action to the arg strings
+++        nargs_pattern = self._get_nargs_pattern(action)
+++        match = _re.match(nargs_pattern, arg_strings_pattern)
+++
+++        # raise an exception if we weren't able to find a match
+++        if match is None:
+++            nargs_errors = {
+++                None: _('expected one argument'),
+++                OPTIONAL: _('expected at most one argument'),
+++                ONE_OR_MORE: _('expected at least one argument'),
+++            }
+++            default = _('expected %s argument(s)') % action.nargs
+++            msg = nargs_errors.get(action.nargs, default)
+++            raise ArgumentError(action, msg)
+++
+++        # return the number of arguments matched
+++        return len(match.group(1))
+++
+++    def _match_arguments_partial(self, actions, arg_strings_pattern):
+++        # progressively shorten the actions list by slicing off the
+++        # final actions until we find a match
+++        result = []
+++        for i in range(len(actions), 0, -1):
+++            actions_slice = actions[:i]
+++            pattern = ''.join([self._get_nargs_pattern(action)
+++                               for action in actions_slice])
+++            match = _re.match(pattern, arg_strings_pattern)
+++            if match is not None:
+++                result.extend([len(string) for string in match.groups()])
+++                break
+++
+++        # return the list of arg string counts
+++        return result
+++
+++    def _parse_optional(self, arg_string):
+++        # if it's an empty string, it was meant to be a positional
+++        if not arg_string:
+++            return None
+++
+++        # if it doesn't start with a prefix, it was meant to be positional
+++        if not arg_string[0] in self.prefix_chars:
+++            return None
+++
+++        # if the option string is present in the parser, return the action
+++        if arg_string in self._option_string_actions:
+++            action = self._option_string_actions[arg_string]
+++            return action, arg_string, None
+++
+++        # if it's just a single character, it was meant to be positional
+++        if len(arg_string) == 1:
+++            return None
+++
+++        # if the option string before the "=" is present, return the action
+++        if '=' in arg_string:
+++            option_string, explicit_arg = arg_string.split('=', 1)
+++            if option_string in self._option_string_actions:
+++                action = self._option_string_actions[option_string]
+++                return action, option_string, explicit_arg
+++
+++        # search through all possible prefixes of the option string
+++        # and all actions in the parser for possible interpretations
+++        option_tuples = self._get_option_tuples(arg_string)
+++
+++        # if multiple actions match, the option string was ambiguous
+++        if len(option_tuples) > 1:
+++            options = ', '.join([option_string
+++                for action, option_string, explicit_arg in option_tuples])
+++            tup = arg_string, options
+++            self.error(_('ambiguous option: %s could match %s') % tup)
+++
+++        # if exactly one action matched, this segmentation is good,
+++        # so return the parsed action
+++        elif len(option_tuples) == 1:
+++            option_tuple, = option_tuples
+++            return option_tuple
+++
+++        # if it was not found as an option, but it looks like a negative
+++        # number, it was meant to be positional
+++        # unless there are negative-number-like options
+++        if self._negative_number_matcher.match(arg_string):
+++            if not self._has_negative_number_optionals:
+++                return None
+++
+++        # if it contains a space, it was meant to be a positional
+++        if ' ' in arg_string:
+++            return None
+++
+++        # it was meant to be an optional but there is no such option
+++        # in this parser (though it might be a valid option in a subparser)
+++        return None, arg_string, None
+++
+++    def _get_option_tuples(self, option_string):
+++        result = []
+++
+++        # option strings starting with two prefix characters are only
+++        # split at the '='
+++        chars = self.prefix_chars
+++        if option_string[0] in chars and option_string[1] in chars:
+++            if '=' in option_string:
+++                option_prefix, explicit_arg = option_string.split('=', 1)
+++            else:
+++                option_prefix = option_string
+++                explicit_arg = None
+++            for option_string in self._option_string_actions:
+++                if option_string.startswith(option_prefix):
+++                    action = self._option_string_actions[option_string]
+++                    tup = action, option_string, explicit_arg
+++                    result.append(tup)
+++
+++        # single character options can be concatenated with their arguments
+++        # but multiple character options always have to have their argument
+++        # separate
+++        elif option_string[0] in chars and option_string[1] not in chars:
+++            option_prefix = option_string
+++            explicit_arg = None
+++            short_option_prefix = option_string[:2]
+++            short_explicit_arg = option_string[2:]
+++
+++            for option_string in self._option_string_actions:
+++                if option_string == short_option_prefix:
+++                    action = self._option_string_actions[option_string]
+++                    tup = action, option_string, short_explicit_arg
+++                    result.append(tup)
+++                elif option_string.startswith(option_prefix):
+++                    action = self._option_string_actions[option_string]
+++                    tup = action, option_string, explicit_arg
+++                    result.append(tup)
+++
+++        # shouldn't ever get here
+++        else:
+++            self.error(_('unexpected option string: %s') % option_string)
+++
+++        # return the collected option tuples
+++        return result
+++
+++    def _get_nargs_pattern(self, action):
+++        # in all examples below, we have to allow for '--' args
+++        # which are represented as '-' in the pattern
+++        nargs = action.nargs
+++
+++        # the default (None) is assumed to be a single argument
+++        if nargs is None:
+++            nargs_pattern = '(-*A-*)'
+++
+++        # allow zero or one arguments
+++        elif nargs == OPTIONAL:
+++            nargs_pattern = '(-*A?-*)'
+++
+++        # allow zero or more arguments
+++        elif nargs == ZERO_OR_MORE:
+++            nargs_pattern = '(-*[A-]*)'
+++
+++        # allow one or more arguments
+++        elif nargs == ONE_OR_MORE:
+++            nargs_pattern = '(-*A[A-]*)'
+++
+++        # allow any number of options or arguments
+++        elif nargs == REMAINDER:
+++            nargs_pattern = '([-AO]*)'
+++
+++        # allow one argument followed by any number of options or arguments
+++        elif nargs == PARSER:
+++            nargs_pattern = '(-*A[-AO]*)'
+++
+++        # all others should be integers
+++        else:
+++            nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
+++
+++        # if this is an optional action, -- is not allowed
+++        if action.option_strings:
+++            nargs_pattern = nargs_pattern.replace('-*', '')
+++            nargs_pattern = nargs_pattern.replace('-', '')
+++
+++        # return the pattern
+++        return nargs_pattern
+++
+++    # ========================
+++    # Value conversion methods
+++    # ========================
+++    def _get_values(self, action, arg_strings):
+++        # for everything but PARSER args, strip out '--'
+++        if action.nargs not in [PARSER, REMAINDER]:
+++            arg_strings = [s for s in arg_strings if s != '--']
+++
+++        # optional argument produces a default when not present
+++        if not arg_strings and action.nargs == OPTIONAL:
+++            if action.option_strings:
+++                value = action.const
+++            else:
+++                value = action.default
+++            if isinstance(value, basestring):
+++                value = self._get_value(action, value)
+++                self._check_value(action, value)
+++
+++        # when nargs='*' on a positional, if there were no command-line
+++        # args, use the default if it is anything other than None
+++        elif (not arg_strings and action.nargs == ZERO_OR_MORE and
+++              not action.option_strings):
+++            if action.default is not None:
+++                value = action.default
+++            else:
+++                value = arg_strings
+++            self._check_value(action, value)
+++
+++        # single argument or optional argument produces a single value
+++        elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:
+++            arg_string, = arg_strings
+++            value = self._get_value(action, arg_string)
+++            self._check_value(action, value)
+++
+++        # REMAINDER arguments convert all values, checking none
+++        elif action.nargs == REMAINDER:
+++            value = [self._get_value(action, v) for v in arg_strings]
+++
+++        # PARSER arguments convert all values, but check only the first
+++        elif action.nargs == PARSER:
+++            value = [self._get_value(action, v) for v in arg_strings]
+++            self._check_value(action, value[0])
+++
+++        # all other types of nargs produce a list
+++        else:
+++            value = [self._get_value(action, v) for v in arg_strings]
+++            for v in value:
+++                self._check_value(action, v)
+++
+++        # return the converted value
+++        return value
+++
+++    def _get_value(self, action, arg_string):
+++        type_func = self._registry_get('type', action.type, action.type)
+++        if not _callable(type_func):
+++            msg = _('%r is not callable')
+++            raise ArgumentError(action, msg % type_func)
+++
+++        # convert the value to the appropriate type
+++        try:
+++            result = type_func(arg_string)
+++
+++        # ArgumentTypeErrors indicate errors
+++        except ArgumentTypeError:
+++            name = getattr(action.type, '__name__', repr(action.type))
+++            msg = str(_sys.exc_info()[1])
+++            raise ArgumentError(action, msg)
+++
+++        # TypeErrors or ValueErrors also indicate errors
+++        except (TypeError, ValueError):
+++            name = getattr(action.type, '__name__', repr(action.type))
+++            msg = _('invalid %s value: %r')
+++            raise ArgumentError(action, msg % (name, arg_string))
+++
+++        # return the converted value
+++        return result
+++
+++    def _check_value(self, action, value):
+++        # converted value must be one of the choices (if specified)
+++        if action.choices is not None and value not in action.choices:
+++            tup = value, ', '.join(map(repr, action.choices))
+++            msg = _('invalid choice: %r (choose from %s)') % tup
+++            raise ArgumentError(action, msg)
+++
+++    # =======================
+++    # Help-formatting methods
+++    # =======================
+++    def format_usage(self):
+++        formatter = self._get_formatter()
+++        formatter.add_usage(self.usage, self._actions,
+++                            self._mutually_exclusive_groups)
+++        return formatter.format_help()
+++
+++    def format_help(self):
+++        formatter = self._get_formatter()
+++
+++        # usage
+++        formatter.add_usage(self.usage, self._actions,
+++                            self._mutually_exclusive_groups)
+++
+++        # description
+++        formatter.add_text(self.description)
+++
+++        # positionals, optionals and user-defined groups
+++        for action_group in self._action_groups:
+++            formatter.start_section(action_group.title)
+++            formatter.add_text(action_group.description)
+++            formatter.add_arguments(action_group._group_actions)
+++            formatter.end_section()
+++
+++        # epilog
+++        formatter.add_text(self.epilog)
+++
+++        # determine help from format above
+++        return formatter.format_help()
+++
+++    def format_version(self):
+++        import warnings
+++        warnings.warn(
+++            'The format_version method is deprecated -- the "version" '
+++            'argument to ArgumentParser is no longer supported.',
+++            DeprecationWarning)
+++        formatter = self._get_formatter()
+++        formatter.add_text(self.version)
+++        return formatter.format_help()
+++
+++    def _get_formatter(self):
+++        return self.formatter_class(prog=self.prog)
+++
+++    # =====================
+++    # Help-printing methods
+++    # =====================
+++    def print_usage(self, file=None):
+++        if file is None:
+++            file = _sys.stdout
+++        self._print_message(self.format_usage(), file)
+++
+++    def print_help(self, file=None):
+++        if file is None:
+++            file = _sys.stdout
+++        self._print_message(self.format_help(), file)
+++
+++    def print_version(self, file=None):
+++        import warnings
+++        warnings.warn(
+++            'The print_version method is deprecated -- the "version" '
+++            'argument to ArgumentParser is no longer supported.',
+++            DeprecationWarning)
+++        self._print_message(self.format_version(), file)
+++
+++    def _print_message(self, message, file=None):
+++        if message:
+++            if file is None:
+++                file = _sys.stderr
+++            file.write(message)
+++
+++    # ===============
+++    # Exiting methods
+++    # ===============
+++    def exit(self, status=0, message=None):
+++        if message:
+++            self._print_message(message, _sys.stderr)
+++        _sys.exit(status)
+++
+++    def error(self, message):
+++        """error(message: string)
+++
+++        Prints a usage message incorporating the message to stderr and
+++        exits.
+++
+++        If you override this in a subclass, it should not return -- it
+++        should either exit or raise an exception.
+++        """
+++        self.print_usage(_sys.stderr)
+++        self.exit(2, _('%s: error: %s\n') % (self.prog, message))
++diff -up mozilla-aurora/rebase/contextdecorator.py.rebase-dir mozilla-aurora/rebase/contextdecorator.py
++--- mozilla-aurora/rebase/contextdecorator.py.rebase-dir	2014-07-28 18:25:25.000000000 +0200
+++++ mozilla-aurora/rebase/contextdecorator.py	2014-07-28 18:25:25.000000000 +0200
++@@ -0,0 +1,185 @@
+++# Copyright (C) 2007-2010 Michael Foord
+++# E-mail: michael AT voidspace DOT org DOT uk
+++# http://pypi.python.org/pypi/contextdecorator
+++'''
+++Create objects that act as both context managers *and* as decorators, and behave
+++the same in both cases.
+++
+++Context managers inheriting from ``ContextDecorator`` have to implement 
+++``__enter__`` and ``__exit__`` as normal. ``__exit__`` retains its optional
+++exception handling even when used as a decorator.
+++
+++Example::
+++
+++   from contextlib import ContextDecorator
+++
+++   class mycontext(ContextDecorator):
+++      def __enter__(self):
+++         print 'Starting'
+++         return self
+++
+++      def __exit__(self, *exc):
+++         print 'Finishing'
+++         return False
+++
+++   @mycontext()
+++   def function():
+++      print 'The bit in the middle'
+++   
+++   with mycontext():
+++      print 'The bit in the middle'
+++
+++Existing context managers that already have a base class can be extended by
+++using ``ContextDecorator`` as a mixin class::
+++
+++   from contextlib import ContextDecorator
+++
+++   class mycontext(ContextBaseClass, ContextDecorator):
+++      def __enter__(self):
+++         return self
+++
+++      def __exit__(self, *exc):
+++         return False
+++
+++'''
+++
+++import sys
+++
+++try:
+++    from functools import wraps
+++except ImportError:
+++    # Python 2.4 compatibility
+++    def wraps(original):
+++        def inner(f):
+++            f.__name__ = original.__name__
+++            return f
+++        return inner
+++
+++# horrible reraise code for compatibility
+++# with Python 2 & 3
+++if sys.version_info >= (3,0):
+++    exec ("""
+++def _reraise(cls, val, tb):
+++    raise val
+++""")
+++else:
+++    exec ("""
+++def _reraise(cls, val, tb):
+++    raise cls, val, tb
+++""")
+++
+++try:
+++    next
+++except NameError:
+++    # Python 2.4 / 2.5
+++    def next(gen):
+++        return gen.next()
+++
+++__all__ = ['__version__', 'ContextDecorator', 'contextmanager']
+++
+++__version__ = '0.10.0'
+++
+++
+++_NO_EXCEPTION = (None, None, None)
+++
+++class ContextDecorator(object):
+++    "A base class or mixin that enables context managers to work as decorators."
+++
+++    def __call__(self, f):
+++        @wraps(f)
+++        def inner(*args, **kw):
+++            self.__enter__()
+++            
+++            exc = _NO_EXCEPTION
+++            try:
+++                result = f(*args, **kw)
+++            except Exception:
+++                exc = sys.exc_info()
+++            
+++            catch = self.__exit__(*exc)
+++            
+++            if not catch and exc is not _NO_EXCEPTION:
+++                _reraise(*exc)
+++            return result
+++        return inner
+++
+++
+++
+++class GeneratorContextManager(ContextDecorator):
+++    """Helper for @contextmanager decorator."""
+++
+++    def __init__(self, gen):
+++        self.gen = gen
+++
+++    def __enter__(self):
+++        try:
+++            return next(self.gen)
+++        except StopIteration:
+++            raise RuntimeError("generator didn't yield")
+++
+++    def __exit__(self, type, value, traceback):
+++        if type is None:
+++            try:
+++                next(self.gen)
+++            except StopIteration:
+++                return
+++            else:
+++                raise RuntimeError("generator didn't stop")
+++        else:
+++            if value is None:
+++                # Need to force instantiation so we can reliably
+++                # tell if we get the same exception back
+++                value = type()
+++            try:
+++                self.gen.throw(type, value, traceback)
+++                raise RuntimeError("generator didn't stop after throw()")
+++            except StopIteration:
+++                # Suppress the exception *unless* it's the same exception that
+++                # was passed to throw().  This prevents a StopIteration
+++                # raised inside the "with" statement from being suppressed
+++                exc = sys.exc_info()[1]
+++                return exc is not value
+++            except:
+++                # only re-raise if it's *not* the exception that was
+++                # passed to throw(), because __exit__() must not raise
+++                # an exception unless __exit__() itself failed.  But throw()
+++                # has to raise the exception to signal propagation, so this
+++                # fixes the impedance mismatch between the throw() protocol
+++                # and the __exit__() protocol.
+++                #
+++                if sys.exc_info()[1] is not value:
+++                    raise
+++
+++
+++def contextmanager(func):
+++    """@contextmanager decorator.
+++
+++    Typical usage:
+++
+++        @contextmanager
+++        def some_generator(<arguments>):
+++            <setup>
+++            try:
+++                yield <value>
+++            finally:
+++                <cleanup>
+++
+++    This makes this:
+++
+++        with some_generator(<arguments>) as <variable>:
+++            <body>
+++
+++    equivalent to this:
+++
+++        <setup>
+++        try:
+++            <variable> = <value>
+++            <body>
+++        finally:
+++            <cleanup>
+++
+++    """
+++    @wraps(func)
+++    def helper(*args, **kwds):
+++        return GeneratorContextManager(func(*args, **kwds))
+++    return helper
++\ No newline at end of file
++diff -up mozilla-aurora/rebase/Counter.py.rebase-dir mozilla-aurora/rebase/Counter.py
++--- mozilla-aurora/rebase/Counter.py.rebase-dir	2014-07-28 18:25:25.000000000 +0200
+++++ mozilla-aurora/rebase/Counter.py	2014-07-28 18:25:25.000000000 +0200
++@@ -0,0 +1,189 @@
+++from operator import itemgetter
+++from heapq import nlargest
+++from itertools import repeat, ifilter
+++
+++class Counter(dict):
+++    '''Dict subclass for counting hashable objects.  Sometimes called a bag
+++    or multiset.  Elements are stored as dictionary keys and their counts
+++    are stored as dictionary values.
+++
+++    >>> Counter('zyzygy')
+++    Counter({'y': 3, 'z': 2, 'g': 1})
+++
+++    '''
+++
+++    def __init__(self, iterable=None, **kwds):
+++        '''Create a new, empty Counter object.  And if given, count elements
+++        from an input iterable.  Or, initialize the count from another mapping
+++        of elements to their counts.
+++
+++        >>> c = Counter()                           # a new, empty counter
+++        >>> c = Counter('gallahad')                 # a new counter from an iterable
+++        >>> c = Counter({'a': 4, 'b': 2})           # a new counter from a mapping
+++        >>> c = Counter(a=4, b=2)                   # a new counter from keyword args
+++
+++        '''        
+++        self.update(iterable, **kwds)
+++
+++    def __missing__(self, key):
+++        return 0
+++
+++    def most_common(self, n=None):
+++        '''List the n most common elements and their counts from the most
+++        common to the least.  If n is None, then list all element counts.
+++
+++        >>> Counter('abracadabra').most_common(3)
+++        [('a', 5), ('r', 2), ('b', 2)]
+++
+++        '''        
+++        if n is None:
+++            return sorted(self.iteritems(), key=itemgetter(1), reverse=True)
+++        return nlargest(n, self.iteritems(), key=itemgetter(1))
+++
+++    def elements(self):
+++        '''Iterator over elements repeating each as many times as its count.
+++
+++        >>> c = Counter('ABCABC')
+++        >>> sorted(c.elements())
+++        ['A', 'A', 'B', 'B', 'C', 'C']
+++
+++        If an element's count has been set to zero or is a negative number,
+++        elements() will ignore it.
+++
+++        '''
+++        for elem, count in self.iteritems():
+++            for _ in repeat(None, count):
+++                yield elem
+++
+++    # Override dict methods where the meaning changes for Counter objects.
+++
+++    @classmethod
+++    def fromkeys(cls, iterable, v=None):
+++        raise NotImplementedError(
+++            'Counter.fromkeys() is undefined.  Use Counter(iterable) instead.')
+++
+++    def update(self, iterable=None, **kwds):
+++        '''Like dict.update() but add counts instead of replacing them.
+++
+++        Source can be an iterable, a dictionary, or another Counter instance.
+++
+++        >>> c = Counter('which')
+++        >>> c.update('witch')           # add elements from another iterable
+++        >>> d = Counter('watch')
+++        >>> c.update(d)                 # add elements from another counter
+++        >>> c['h']                      # four 'h' in which, witch, and watch
+++        4
+++
+++        '''        
+++        if iterable is not None:
+++            if hasattr(iterable, 'iteritems'):
+++                if self:
+++                    self_get = self.get
+++                    for elem, count in iterable.iteritems():
+++                        self[elem] = self_get(elem, 0) + count
+++                else:
+++                    dict.update(self, iterable) # fast path when counter is empty
+++            else:
+++                self_get = self.get
+++                for elem in iterable:
+++                    self[elem] = self_get(elem, 0) + 1
+++        if kwds:
+++            self.update(kwds)
+++
+++    def copy(self):
+++        'Like dict.copy() but returns a Counter instance instead of a dict.'
+++        return Counter(self)
+++
+++    def __delitem__(self, elem):
+++        'Like dict.__delitem__() but does not raise KeyError for missing values.'
+++        if elem in self:
+++            dict.__delitem__(self, elem)
+++
+++    def __repr__(self):
+++        if not self:
+++            return '%s()' % self.__class__.__name__
+++        items = ', '.join(map('%r: %r'.__mod__, self.most_common()))
+++        return '%s({%s})' % (self.__class__.__name__, items)
+++
+++    # Multiset-style mathematical operations discussed in:
+++    #       Knuth TAOCP Volume II section 4.6.3 exercise 19
+++    #       and at http://en.wikipedia.org/wiki/Multiset
+++    #
+++    # Outputs guaranteed to only include positive counts.
+++    #
+++    # To strip negative and zero counts, add-in an empty counter:
+++    #       c += Counter()
+++
+++    def __add__(self, other):
+++        '''Add counts from two counters.
+++
+++        >>> Counter('abbb') + Counter('bcc')
+++        Counter({'b': 4, 'c': 2, 'a': 1})
+++
+++
+++        '''
+++        if not isinstance(other, Counter):
+++            return NotImplemented
+++        result = Counter()
+++        for elem in set(self) | set(other):
+++            newcount = self[elem] + other[elem]
+++            if newcount > 0:
+++                result[elem] = newcount
+++        return result
+++
+++    def __sub__(self, other):
+++        ''' Subtract count, but keep only results with positive counts.
+++
+++        >>> Counter('abbbc') - Counter('bccd')
+++        Counter({'b': 2, 'a': 1})
+++
+++        '''
+++        if not isinstance(other, Counter):
+++            return NotImplemented
+++        result = Counter()
+++        for elem in set(self) | set(other):
+++            newcount = self[elem] - other[elem]
+++            if newcount > 0:
+++                result[elem] = newcount
+++        return result
+++
+++    def __or__(self, other):
+++        '''Union is the maximum of value in either of the input counters.
+++
+++        >>> Counter('abbb') | Counter('bcc')
+++        Counter({'b': 3, 'c': 2, 'a': 1})
+++
+++        '''
+++        if not isinstance(other, Counter):
+++            return NotImplemented
+++        _max = max
+++        result = Counter()
+++        for elem in set(self) | set(other):
+++            newcount = _max(self[elem], other[elem])
+++            if newcount > 0:
+++                result[elem] = newcount
+++        return result
+++
+++    def __and__(self, other):
+++        ''' Intersection is the minimum of corresponding counts.
+++
+++        >>> Counter('abbb') & Counter('bcc')
+++        Counter({'b': 1})
+++
+++        '''
+++        if not isinstance(other, Counter):
+++            return NotImplemented
+++        _min = min
+++        result = Counter()
+++        if len(self) < len(other):
+++            self, other = other, self
+++        for elem in ifilter(self.__contains__, other):
+++            newcount = _min(self[elem], other[elem])
+++            if newcount > 0:
+++                result[elem] = newcount
+++        return result
+++
+++
+++if __name__ == '__main__':
+++    import doctest
+++    print doctest.testmod()
++diff -up mozilla-aurora/rebase/mycollections.py.rebase-dir mozilla-aurora/rebase/mycollections.py
++--- mozilla-aurora/rebase/mycollections.py.rebase-dir	2014-07-28 18:25:25.000000000 +0200
+++++ mozilla-aurora/rebase/mycollections.py	2014-07-28 18:25:25.000000000 +0200
++@@ -0,0 +1,38 @@
+++from ordereddict import OrderedDict
+++from namedtuple import namedtuple
+++
+++class defaultdict(dict):
+++    def __init__(self, default_factory=None, *a, **kw):
+++        if (default_factory is not None and
+++            not hasattr(default_factory, '__call__')):
+++            raise TypeError('first argument must be callable')
+++        dict.__init__(self, *a, **kw)
+++        self.default_factory = default_factory
+++    def __getitem__(self, key):
+++        try:
+++            return dict.__getitem__(self, key)
+++        except KeyError:
+++            return self.__missing__(key)
+++    def __missing__(self, key):
+++        if self.default_factory is None:
+++            raise KeyError(key)
+++        self[key] = value = self.default_factory()
+++        return value
+++    def __reduce__(self):
+++        if self.default_factory is None:
+++            args = tuple()
+++        else:
+++            args = self.default_factory,
+++        return type(self), args, None, None, self.items()
+++    def copy(self):
+++        return self.__copy__()
+++    def __copy__(self):
+++        return type(self)(self.default_factory, self)
+++    def __deepcopy__(self, memo):
+++        import copy
+++        return type(self)(self.default_factory,
+++                          copy.deepcopy(self.items()))
+++    def __repr__(self):
+++        return 'defaultdict(%s, %s)' % (self.default_factory,
+++                                        dict.__repr__(self))
+++
++diff -up mozilla-aurora/rebase/mypickle.py.rebase-dir mozilla-aurora/rebase/mypickle.py
++--- mozilla-aurora/rebase/mypickle.py.rebase-dir	2014-07-28 18:25:25.000000000 +0200
+++++ mozilla-aurora/rebase/mypickle.py	2014-07-28 18:25:25.000000000 +0200
++@@ -0,0 +1,1403 @@
+++"""Create portable serialized representations of Python objects.
+++
+++See module cPickle for a (much) faster implementation.
+++See module copy_reg for a mechanism for registering custom picklers.
+++See module pickletools source for extensive comments.
+++
+++Classes:
+++
+++    Pickler
+++    Unpickler
+++
+++Functions:
+++
+++    dump(object, file)
+++    dumps(object) -> string
+++    load(file) -> object
+++    loads(string) -> object
+++
+++Misc variables:
+++
+++    __version__
+++    format_version
+++    compatible_formats
+++
+++"""
+++
+++__version__ = "$Revision: 72223 $"       # Code version
+++
+++from types import *
+++from copy_reg import dispatch_table
+++from copy_reg import _extension_registry, _inverted_registry, _extension_cache
+++import marshal
+++import sys
+++import struct
+++import re
+++
+++__all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler",
+++           "Unpickler", "dump", "dumps", "load", "loads"]
+++
+++# These are purely informational; no code uses these.
+++format_version = "2.0"                  # File format version we write
+++compatible_formats = ["1.0",            # Original protocol 0
+++                      "1.1",            # Protocol 0 with INST added
+++                      "1.2",            # Original protocol 1
+++                      "1.3",            # Protocol 1 with BINFLOAT added
+++                      "2.0",            # Protocol 2
+++                      ]                 # Old format versions we can read
+++
+++# Keep in synch with cPickle.  This is the highest protocol number we
+++# know how to read.
+++HIGHEST_PROTOCOL = 2
+++
+++# Why use struct.pack() for pickling but marshal.loads() for
+++# unpickling?  struct.pack() is 40% faster than marshal.dumps(), but
+++# marshal.loads() is twice as fast as struct.unpack()!
+++mloads = marshal.loads
+++
+++class PickleError(Exception):
+++    """A common base class for the other pickling exceptions."""
+++    pass
+++
+++class PicklingError(PickleError):
+++    """This exception is raised when an unpicklable object is passed to the
+++    dump() method.
+++
+++    """
+++    pass
+++
+++class UnpicklingError(PickleError):
+++    """This exception is raised when there is a problem unpickling an object,
+++    such as a security violation.
+++
+++    Note that other exceptions may also be raised during unpickling, including
+++    (but not necessarily limited to) AttributeError, EOFError, ImportError,
+++    and IndexError.
+++
+++    """
+++    pass
+++
+++# An instance of _Stop is raised by Unpickler.load_stop() in response to
+++# the STOP opcode, passing the object that is the result of unpickling.
+++class _Stop(Exception):
+++    def __init__(self, value):
+++        self.value = value
+++
+++# Jython has PyStringMap; it's a dict subclass with string keys
+++try:
+++    from org.python.core import PyStringMap
+++except ImportError:
+++    PyStringMap = None
+++
+++# UnicodeType may or may not be exported (normally imported from types)
+++try:
+++    UnicodeType
+++except NameError:
+++    UnicodeType = None
+++
+++# Pickle opcodes.  See pickletools.py for extensive docs.  The listing
+++# here is in kind-of alphabetical order of 1-character pickle code.
+++# pickletools groups them by purpose.
+++
+++MARK            = '('   # push special markobject on stack
+++STOP            = '.'   # every pickle ends with STOP
+++POP             = '0'   # discard topmost stack item
+++POP_MARK        = '1'   # discard stack top through topmost markobject
+++DUP             = '2'   # duplicate top stack item
+++FLOAT           = 'F'   # push float object; decimal string argument
+++INT             = 'I'   # push integer or bool; decimal string argument
+++BININT          = 'J'   # push four-byte signed int
+++BININT1         = 'K'   # push 1-byte unsigned int
+++LONG            = 'L'   # push long; decimal string argument
+++BININT2         = 'M'   # push 2-byte unsigned int
+++NONE            = 'N'   # push None
+++PERSID          = 'P'   # push persistent object; id is taken from string arg
+++BINPERSID       = 'Q'   #  "       "         "  ;  "  "   "     "  stack
+++REDUCE          = 'R'   # apply callable to argtuple, both on stack
+++STRING          = 'S'   # push string; NL-terminated string argument
+++BINSTRING       = 'T'   # push string; counted binary string argument
+++SHORT_BINSTRING = 'U'   #  "     "   ;    "      "       "      " < 256 bytes
+++UNICODE         = 'V'   # push Unicode string; raw-unicode-escaped'd argument
+++BINUNICODE      = 'X'   #   "     "       "  ; counted UTF-8 string argument
+++APPEND          = 'a'   # append stack top to list below it
+++BUILD           = 'b'   # call __setstate__ or __dict__.update()
+++GLOBAL          = 'c'   # push self.find_class(modname, name); 2 string args
+++DICT            = 'd'   # build a dict from stack items
+++EMPTY_DICT      = '}'   # push empty dict
+++APPENDS         = 'e'   # extend list on stack by topmost stack slice
+++GET             = 'g'   # push item from memo on stack; index is string arg
+++BINGET          = 'h'   #   "    "    "    "   "   "  ;   "    " 1-byte arg
+++INST            = 'i'   # build & push class instance
+++LONG_BINGET     = 'j'   # push item from memo on stack; index is 4-byte arg
+++LIST            = 'l'   # build list from topmost stack items
+++EMPTY_LIST      = ']'   # push empty list
+++OBJ             = 'o'   # build & push class instance
+++PUT             = 'p'   # store stack top in memo; index is string arg
+++BINPUT          = 'q'   #   "     "    "   "   " ;   "    " 1-byte arg
+++LONG_BINPUT     = 'r'   #   "     "    "   "   " ;   "    " 4-byte arg
+++SETITEM         = 's'   # add key+value pair to dict
+++TUPLE           = 't'   # build tuple from topmost stack items
+++EMPTY_TUPLE     = ')'   # push empty tuple
+++SETITEMS        = 'u'   # modify dict by adding topmost key+value pairs
+++BINFLOAT        = 'G'   # push float; arg is 8-byte float encoding
+++
+++TRUE            = 'I01\n'  # not an opcode; see INT docs in pickletools.py
+++FALSE           = 'I00\n'  # not an opcode; see INT docs in pickletools.py
+++
+++# Protocol 2
+++
+++PROTO           = '\x80'  # identify pickle protocol
+++NEWOBJ          = '\x81'  # build object by applying cls.__new__ to argtuple
+++EXT1            = '\x82'  # push object from extension registry; 1-byte index
+++EXT2            = '\x83'  # ditto, but 2-byte index
+++EXT4            = '\x84'  # ditto, but 4-byte index
+++TUPLE1          = '\x85'  # build 1-tuple from stack top
+++TUPLE2          = '\x86'  # build 2-tuple from two topmost stack items
+++TUPLE3          = '\x87'  # build 3-tuple from three topmost stack items
+++NEWTRUE         = '\x88'  # push True
+++NEWFALSE        = '\x89'  # push False
+++LONG1           = '\x8a'  # push long from < 256 bytes
+++LONG4           = '\x8b'  # push really big long
+++
+++_tuplesize2code = [EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3]
+++
+++
+++__all__.extend([x for x in dir() if re.match("[A-Z][A-Z0-9_]+$",x)])
+++del x
+++
+++
+++# Pickling machinery
+++
+++class Pickler:
+++
+++    def __init__(self, file, protocol=None):
+++        """This takes a file-like object for writing a pickle data stream.
+++
+++        The optional protocol argument tells the pickler to use the
+++        given protocol; supported protocols are 0, 1, 2.  The default
+++        protocol is 0, to be backwards compatible.  (Protocol 0 is the
+++        only protocol that can be written to a file opened in text
+++        mode and read back successfully.  When using a protocol higher
+++        than 0, make sure the file is opened in binary mode, both when
+++        pickling and unpickling.)
+++
+++        Protocol 1 is more efficient than protocol 0; protocol 2 is
+++        more efficient than protocol 1.
+++
+++        Specifying a negative protocol version selects the highest
+++        protocol version supported.  The higher the protocol used, the
+++        more recent the version of Python needed to read the pickle
+++        produced.
+++
+++        The file parameter must have a write() method that accepts a single
+++        string argument.  It can thus be an open file object, a StringIO
+++        object, or any other custom object that meets this interface.
+++
+++        """
+++        if protocol is None:
+++            protocol = 0
+++        if protocol < 0:
+++            protocol = HIGHEST_PROTOCOL
+++        elif not 0 <= protocol <= HIGHEST_PROTOCOL:
+++            raise ValueError("pickle protocol must be <= %d" % HIGHEST_PROTOCOL)
+++        self.write = file.write
+++        self.memo = {}
+++        self.proto = int(protocol)
+++        self.bin = protocol >= 1
+++        self.fast = 0
+++
+++    def clear_memo(self):
+++        """Clears the pickler's "memo".
+++
+++        The memo is the data structure that remembers which objects the
+++        pickler has already seen, so that shared or recursive objects are
+++        pickled by reference and not by value.  This method is useful when
+++        re-using picklers.
+++
+++        """
+++        self.memo.clear()
+++
+++    def dump(self, obj):
+++        """Write a pickled representation of obj to the open file."""
+++        if self.proto >= 2:
+++            self.write(PROTO + chr(self.proto))
+++        self.save(obj)
+++        self.write(STOP)
+++
+++    def memoize(self, obj):
+++        """Store an object in the memo."""
+++
+++        # The Pickler memo is a dictionary mapping object ids to 2-tuples
+++        # that contain the Unpickler memo key and the object being memoized.
+++        # The memo key is written to the pickle and will become
+++        # the key in the Unpickler's memo.  The object is stored in the
+++        # Pickler memo so that transient objects are kept alive during
+++        # pickling.
+++
+++        # The use of the Unpickler memo length as the memo key is just a
+++        # convention.  The only requirement is that the memo values be unique.
+++        # But there appears no advantage to any other scheme, and this
+++        # scheme allows the Unpickler memo to be implemented as a plain (but
+++        # growable) array, indexed by memo key.
+++        if self.fast:
+++            return
+++        assert id(obj) not in self.memo
+++        memo_len = len(self.memo)
+++        self.write(self.put(memo_len))
+++        self.memo[id(obj)] = memo_len, obj
+++
+++    # Return a PUT (BINPUT, LONG_BINPUT) opcode string, with argument i.
+++    def put(self, i, pack=struct.pack):
+++        if self.bin:
+++            if i < 256:
+++                return BINPUT + chr(i)
+++            else:
+++                return LONG_BINPUT + pack("<i", i)
+++
+++        return PUT + repr(i) + '\n'
+++
+++    # Return a GET (BINGET, LONG_BINGET) opcode string, with argument i.
+++    def get(self, i, pack=struct.pack):
+++        if self.bin:
+++            if i < 256:
+++                return BINGET + chr(i)
+++            else:
+++                return LONG_BINGET + pack("<i", i)
+++
+++        return GET + repr(i) + '\n'
+++
+++    def save(self, obj):
+++        # Check for persistent id (defined by a subclass)
+++        pid = self.persistent_id(obj)
+++        if pid:
+++            self.save_pers(pid)
+++            return
+++
+++        # Check the memo
+++        x = self.memo.get(id(obj))
+++        if x:
+++            self.write(self.get(x[0]))
+++            return
+++
+++        # Check the type dispatch table
+++        t = type(obj)
+++        f = self.dispatch.get(t)
+++        if f:
+++            f(self, obj) # Call unbound method with explicit self
+++            return
+++
+++        # Check copy_reg.dispatch_table
+++        reduce = dispatch_table.get(t)
+++        if reduce:
+++            rv = reduce(obj)
+++        else:
+++            # Check for a class with a custom metaclass; treat as regular class
+++            try:
+++                issc = issubclass(t, TypeType)
+++            except TypeError: # t is not a class (old Boost; see SF #502085)
+++                issc = 0
+++            if issc:
+++                self.save_global(obj)
+++                return
+++
+++            # Check for a __reduce_ex__ method, fall back to __reduce__
+++            reduce = getattr(obj, "__reduce_ex__", None)
+++            if reduce:
+++                rv = reduce(self.proto)
+++            else:
+++                reduce = getattr(obj, "__reduce__", None)
+++                if reduce:
+++                    rv = reduce()
+++                else:
+++                    raise PicklingError("Can't pickle %r object: %r" %
+++                                        (t.__name__, obj))
+++
+++        # Check for string returned by reduce(), meaning "save as global"
+++        if type(rv) is StringType:
+++            self.save_global(obj, rv)
+++            return
+++
+++        # Assert that reduce() returned a tuple
+++        if type(rv) is not TupleType:
+++            raise PicklingError("%s must return string or tuple" % reduce)
+++
+++        # Assert that it returned an appropriately sized tuple
+++        l = len(rv)
+++        if not (2 <= l <= 5):
+++            raise PicklingError("Tuple returned by %s must have "
+++                                "two to five elements" % reduce)
+++
+++        # Save the reduce() output and finally memoize the object
+++        self.save_reduce(obj=obj, *rv)
+++
+++    def persistent_id(self, obj):
+++        # This exists so a subclass can override it
+++        return None
+++
+++    def save_pers(self, pid):
+++        # Save a persistent id reference
+++        if self.bin:
+++            self.save(pid)
+++            self.write(BINPERSID)
+++        else:
+++            self.write(PERSID + str(pid) + '\n')
+++
+++    def save_reduce(self, func, args, state=None,
+++                    listitems=None, dictitems=None, obj=None):
+++        # This API is called by some subclasses
+++
+++        # Assert that args is a tuple or None
+++        if not isinstance(args, TupleType):
+++            raise PicklingError("args from reduce() should be a tuple")
+++
+++        # Assert that func is callable
+++        if not hasattr(func, '__call__'):
+++            raise PicklingError("func from reduce should be callable")
+++
+++        save = self.save
+++        write = self.write
+++
+++        # Protocol 2 special case: if func's name is __newobj__, use NEWOBJ
+++        if self.proto >= 2 and getattr(func, "__name__", "") == "__newobj__":
+++            # A __reduce__ implementation can direct protocol 2 to
+++            # use the more efficient NEWOBJ opcode, while still
+++            # allowing protocol 0 and 1 to work normally.  For this to
+++            # work, the function returned by __reduce__ should be
+++            # called __newobj__, and its first argument should be a
+++            # new-style class.  The implementation for __newobj__
+++            # should be as follows, although pickle has no way to
+++            # verify this:
+++            #
+++            # def __newobj__(cls, *args):
+++            #     return cls.__new__(cls, *args)
+++            #
+++            # Protocols 0 and 1 will pickle a reference to __newobj__,
+++            # while protocol 2 (and above) will pickle a reference to
+++            # cls, the remaining args tuple, and the NEWOBJ code,
+++            # which calls cls.__new__(cls, *args) at unpickling time
+++            # (see load_newobj below).  If __reduce__ returns a
+++            # three-tuple, the state from the third tuple item will be
+++            # pickled regardless of the protocol, calling __setstate__
+++            # at unpickling time (see load_build below).
+++            #
+++            # Note that no standard __newobj__ implementation exists;
+++            # you have to provide your own.  This is to enforce
+++            # compatibility with Python 2.2 (pickles written using
+++            # protocol 0 or 1 in Python 2.3 should be unpicklable by
+++            # Python 2.2).
+++            cls = args[0]
+++            if not hasattr(cls, "__new__"):
+++                raise PicklingError(
+++                    "args[0] from __newobj__ args has no __new__")
+++            if obj is not None and cls is not obj.__class__:
+++                raise PicklingError(
+++                    "args[0] from __newobj__ args has the wrong class")
+++            args = args[1:]
+++            save(cls)
+++            save(args)
+++            write(NEWOBJ)
+++        else:
+++            save(func)
+++            save(args)
+++            write(REDUCE)
+++
+++        if obj is not None:
+++            self.memoize(obj)
+++
+++        # More new special cases (that work with older protocols as
+++        # well): when __reduce__ returns a tuple with 4 or 5 items,
+++        # the 4th and 5th item should be iterators that provide list
+++        # items and dict items (as (key, value) tuples), or None.
+++
+++        if listitems is not None:
+++            self._batch_appends(listitems)
+++
+++        if dictitems is not None:
+++            self._batch_setitems(dictitems)
+++
+++        if state is not None:
+++            save(state)
+++            write(BUILD)
+++
+++    # Methods below this point are dispatched through the dispatch table
+++
+++    dispatch = {}
+++
+++    def save_none(self, obj):
+++        self.write(NONE)
+++    dispatch[NoneType] = save_none
+++
+++    def save_bool(self, obj):
+++        if self.proto >= 2:
+++            self.write(obj and NEWTRUE or NEWFALSE)
+++        else:
+++            self.write(obj and TRUE or FALSE)
+++    dispatch[bool] = save_bool
+++
+++    def save_int(self, obj, pack=struct.pack):
+++        if self.bin:
+++            # If the int is small enough to fit in a signed 4-byte 2's-comp
+++            # format, we can store it more efficiently than the general
+++            # case.
+++            # First one- and two-byte unsigned ints:
+++            if obj >= 0:
+++                if obj <= 0xff:
+++                    self.write(BININT1 + chr(obj))
+++                    return
+++                if obj <= 0xffff:
+++                    self.write("%c%c%c" % (BININT2, obj&0xff, obj>>8))
+++                    return
+++            # Next check for 4-byte signed ints:
+++            high_bits = obj >> 31  # note that Python shift sign-extends
+++            if high_bits == 0 or high_bits == -1:
+++                # All high bits are copies of bit 2**31, so the value
+++                # fits in a 4-byte signed int.
+++                self.write(BININT + pack("<i", obj))
+++                return
+++        # Text pickle, or int too big to fit in signed 4-byte format.
+++        self.write(INT + repr(obj) + '\n')
+++    dispatch[IntType] = save_int
+++
+++    def save_long(self, obj, pack=struct.pack):
+++        if self.proto >= 2:
+++            bytes = encode_long(obj)
+++            n = len(bytes)
+++            if n < 256:
+++                self.write(LONG1 + chr(n) + bytes)
+++            else:
+++                self.write(LONG4 + pack("<i", n) + bytes)
+++            return
+++        self.write(LONG + repr(obj) + '\n')
+++    dispatch[LongType] = save_long
+++
+++    def save_float(self, obj, pack=struct.pack):
+++        print obj
+++        if obj == float('inf'):
+++          self.write(FLOAT + repr(float('9999999999999.0')) + '\n')
+++        else:
+++          if obj == float('-inf'):
+++            self.write(FLOAT + repr(float('-9999999999999.0')) + '\n')
+++          else:
+++            if self.bin:
+++                self.write(BINFLOAT + pack('>d', obj))
+++            else:
+++                self.write(FLOAT + repr(obj) + '\n')
+++    dispatch[FloatType] = save_float
+++
+++    def save_string(self, obj, pack=struct.pack):
+++        if self.bin:
+++            n = len(obj)
+++            if n < 256:
+++                self.write(SHORT_BINSTRING + chr(n) + obj)
+++            else:
+++                self.write(BINSTRING + pack("<i", n) + obj)
+++        else:
+++            self.write(STRING + repr(obj) + '\n')
+++        self.memoize(obj)
+++    dispatch[StringType] = save_string
+++
+++    def save_unicode(self, obj, pack=struct.pack):
+++        if self.bin:
+++            encoding = obj.encode('utf-8')
+++            n = len(encoding)
+++            self.write(BINUNICODE + pack("<i", n) + encoding)
+++        else:
+++            obj = obj.replace("\\", "\\u005c")
+++            obj = obj.replace("\n", "\\u000a")
+++            self.write(UNICODE + obj.encode('raw-unicode-escape') + '\n')
+++        self.memoize(obj)
+++    dispatch[UnicodeType] = save_unicode
+++
+++    if StringType is UnicodeType:
+++        # This is true for Jython
+++        def save_string(self, obj, pack=struct.pack):
+++            unicode = obj.isunicode()
+++
+++            if self.bin:
+++                if unicode:
+++                    obj = obj.encode("utf-8")
+++                l = len(obj)
+++                if l < 256 and not unicode:
+++                    self.write(SHORT_BINSTRING + chr(l) + obj)
+++                else:
+++                    s = pack("<i", l)
+++                    if unicode:
+++                        self.write(BINUNICODE + s + obj)
+++                    else:
+++                        self.write(BINSTRING + s + obj)
+++            else:
+++                if unicode:
+++                    obj = obj.replace("\\", "\\u005c")
+++                    obj = obj.replace("\n", "\\u000a")
+++                    obj = obj.encode('raw-unicode-escape')
+++                    self.write(UNICODE + obj + '\n')
+++                else:
+++                    self.write(STRING + repr(obj) + '\n')
+++            self.memoize(obj)
+++        dispatch[StringType] = save_string
+++
+++    def save_tuple(self, obj):
+++        write = self.write
+++        proto = self.proto
+++
+++        n = len(obj)
+++        if n == 0:
+++            if proto:
+++                write(EMPTY_TUPLE)
+++            else:
+++                write(MARK + TUPLE)
+++            return
+++
+++        save = self.save
+++        memo = self.memo
+++        if n <= 3 and proto >= 2:
+++            for element in obj:
+++                save(element)
+++            # Subtle.  Same as in the big comment below.
+++            if id(obj) in memo:
+++                get = self.get(memo[id(obj)][0])
+++                write(POP * n + get)
+++            else:
+++                write(_tuplesize2code[n])
+++                self.memoize(obj)
+++            return
+++
+++        # proto 0 or proto 1 and tuple isn't empty, or proto > 1 and tuple
+++        # has more than 3 elements.
+++        write(MARK)
+++        for element in obj:
+++            save(element)
+++
+++        if id(obj) in memo:
+++            # Subtle.  d was not in memo when we entered save_tuple(), so
+++            # the process of saving the tuple's elements must have saved
+++            # the tuple itself:  the tuple is recursive.  The proper action
+++            # now is to throw away everything we put on the stack, and
+++            # simply GET the tuple (it's already constructed).  This check
+++            # could have been done in the "for element" loop instead, but
+++            # recursive tuples are a rare thing.
+++            get = self.get(memo[id(obj)][0])
+++            if proto:
+++                write(POP_MARK + get)
+++            else:   # proto 0 -- POP_MARK not available
+++                write(POP * (n+1) + get)
+++            return
+++
+++        # No recursion.
+++        self.write(TUPLE)
+++        self.memoize(obj)
+++
+++    dispatch[TupleType] = save_tuple
+++
+++    # save_empty_tuple() isn't used by anything in Python 2.3.  However, I
+++    # found a Pickler subclass in Zope3 that calls it, so it's not harmless
+++    # to remove it.
+++    def save_empty_tuple(self, obj):
+++        self.write(EMPTY_TUPLE)
+++
+++    def save_list(self, obj):
+++        write = self.write
+++
+++        if self.bin:
+++            write(EMPTY_LIST)
+++        else:   # proto 0 -- can't use EMPTY_LIST
+++            write(MARK + LIST)
+++
+++        self.memoize(obj)
+++        self._batch_appends(iter(obj))
+++
+++    dispatch[ListType] = save_list
+++
+++    # Keep in synch with cPickle's BATCHSIZE.  Nothing will break if it gets
+++    # out of synch, though.
+++    _BATCHSIZE = 1000
+++
+++    def _batch_appends(self, items):
+++        # Helper to batch up APPENDS sequences
+++        save = self.save
+++        write = self.write
+++
+++        if not self.bin:
+++            for x in items:
+++                save(x)
+++                write(APPEND)
+++            return
+++
+++        r = xrange(self._BATCHSIZE)
+++        while items is not None:
+++            tmp = []
+++            for i in r:
+++                try:
+++                    x = items.next()
+++                    tmp.append(x)
+++                except StopIteration:
+++                    items = None
+++                    break
+++            n = len(tmp)
+++            if n > 1:
+++                write(MARK)
+++                for x in tmp:
+++                    save(x)
+++                write(APPENDS)
+++            elif n:
+++                save(tmp[0])
+++                write(APPEND)
+++            # else tmp is empty, and we're done
+++
+++    def save_dict(self, obj):
+++        write = self.write
+++
+++        if self.bin:
+++            write(EMPTY_DICT)
+++        else:   # proto 0 -- can't use EMPTY_DICT
+++            write(MARK + DICT)
+++
+++        self.memoize(obj)
+++        self._batch_setitems(obj.iteritems())
+++
+++    dispatch[DictionaryType] = save_dict
+++    if not PyStringMap is None:
+++        dispatch[PyStringMap] = save_dict
+++
+++    def _batch_setitems(self, items):
+++        # Helper to batch up SETITEMS sequences; proto >= 1 only
+++        save = self.save
+++        write = self.write
+++
+++        if not self.bin:
+++            for k, v in items:
+++                save(k)
+++                save(v)
+++                write(SETITEM)
+++            return
+++
+++        r = xrange(self._BATCHSIZE)
+++        while items is not None:
+++            tmp = []
+++            for i in r:
+++                try:
+++                    tmp.append(items.next())
+++                except StopIteration:
+++                    items = None
+++                    break
+++            n = len(tmp)
+++            if n > 1:
+++                write(MARK)
+++                for k, v in tmp:
+++                    save(k)
+++                    save(v)
+++                write(SETITEMS)
+++            elif n:
+++                k, v = tmp[0]
+++                save(k)
+++                save(v)
+++                write(SETITEM)
+++            # else tmp is empty, and we're done
+++
+++    def save_inst(self, obj):
+++        cls = obj.__class__
+++
+++        memo  = self.memo
+++        write = self.write
+++        save  = self.save
+++
+++        if hasattr(obj, '__getinitargs__'):
+++            args = obj.__getinitargs__()
+++            len(args) # XXX Assert it's a sequence
+++            _keep_alive(args, memo)
+++        else:
+++            args = ()
+++
+++        write(MARK)
+++
+++        if self.bin:
+++            save(cls)
+++            for arg in args:
+++                save(arg)
+++            write(OBJ)
+++        else:
+++            for arg in args:
+++                save(arg)
+++            write(INST + cls.__module__ + '\n' + cls.__name__ + '\n')
+++
+++        self.memoize(obj)
+++
+++        try:
+++            getstate = obj.__getstate__
+++        except AttributeError:
+++            stuff = obj.__dict__
+++        else:
+++            stuff = getstate()
+++            _keep_alive(stuff, memo)
+++        save(stuff)
+++        write(BUILD)
+++
+++    dispatch[InstanceType] = save_inst
+++
+++    def save_global(self, obj, name=None, pack=struct.pack):
+++        write = self.write
+++        memo = self.memo
+++
+++        if name is None:
+++            name = obj.__name__
+++
+++        module = getattr(obj, "__module__", None)
+++        if module is None:
+++            module = whichmodule(obj, name)
+++
+++        try:
+++            __import__(module)
+++            mod = sys.modules[module]
+++            klass = getattr(mod, name)
+++        except (ImportError, KeyError, AttributeError):
+++            raise PicklingError(
+++                "Can't pickle %r: it's not found as %s.%s" %
+++                (obj, module, name))
+++        else:
+++            if klass is not obj:
+++                raise PicklingError(
+++                    "Can't pickle %r: it's not the same object as %s.%s" %
+++                    (obj, module, name))
+++
+++        if self.proto >= 2:
+++            code = _extension_registry.get((module, name))
+++            if code:
+++                assert code > 0
+++                if code <= 0xff:
+++                    write(EXT1 + chr(code))
+++                elif code <= 0xffff:
+++                    write("%c%c%c" % (EXT2, code&0xff, code>>8))
+++                else:
+++                    write(EXT4 + pack("<i", code))
+++                return
+++
+++        write(GLOBAL + module + '\n' + name + '\n')
+++        self.memoize(obj)
+++
+++    dispatch[ClassType] = save_global
+++    dispatch[FunctionType] = save_global
+++    dispatch[BuiltinFunctionType] = save_global
+++    dispatch[TypeType] = save_global
+++
+++# Pickling helpers
+++
+++def _keep_alive(x, memo):
+++    """Keeps a reference to the object x in the memo.
+++
+++    Because we remember objects by their id, we have
+++    to assure that possibly temporary objects are kept
+++    alive by referencing them.
+++    We store a reference at the id of the memo, which should
+++    normally not be used unless someone tries to deepcopy
+++    the memo itself...
+++    """
+++    try:
+++        memo[id(memo)].append(x)
+++    except KeyError:
+++        # aha, this is the first one :-)
+++        memo[id(memo)]=[x]
+++
+++
+++# A cache for whichmodule(), mapping a function object to the name of
+++# the module in which the function was found.
+++
+++classmap = {} # called classmap for backwards compatibility
+++
+++def whichmodule(func, funcname):
+++    """Figure out the module in which a function occurs.
+++
+++    Search sys.modules for the module.
+++    Cache in classmap.
+++    Return a module name.
+++    If the function cannot be found, return "__main__".
+++    """
+++    # Python functions should always get an __module__ from their globals.
+++    mod = getattr(func, "__module__", None)
+++    if mod is not None:
+++        return mod
+++    if func in classmap:
+++        return classmap[func]
+++
+++    for name, module in sys.modules.items():
+++        if module is None:
+++            continue # skip dummy package entries
+++        if name != '__main__' and getattr(module, funcname, None) is func:
+++            break
+++    else:
+++        name = '__main__'
+++    classmap[func] = name
+++    return name
+++
+++
+++# Unpickling machinery
+++
+++class Unpickler:
+++
+++    def __init__(self, file):
+++        """This takes a file-like object for reading a pickle data stream.
+++
+++        The protocol version of the pickle is detected automatically, so no
+++        proto argument is needed.
+++
+++        The file-like object must have two methods, a read() method that
+++        takes an integer argument, and a readline() method that requires no
+++        arguments.  Both methods should return a string.  Thus file-like
+++        object can be a file object opened for reading, a StringIO object,
+++        or any other custom object that meets this interface.
+++        """
+++        self.readline = file.readline
+++        self.read = file.read
+++        self.memo = {}
+++
+++    def load(self):
+++        """Read a pickled object representation from the open file.
+++
+++        Return the reconstituted object hierarchy specified in the file.
+++        """
+++        self.mark = object() # any new unique object
+++        self.stack = []
+++        self.append = self.stack.append
+++        read = self.read
+++        dispatch = self.dispatch
+++        try:
+++            while 1:
+++                key = read(1)
+++                dispatch[key](self)
+++        except _Stop, stopinst:
+++            return stopinst.value
+++
+++    # Return largest index k such that self.stack[k] is self.mark.
+++    # If the stack doesn't contain a mark, eventually raises IndexError.
+++    # This could be sped by maintaining another stack, of indices at which
+++    # the mark appears.  For that matter, the latter stack would suffice,
+++    # and we wouldn't need to push mark objects on self.stack at all.
+++    # Doing so is probably a good thing, though, since if the pickle is
+++    # corrupt (or hostile) we may get a clue from finding self.mark embedded
+++    # in unpickled objects.
+++    def marker(self):
+++        stack = self.stack
+++        mark = self.mark
+++        k = len(stack)-1
+++        while stack[k] is not mark: k = k-1
+++        return k
+++
+++    dispatch = {}
+++
+++    def load_eof(self):
+++        raise EOFError
+++    dispatch[''] = load_eof
+++
+++    def load_proto(self):
+++        proto = ord(self.read(1))
+++        if not 0 <= proto <= 2:
+++            raise ValueError, "unsupported pickle protocol: %d" % proto
+++    dispatch[PROTO] = load_proto
+++
+++    def load_persid(self):
+++        pid = self.readline()[:-1]
+++        self.append(self.persistent_load(pid))
+++    dispatch[PERSID] = load_persid
+++
+++    def load_binpersid(self):
+++        pid = self.stack.pop()
+++        self.append(self.persistent_load(pid))
+++    dispatch[BINPERSID] = load_binpersid
+++
+++    def load_none(self):
+++        self.append(None)
+++    dispatch[NONE] = load_none
+++
+++    def load_false(self):
+++        self.append(False)
+++    dispatch[NEWFALSE] = load_false
+++
+++    def load_true(self):
+++        self.append(True)
+++    dispatch[NEWTRUE] = load_true
+++
+++    def load_int(self):
+++        data = self.readline()
+++        if data == FALSE[1:]:
+++            val = False
+++        elif data == TRUE[1:]:
+++            val = True
+++        else:
+++            try:
+++                val = int(data)
+++            except ValueError:
+++                val = long(data)
+++        self.append(val)
+++    dispatch[INT] = load_int
+++
+++    def load_binint(self):
+++        self.append(mloads('i' + self.read(4)))
+++    dispatch[BININT] = load_binint
+++
+++    def load_binint1(self):
+++        self.append(ord(self.read(1)))
+++    dispatch[BININT1] = load_binint1
+++
+++    def load_binint2(self):
+++        self.append(mloads('i' + self.read(2) + '\000\000'))
+++    dispatch[BININT2] = load_binint2
+++
+++    def load_long(self):
+++        self.append(long(self.readline()[:-1], 0))
+++    dispatch[LONG] = load_long
+++
+++    def load_long1(self):
+++        n = ord(self.read(1))
+++        bytes = self.read(n)
+++        self.append(decode_long(bytes))
+++    dispatch[LONG1] = load_long1
+++
+++    def load_long4(self):
+++        n = mloads('i' + self.read(4))
+++        bytes = self.read(n)
+++        self.append(decode_long(bytes))
+++    dispatch[LONG4] = load_long4
+++
+++    def load_float(self):
+++        num = float(self.readline()[:-1])
+++        if num == 9999999999999.0: # very cheap trick
+++          num = float('inf')
+++        if num == -9999999999999.0: # very cheap trick
+++          num = float('-inf')
+++        self.append(num)
+++    dispatch[FLOAT] = load_float
+++
+++    def load_binfloat(self, unpack=struct.unpack):
+++        self.append(unpack('>d', self.read(8))[0])
+++    dispatch[BINFLOAT] = load_binfloat
+++
+++    def load_string(self):
+++        rep = self.readline()[:-1]
+++        for q in "\"'": # double or single quote
+++            if rep.startswith(q):
+++                if len(rep) < 2 or not rep.endswith(q):
+++                    raise ValueError, "insecure string pickle"
+++                rep = rep[len(q):-len(q)]
+++                break
+++        else:
+++            raise ValueError, "insecure string pickle"
+++        self.append(rep.decode("string-escape"))
+++    dispatch[STRING] = load_string
+++
+++    def load_binstring(self):
+++        len = mloads('i' + self.read(4))
+++        self.append(self.read(len))
+++    dispatch[BINSTRING] = load_binstring
+++
+++    def load_unicode(self):
+++        self.append(unicode(self.readline()[:-1],'raw-unicode-escape'))
+++    dispatch[UNICODE] = load_unicode
+++
+++    def load_binunicode(self):
+++        len = mloads('i' + self.read(4))
+++        self.append(unicode(self.read(len),'utf-8'))
+++    dispatch[BINUNICODE] = load_binunicode
+++
+++    def load_short_binstring(self):
+++        len = ord(self.read(1))
+++        self.append(self.read(len))
+++    dispatch[SHORT_BINSTRING] = load_short_binstring
+++
+++    def load_tuple(self):
+++        k = self.marker()
+++        self.stack[k:] = [tuple(self.stack[k+1:])]
+++    dispatch[TUPLE] = load_tuple
+++
+++    def load_empty_tuple(self):
+++        self.stack.append(())
+++    dispatch[EMPTY_TUPLE] = load_empty_tuple
+++
+++    def load_tuple1(self):
+++        self.stack[-1] = (self.stack[-1],)
+++    dispatch[TUPLE1] = load_tuple1
+++
+++    def load_tuple2(self):
+++        self.stack[-2:] = [(self.stack[-2], self.stack[-1])]
+++    dispatch[TUPLE2] = load_tuple2
+++
+++    def load_tuple3(self):
+++        self.stack[-3:] = [(self.stack[-3], self.stack[-2], self.stack[-1])]
+++    dispatch[TUPLE3] = load_tuple3
+++
+++    def load_empty_list(self):
+++        self.stack.append([])
+++    dispatch[EMPTY_LIST] = load_empty_list
+++
+++    def load_empty_dictionary(self):
+++        self.stack.append({})
+++    dispatch[EMPTY_DICT] = load_empty_dictionary
+++
+++    def load_list(self):
+++        k = self.marker()
+++        self.stack[k:] = [self.stack[k+1:]]
+++    dispatch[LIST] = load_list
+++
+++    def load_dict(self):
+++        k = self.marker()
+++        d = {}
+++        items = self.stack[k+1:]
+++        for i in range(0, len(items), 2):
+++            key = items[i]
+++            value = items[i+1]
+++            d[key] = value
+++        self.stack[k:] = [d]
+++    dispatch[DICT] = load_dict
+++
+++    # INST and OBJ differ only in how they get a class object.  It's not
+++    # only sensible to do the rest in a common routine, the two routines
+++    # previously diverged and grew different bugs.
+++    # klass is the class to instantiate, and k points to the topmost mark
+++    # object, following which are the arguments for klass.__init__.
+++    def _instantiate(self, klass, k):
+++        args = tuple(self.stack[k+1:])
+++        del self.stack[k:]
+++        instantiated = 0
+++        if (not args and
+++                type(klass) is ClassType and
+++                not hasattr(klass, "__getinitargs__")):
+++            try:
+++                value = _EmptyClass()
+++                value.__class__ = klass
+++                instantiated = 1
+++            except RuntimeError:
+++                # In restricted execution, assignment to inst.__class__ is
+++                # prohibited
+++                pass
+++        if not instantiated:
+++            try:
+++                value = klass(*args)
+++            except TypeError, err:
+++                raise TypeError, "in constructor for %s: %s" % (
+++                    klass.__name__, str(err)), sys.exc_info()[2]
+++        self.append(value)
+++
+++    def load_inst(self):
+++        module = self.readline()[:-1]
+++        name = self.readline()[:-1]
+++        klass = self.find_class(module, name)
+++        self._instantiate(klass, self.marker())
+++    dispatch[INST] = load_inst
+++
+++    def load_obj(self):
+++        # Stack is ... markobject classobject arg1 arg2 ...
+++        k = self.marker()
+++        klass = self.stack.pop(k+1)
+++        self._instantiate(klass, k)
+++    dispatch[OBJ] = load_obj
+++
+++    def load_newobj(self):
+++        args = self.stack.pop()
+++        cls = self.stack[-1]
+++        obj = cls.__new__(cls, *args)
+++        self.stack[-1] = obj
+++    dispatch[NEWOBJ] = load_newobj
+++
+++    def load_global(self):
+++        module = self.readline()[:-1]
+++        name = self.readline()[:-1]
+++        klass = self.find_class(module, name)
+++        self.append(klass)
+++    dispatch[GLOBAL] = load_global
+++
+++    def load_ext1(self):
+++        code = ord(self.read(1))
+++        self.get_extension(code)
+++    dispatch[EXT1] = load_ext1
+++
+++    def load_ext2(self):
+++        code = mloads('i' + self.read(2) + '\000\000')
+++        self.get_extension(code)
+++    dispatch[EXT2] = load_ext2
+++
+++    def load_ext4(self):
+++        code = mloads('i' + self.read(4))
+++        self.get_extension(code)
+++    dispatch[EXT4] = load_ext4
+++
+++    def get_extension(self, code):
+++        nil = []
+++        obj = _extension_cache.get(code, nil)
+++        if obj is not nil:
+++            self.append(obj)
+++            return
+++        key = _inverted_registry.get(code)
+++        if not key:
+++            raise ValueError("unregistered extension code %d" % code)
+++        obj = self.find_class(*key)
+++        _extension_cache[code] = obj
+++        self.append(obj)
+++
+++    def find_class(self, module, name):
+++        # Subclasses may override this
+++        __import__(module)
+++        mod = sys.modules[module]
+++        klass = getattr(mod, name)
+++        return klass
+++
+++    def load_reduce(self):
+++        stack = self.stack
+++        args = stack.pop()
+++        func = stack[-1]
+++        value = func(*args)
+++        stack[-1] = value
+++    dispatch[REDUCE] = load_reduce
+++
+++    def load_pop(self):
+++        del self.stack[-1]
+++    dispatch[POP] = load_pop
+++
+++    def load_pop_mark(self):
+++        k = self.marker()
+++        del self.stack[k:]
+++    dispatch[POP_MARK] = load_pop_mark
+++
+++    def load_dup(self):
+++        self.append(self.stack[-1])
+++    dispatch[DUP] = load_dup
+++
+++    def load_get(self):
+++        self.append(self.memo[self.readline()[:-1]])
+++    dispatch[GET] = load_get
+++
+++    def load_binget(self):
+++        i = ord(self.read(1))
+++        self.append(self.memo[repr(i)])
+++    dispatch[BINGET] = load_binget
+++
+++    def load_long_binget(self):
+++        i = mloads('i' + self.read(4))
+++        self.append(self.memo[repr(i)])
+++    dispatch[LONG_BINGET] = load_long_binget
+++
+++    def load_put(self):
+++        self.memo[self.readline()[:-1]] = self.stack[-1]
+++    dispatch[PUT] = load_put
+++
+++    def load_binput(self):
+++        i = ord(self.read(1))
+++        self.memo[repr(i)] = self.stack[-1]
+++    dispatch[BINPUT] = load_binput
+++
+++    def load_long_binput(self):
+++        i = mloads('i' + self.read(4))
+++        self.memo[repr(i)] = self.stack[-1]
+++    dispatch[LONG_BINPUT] = load_long_binput
+++
+++    def load_append(self):
+++        stack = self.stack
+++        value = stack.pop()
+++        list = stack[-1]
+++        list.append(value)
+++    dispatch[APPEND] = load_append
+++
+++    def load_appends(self):
+++        stack = self.stack
+++        mark = self.marker()
+++        list = stack[mark - 1]
+++        list.extend(stack[mark + 1:])
+++        del stack[mark:]
+++    dispatch[APPENDS] = load_appends
+++
+++    def load_setitem(self):
+++        stack = self.stack
+++        value = stack.pop()
+++        key = stack.pop()
+++        dict = stack[-1]
+++        dict[key] = value
+++    dispatch[SETITEM] = load_setitem
+++
+++    def load_setitems(self):
+++        stack = self.stack
+++        mark = self.marker()
+++        dict = stack[mark - 1]
+++        for i in range(mark + 1, len(stack), 2):
+++            dict[stack[i]] = stack[i + 1]
+++
+++        del stack[mark:]
+++    dispatch[SETITEMS] = load_setitems
+++
+++    def load_build(self):
+++        stack = self.stack
+++        state = stack.pop()
+++        inst = stack[-1]
+++        setstate = getattr(inst, "__setstate__", None)
+++        if setstate:
+++            setstate(state)
+++            return
+++        slotstate = None
+++        if isinstance(state, tuple) and len(state) == 2:
+++            state, slotstate = state
+++        if state:
+++            try:
+++                d = inst.__dict__
+++                try:
+++                    for k, v in state.iteritems():
+++                        d[intern(k)] = v
+++                # keys in state don't have to be strings
+++                # don't blow up, but don't go out of our way
+++                except TypeError:
+++                    d.update(state)
+++
+++            except RuntimeError:
+++                # XXX In restricted execution, the instance's __dict__
+++                # is not accessible.  Use the old way of unpickling
+++                # the instance variables.  This is a semantic
+++                # difference when unpickling in restricted
+++                # vs. unrestricted modes.
+++                # Note, however, that cPickle has never tried to do the
+++                # .update() business, and always uses
+++                #     PyObject_SetItem(inst.__dict__, key, value) in a
+++                # loop over state.items().
+++                for k, v in state.items():
+++                    setattr(inst, k, v)
+++        if slotstate:
+++            for k, v in slotstate.items():
+++                setattr(inst, k, v)
+++    dispatch[BUILD] = load_build
+++
+++    def load_mark(self):
+++        self.append(self.mark)
+++    dispatch[MARK] = load_mark
+++
+++    def load_stop(self):
+++        value = self.stack.pop()
+++        raise _Stop(value)
+++    dispatch[STOP] = load_stop
+++
+++# Helper class for load_inst/load_obj
+++
+++class _EmptyClass:
+++    pass
+++
+++# Encode/decode longs in linear time.
+++
+++import binascii as _binascii
+++
+++def encode_long(x):
+++    r"""Encode a long to a two's complement little-endian binary string.
+++    Note that 0L is a special case, returning an empty string, to save a
+++    byte in the LONG1 pickling context.
+++
+++    >>> encode_long(0L)
+++    ''
+++    >>> encode_long(255L)
+++    '\xff\x00'
+++    >>> encode_long(32767L)
+++    '\xff\x7f'
+++    >>> encode_long(-256L)
+++    '\x00\xff'
+++    >>> encode_long(-32768L)
+++    '\x00\x80'
+++    >>> encode_long(-128L)
+++    '\x80'
+++    >>> encode_long(127L)
+++    '\x7f'
+++    >>>
+++    """
+++
+++    if x == 0:
+++        return ''
+++    if x > 0:
+++        ashex = hex(x)
+++        assert ashex.startswith("0x")
+++        njunkchars = 2 + ashex.endswith('L')
+++        nibbles = len(ashex) - njunkchars
+++        if nibbles & 1:
+++            # need an even # of nibbles for unhexlify
+++            ashex = "0x0" + ashex[2:]
+++        elif int(ashex[2], 16) >= 8:
+++            # "looks negative", so need a byte of sign bits
+++            ashex = "0x00" + ashex[2:]
+++    else:
+++        # Build the 256's-complement:  (1L << nbytes) + x.  The trick is
+++        # to find the number of bytes in linear time (although that should
+++        # really be a constant-time task).
+++        ashex = hex(-x)
+++        assert ashex.startswith("0x")
+++        njunkchars = 2 + ashex.endswith('L')
+++        nibbles = len(ashex) - njunkchars
+++        if nibbles & 1:
+++            # Extend to a full byte.
+++            nibbles += 1
+++        nbits = nibbles * 4
+++        x += 1L << nbits
+++        assert x > 0
+++        ashex = hex(x)
+++        njunkchars = 2 + ashex.endswith('L')
+++        newnibbles = len(ashex) - njunkchars
+++        if newnibbles < nibbles:
+++            ashex = "0x" + "0" * (nibbles - newnibbles) + ashex[2:]
+++        if int(ashex[2], 16) < 8:
+++            # "looks positive", so need a byte of sign bits
+++            ashex = "0xff" + ashex[2:]
+++
+++    if ashex.endswith('L'):
+++        ashex = ashex[2:-1]
+++    else:
+++        ashex = ashex[2:]
+++    assert len(ashex) & 1 == 0, (x, ashex)
+++    binary = _binascii.unhexlify(ashex)
+++    return binary[::-1]
+++
+++def decode_long(data):
+++    r"""Decode a long from a two's complement little-endian binary string.
+++
+++    >>> decode_long('')
+++    0L
+++    >>> decode_long("\xff\x00")
+++    255L
+++    >>> decode_long("\xff\x7f")
+++    32767L
+++    >>> decode_long("\x00\xff")
+++    -256L
+++    >>> decode_long("\x00\x80")
+++    -32768L
+++    >>> decode_long("\x80")
+++    -128L
+++    >>> decode_long("\x7f")
+++    127L
+++    """
+++
+++    nbytes = len(data)
+++    if nbytes == 0:
+++        return 0L
+++    ashex = _binascii.hexlify(data[::-1])
+++    n = long(ashex, 16) # quadratic time before Python 2.3; linear now
+++    if data[-1] >= '\x80':
+++        n -= 1L << (nbytes * 8)
+++    return n
+++
+++# Shorthands
+++
+++try:
+++    from cStringIO import StringIO
+++except ImportError:
+++    from StringIO import StringIO
+++
+++def dump(obj, file, protocol=None):
+++    Pickler(file, protocol).dump(obj)
+++
+++def dumps(obj, protocol=None):
+++    file = StringIO()
+++    Pickler(file, protocol).dump(obj)
+++    return file.getvalue()
+++
+++def load(file):
+++    return Unpickler(file).load()
+++
+++def loads(str):
+++    file = StringIO(str)
+++    return Unpickler(file).load()
+++
+++# Doctest
+++
+++def _test():
+++    import doctest
+++    return doctest.testmod()
+++
+++if __name__ == "__main__":
+++    _test()
++diff -up mozilla-aurora/rebase/mystruct.py.rebase-dir mozilla-aurora/rebase/mystruct.py
++--- mozilla-aurora/rebase/mystruct.py.rebase-dir	2014-07-28 18:25:25.000000000 +0200
+++++ mozilla-aurora/rebase/mystruct.py	2014-07-28 18:25:25.000000000 +0200
++@@ -0,0 +1,15 @@
+++import struct
+++
+++def unpack_from(format, data, start):
+++  return struct.unpack(format, data[start:start + struct.calcsize(format)])
+++
+++class Struct:
+++  def __init__(self, format):
+++    self.format = format
+++    self.size = struct.calcsize(format)
+++  def unpack_from(self, buf, offset=0):
+++    return unpack_from(self.format, buf, offset)
+++  def pack(self, *args):
+++    return struct.pack(self.format, *args)
+++
+++
++diff -up mozilla-aurora/rebase/namedtuple.py.rebase-dir mozilla-aurora/rebase/namedtuple.py
++--- mozilla-aurora/rebase/namedtuple.py.rebase-dir	2014-07-28 18:25:25.000000000 +0200
+++++ mozilla-aurora/rebase/namedtuple.py	2014-07-28 18:25:25.000000000 +0200
++@@ -0,0 +1,147 @@
+++from operator import itemgetter as _itemgetter
+++from keyword import iskeyword as _iskeyword
+++import sys as _sys
+++
+++def namedtuple(typename, field_names, verbose=False, rename=False):
+++    """Returns a new subclass of tuple with named fields.
+++
+++    >>> Point = namedtuple('Point', 'x y')
+++    >>> Point.__doc__                   # docstring for the new class
+++    'Point(x, y)'
+++    >>> p = Point(11, y=22)             # instantiate with positional args or keywords
+++    >>> p[0] + p[1]                     # indexable like a plain tuple
+++    33
+++    >>> x, y = p                        # unpack like a regular tuple
+++    >>> x, y
+++    (11, 22)
+++    >>> p.x + p.y                       # fields also accessable by name
+++    33
+++    >>> d = p._asdict()                 # convert to a dictionary
+++    >>> d['x']
+++    11
+++    >>> Point(**d)                      # convert from a dictionary
+++    Point(x=11, y=22)
+++    >>> p._replace(x=100)               # _replace() is like str.replace() but targets named fields
+++    Point(x=100, y=22)
+++
+++    """
+++
+++    # Parse and validate the field names.  Validation serves two purposes,
+++    # generating informative error messages and preventing template injection attacks.
+++    if isinstance(field_names, basestring):
+++        field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas
+++    field_names = tuple(map(str, field_names))
+++    if rename:
+++        names = list(field_names)
+++        seen = set()
+++        for i, name in enumerate(names):
+++            if (not min(c.isalnum() or c=='_' for c in name) or _iskeyword(name)
+++                or not name or name[0].isdigit() or name.startswith('_')
+++                or name in seen):
+++                    names[i] = '_%d' % i
+++            seen.add(name)
+++        field_names = tuple(names)
+++    for name in (typename,) + field_names:
+++        if not min(c.isalnum() or c=='_' for c in name):
+++            raise ValueError('Type names and field names can only contain alphanumeric characters and underscores: %r' % name)
+++        if _iskeyword(name):
+++            raise ValueError('Type names and field names cannot be a keyword: %r' % name)
+++        if name[0].isdigit():
+++            raise ValueError('Type names and field names cannot start with a number: %r' % name)
+++    seen_names = set()
+++    for name in field_names:
+++        if name.startswith('_') and not rename:
+++            raise ValueError('Field names cannot start with an underscore: %r' % name)
+++        if name in seen_names:
+++            raise ValueError('Encountered duplicate field name: %r' % name)
+++        seen_names.add(name)
+++
+++    # Create and fill-in the class template
+++    numfields = len(field_names)
+++    argtxt = repr(field_names).replace("'", "")[1:-1]   # tuple repr without parens or quotes
+++    reprtxt = ', '.join('%s=%%r' % name for name in field_names)
+++    template = '''class %(typename)s(tuple):
+++        '%(typename)s(%(argtxt)s)' \n
+++        __slots__ = () \n
+++        _fields = %(field_names)r \n
+++        def __new__(_cls, %(argtxt)s):
+++            return _tuple.__new__(_cls, (%(argtxt)s)) \n
+++        @classmethod
+++        def _make(cls, iterable, new=tuple.__new__, len=len):
+++            'Make a new %(typename)s object from a sequence or iterable'
+++            result = new(cls, iterable)
+++            if len(result) != %(numfields)d:
+++                raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result))
+++            return result \n
+++        def __repr__(self):
+++            return '%(typename)s(%(reprtxt)s)' %% self \n
+++        def _asdict(self):
+++            'Return a new dict which maps field names to their values'
+++            return dict(zip(self._fields, self)) \n
+++        def _replace(_self, **kwds):
+++            'Return a new %(typename)s object replacing specified fields with new values'
+++            result = _self._make(map(kwds.pop, %(field_names)r, _self))
+++            if kwds:
+++                raise ValueError('Got unexpected field names: %%r' %% kwds.keys())
+++            return result \n
+++        def __getnewargs__(self):
+++            return tuple(self) \n\n''' % locals()
+++    for i, name in enumerate(field_names):
+++        template += '        %s = _property(_itemgetter(%d))\n' % (name, i)
+++    if verbose:
+++        print template
+++
+++    # Execute the template string in a temporary namespace
+++    namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename,
+++                     _property=property, _tuple=tuple)
+++    try:
+++        exec template in namespace
+++    except SyntaxError, e:
+++        raise SyntaxError(e.message + ':\n' + template)
+++    result = namespace[typename]
+++
+++    # For pickling to work, the __module__ variable needs to be set to the frame
+++    # where the named tuple is created.  Bypass this step in enviroments where
+++    # sys._getframe is not defined (Jython for example) or sys._getframe is not
+++    # defined for arguments greater than 0 (IronPython).
+++    try:
+++        result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__')
+++    except (AttributeError, ValueError):
+++        pass
+++
+++    return result
+++
+++
+++
+++
+++
+++
+++if __name__ == '__main__':
+++    # verify that instances can be pickled
+++    from cPickle import loads, dumps
+++    Point = namedtuple('Point', 'x, y', True)
+++    p = Point(x=10, y=20)
+++    assert p == loads(dumps(p, -1))
+++
+++    # test and demonstrate ability to override methods
+++    class Point(namedtuple('Point', 'x y')):
+++        @property
+++        def hypot(self):
+++            return (self.x ** 2 + self.y ** 2) ** 0.5
+++        def __str__(self):
+++            return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
+++
+++    for p in Point(3,4), Point(14,5), Point(9./7,6):
+++        print p
+++
+++    class Point(namedtuple('Point', 'x y')):
+++        'Point class with optimized _make() and _replace() without error-checking'
+++        _make = classmethod(tuple.__new__)
+++        def _replace(self, _map=map, **kwds):
+++            return self._make(_map(kwds.get, ('x', 'y'), self))
+++
+++    print Point(11, 22)._replace(x=100)
+++
+++    import doctest
+++    TestResults = namedtuple('TestResults', 'failed attempted')
+++    print TestResults(*doctest.testmod())
++diff -up mozilla-aurora/rebase/ordereddict.py.rebase-dir mozilla-aurora/rebase/ordereddict.py
++--- mozilla-aurora/rebase/ordereddict.py.rebase-dir	2014-07-28 18:25:25.000000000 +0200
+++++ mozilla-aurora/rebase/ordereddict.py	2014-07-28 18:25:25.000000000 +0200
++@@ -0,0 +1,127 @@
+++# Copyright (c) 2009 Raymond Hettinger
+++#
+++# 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.
+++
+++from UserDict import DictMixin
+++
+++class OrderedDict(dict, DictMixin):
+++
+++    def __init__(self, *args, **kwds):
+++        if len(args) > 1:
+++            raise TypeError('expected at most 1 arguments, got %d' % len(args))
+++        try:
+++            self.__end
+++        except AttributeError:
+++            self.clear()
+++        self.update(*args, **kwds)
+++
+++    def clear(self):
+++        self.__end = end = []
+++        end += [None, end, end]         # sentinel node for doubly linked list
+++        self.__map = {}                 # key --> [key, prev, next]
+++        dict.clear(self)
+++
+++    def __setitem__(self, key, value):
+++        if key not in self:
+++            end = self.__end
+++            curr = end[1]
+++            curr[2] = end[1] = self.__map[key] = [key, curr, end]
+++        dict.__setitem__(self, key, value)
+++
+++    def __delitem__(self, key):
+++        dict.__delitem__(self, key)
+++        key, prev, next = self.__map.pop(key)
+++        prev[2] = next
+++        next[1] = prev
+++
+++    def __iter__(self):
+++        end = self.__end
+++        curr = end[2]
+++        while curr is not end:
+++            yield curr[0]
+++            curr = curr[2]
+++
+++    def __reversed__(self):
+++        end = self.__end
+++        curr = end[1]
+++        while curr is not end:
+++            yield curr[0]
+++            curr = curr[1]
+++
+++    def popitem(self, last=True):
+++        if not self:
+++            raise KeyError('dictionary is empty')
+++        if last:
+++            key = reversed(self).next()
+++        else:
+++            key = iter(self).next()
+++        value = self.pop(key)
+++        return key, value
+++
+++    def __reduce__(self):
+++        items = [[k, self[k]] for k in self]
+++        tmp = self.__map, self.__end
+++        del self.__map, self.__end
+++        inst_dict = vars(self).copy()
+++        self.__map, self.__end = tmp
+++        if inst_dict:
+++            return (self.__class__, (items,), inst_dict)
+++        return self.__class__, (items,)
+++
+++    def keys(self):
+++        return list(self)
+++
+++    setdefault = DictMixin.setdefault
+++    update = DictMixin.update
+++    pop = DictMixin.pop
+++    values = DictMixin.values
+++    items = DictMixin.items
+++    iterkeys = DictMixin.iterkeys
+++    itervalues = DictMixin.itervalues
+++    iteritems = DictMixin.iteritems
+++
+++    def __repr__(self):
+++        if not self:
+++            return '%s()' % (self.__class__.__name__,)
+++        return '%s(%r)' % (self.__class__.__name__, self.items())
+++
+++    def copy(self):
+++        return self.__class__(self)
+++
+++    @classmethod
+++    def fromkeys(cls, iterable, value=None):
+++        d = cls()
+++        for key in iterable:
+++            d[key] = value
+++        return d
+++
+++    def __eq__(self, other):
+++        if isinstance(other, OrderedDict):
+++            if len(self) != len(other):
+++                return False
+++            for p, q in  zip(self.items(), other.items()):
+++                if p != q:
+++                    return False
+++            return True
+++        return dict.__eq__(self, other)
+++
+++    def __ne__(self, other):
+++        return not self == other
++diff -up mozilla-aurora/rebase/rhrebase.py.rebase-dir mozilla-aurora/rebase/rhrebase.py
++--- mozilla-aurora/rebase/rhrebase.py.rebase-dir	2014-07-28 18:25:25.000000000 +0200
+++++ mozilla-aurora/rebase/rhrebase.py	2014-07-28 18:25:25.000000000 +0200
++@@ -0,0 +1,46 @@
+++def isIterable(l):
+++  if hasattr(l, '__iter__'):
+++     return True
+++  else:
+++     return False
+++
+++def print24(msg, file):
+++  if file:
+++    file.write(msg)
+++  else:
+++    print msg
+++
+++# hack to not import this file instead of system logging
+++def import_non_local(name, custom_name=None):
+++    import imp, sys
+++
+++    custom_name = custom_name or name
+++
+++    f, pathname, desc = imp.find_module(name, sys.path[1:])
+++    module = imp.load_module(custom_name, f, pathname, desc)
+++    #f.close()
+++
+++    return module
+++
+++def get_first_if_true(first, second, cond):
+++   if cond:
+++      return first
+++   else:
+++      return second
+++
+++def all(iterable):
+++    for element in iterable:
+++        if not element:
+++            return False
+++    return True
+++
+++def any(iterable):
+++    for element in iterable:
+++        if element:
+++            return True
+++    return False
+++
+++
+++
+++
+++
++diff -up mozilla-aurora/rebase/uuid.py.rebase-dir mozilla-aurora/rebase/uuid.py
++--- mozilla-aurora/rebase/uuid.py.rebase-dir	2014-07-28 18:25:25.000000000 +0200
+++++ mozilla-aurora/rebase/uuid.py	2014-07-28 18:25:25.000000000 +0200
++@@ -0,0 +1,476 @@
+++r"""UUID objects (universally unique identifiers) according to RFC 4122.
+++
+++This module provides immutable UUID objects (class UUID) and the functions
+++uuid1(), uuid3(), uuid4(), uuid5() for generating version 1, 3, 4, and 5
+++UUIDs as specified in RFC 4122.
+++
+++If all you want is a unique ID, you should probably call uuid1() or uuid4().
+++Note that uuid1() may compromise privacy since it creates a UUID containing
+++the computer's network address.  uuid4() creates a random UUID.
+++
+++Typical usage:
+++
+++    >>> import uuid
+++
+++    # make a UUID based on the host ID and current time
+++    >>> uuid.uuid1()
+++    UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')
+++
+++    # make a UUID using an MD5 hash of a namespace UUID and a name
+++    >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
+++    UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
+++
+++    # make a random UUID
+++    >>> uuid.uuid4()
+++    UUID('16fd2706-8baf-433b-82eb-8c7fada847da')
+++
+++    # make a UUID using a SHA-1 hash of a namespace UUID and a name
+++    >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
+++    UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
+++
+++    # make a UUID from a string of hex digits (braces and hyphens ignored)
+++    >>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')
+++
+++    # convert a UUID to a string of hex digits in standard form
+++    >>> str(x)
+++    '00010203-0405-0607-0809-0a0b0c0d0e0f'
+++
+++    # get the raw 16 bytes of the UUID
+++    >>> x.bytes
+++    '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'
+++
+++    # make a UUID from a 16-byte string
+++    >>> uuid.UUID(bytes=x.bytes)
+++    UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
+++"""
+++
+++__author__ = 'Ka-Ping Yee <ping at zesty.ca>'
+++__date__ = '$Date: 2006/06/12 23:15:40 $'.split()[1].replace('/', '-')
+++__version__ = '$Revision: 1.30 $'.split()[1]
+++
+++RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [
+++    'reserved for NCS compatibility', 'specified in RFC 4122',
+++    'reserved for Microsoft compatibility', 'reserved for future definition']
+++
+++class UUID(object):
+++    """Instances of the UUID class represent UUIDs as specified in RFC 4122.
+++    UUID objects are immutable, hashable, and usable as dictionary keys.
+++    Converting a UUID to a string with str() yields something in the form
+++    '12345678-1234-1234-1234-123456789abc'.  The UUID constructor accepts
+++    four possible forms: a similar string of hexadecimal digits, or a
+++    string of 16 raw bytes as an argument named 'bytes', or a tuple of
+++    six integer fields (with 32-bit, 16-bit, 16-bit, 8-bit, 8-bit, and
+++    48-bit values respectively) as an argument named 'fields', or a single
+++    128-bit integer as an argument named 'int'.
+++
+++    UUIDs have these read-only attributes:
+++
+++        bytes       the UUID as a 16-byte string
+++
+++        fields      a tuple of the six integer fields of the UUID,
+++                    which are also available as six individual attributes
+++                    and two derived attributes:
+++
+++            time_low                the first 32 bits of the UUID
+++            time_mid                the next 16 bits of the UUID
+++            time_hi_version         the next 16 bits of the UUID
+++            clock_seq_hi_variant    the next 8 bits of the UUID
+++            clock_seq_low           the next 8 bits of the UUID
+++            node                    the last 48 bits of the UUID
+++
+++            time                    the 60-bit timestamp
+++            clock_seq               the 14-bit sequence number
+++
+++        hex         the UUID as a 32-character hexadecimal string
+++
+++        int         the UUID as a 128-bit integer
+++
+++        urn         the UUID as a URN as specified in RFC 4122
+++
+++        variant     the UUID variant (one of the constants RESERVED_NCS,
+++                    RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE)
+++
+++        version     the UUID version number (1 through 5, meaningful only
+++                    when the variant is RFC_4122)
+++    """
+++
+++    def __init__(self, hex=None, bytes=None, fields=None, int=None,
+++                       version=None):
+++        r"""Create a UUID from either a string of 32 hexadecimal digits,
+++        a string of 16 bytes as the 'bytes' argument, a tuple of six
+++        integers (32-bit time_low, 16-bit time_mid, 16-bit time_hi_version,
+++        8-bit clock_seq_hi_variant, 8-bit clock_seq_low, 48-bit node) as
+++        the 'fields' argument, or a single 128-bit integer as the 'int'
+++        argument.  When a string of hex digits is given, curly braces,
+++        hyphens, and a URN prefix are all optional.  For example, these
+++        expressions all yield the same UUID:
+++
+++        UUID('{12345678-1234-5678-1234-567812345678}')
+++        UUID('12345678123456781234567812345678')
+++        UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
+++        UUID(bytes='\x12\x34\x56\x78'*4)
+++        UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
+++        UUID(int=0x12345678123456781234567812345678)
+++
+++        Exactly one of 'hex', 'bytes', 'fields', or 'int' must be given.
+++        The 'version' argument is optional; if given, the resulting UUID
+++        will have its variant and version number set according to RFC 4122,
+++        overriding bits in the given 'hex', 'bytes', 'fields', or 'int'.
+++        """
+++
+++        if [hex, bytes, fields, int].count(None) != 3:
+++            raise TypeError('need just one of hex, bytes, fields, or int')
+++        if hex is not None:
+++            hex = hex.replace('urn:', '').replace('uuid:', '')
+++            hex = hex.strip('{}').replace('-', '')
+++            if len(hex) != 32:
+++                raise ValueError('badly formed hexadecimal UUID string')
+++            int = long(hex, 16)
+++        if bytes is not None:
+++            if len(bytes) != 16:
+++                raise ValueError('bytes is not a 16-char string')
+++            int = long(('%02x'*16) % tuple(map(ord, bytes)), 16)
+++        if fields is not None:
+++            if len(fields) != 6:
+++                raise ValueError('fields is not a 6-tuple')
+++            (time_low, time_mid, time_hi_version,
+++             clock_seq_hi_variant, clock_seq_low, node) = fields
+++            if not 0 <= time_low < 1<<32L:
+++                raise ValueError('field 1 out of range (need a 32-bit value)')
+++            if not 0 <= time_mid < 1<<16L:
+++                raise ValueError('field 2 out of range (need a 16-bit value)')
+++            if not 0 <= time_hi_version < 1<<16L:
+++                raise ValueError('field 3 out of range (need a 16-bit value)')
+++            if not 0 <= clock_seq_hi_variant < 1<<8L:
+++                raise ValueError('field 4 out of range (need an 8-bit value)')
+++            if not 0 <= clock_seq_low < 1<<8L:
+++                raise ValueError('field 5 out of range (need an 8-bit value)')
+++            if not 0 <= node < 1<<48L:
+++                raise ValueError('field 6 out of range (need a 48-bit value)')
+++            clock_seq = (clock_seq_hi_variant << 8L) | clock_seq_low
+++            int = ((time_low << 96L) | (time_mid << 80L) |
+++                   (time_hi_version << 64L) | (clock_seq << 48L) | node)
+++        if int is not None:
+++            if not 0 <= int < 1<<128L:
+++                raise ValueError('int is out of range (need a 128-bit value)')
+++        if version is not None:
+++            if not 1 <= version <= 5:
+++                raise ValueError('illegal version number')
+++            # Set the variant to RFC 4122.
+++            int &= ~(0xc000 << 48L)
+++            int |= 0x8000 << 48L
+++            # Set the version number.
+++            int &= ~(0xf000 << 64L)
+++            int |= version << 76L
+++        self.__dict__['int'] = int
+++
+++    def __cmp__(self, other):
+++        if isinstance(other, UUID):
+++            return cmp(self.int, other.int)
+++        return NotImplemented
+++
+++    def __hash__(self):
+++        return hash(self.int)
+++
+++    def __int__(self):
+++        return self.int
+++
+++    def __repr__(self):
+++        return 'UUID(%r)' % str(self)
+++
+++    def __setattr__(self, name, value):
+++        raise TypeError('UUID objects are immutable')
+++
+++    def __str__(self):
+++        hex = '%032x' % self.int
+++        return '%s-%s-%s-%s-%s' % (
+++            hex[:8], hex[8:12], hex[12:16], hex[16:20], hex[20:])
+++
+++    def get_bytes(self):
+++        bytes = ''
+++        for shift in range(0, 128, 8):
+++            bytes = chr((self.int >> shift) & 0xff) + bytes
+++        return bytes
+++
+++    bytes = property(get_bytes)
+++
+++    def get_fields(self):
+++        return (self.time_low, self.time_mid, self.time_hi_version,
+++                self.clock_seq_hi_variant, self.clock_seq_low, self.node)
+++
+++    fields = property(get_fields)
+++
+++    def get_time_low(self):
+++        return self.int >> 96L
+++
+++    time_low = property(get_time_low)
+++
+++    def get_time_mid(self):
+++        return (self.int >> 80L) & 0xffff
+++
+++    time_mid = property(get_time_mid)
+++
+++    def get_time_hi_version(self):
+++        return (self.int >> 64L) & 0xffff
+++
+++    time_hi_version = property(get_time_hi_version)
+++
+++    def get_clock_seq_hi_variant(self):
+++        return (self.int >> 56L) & 0xff
+++
+++    clock_seq_hi_variant = property(get_clock_seq_hi_variant)
+++
+++    def get_clock_seq_low(self):
+++        return (self.int >> 48L) & 0xff
+++
+++    clock_seq_low = property(get_clock_seq_low)
+++
+++    def get_time(self):
+++        return (((self.time_hi_version & 0x0fffL) << 48L) |
+++                (self.time_mid << 32L) | self.time_low)
+++
+++    time = property(get_time)
+++
+++    def get_clock_seq(self):
+++        return (((self.clock_seq_hi_variant & 0x3fL) << 8L) |
+++                self.clock_seq_low)
+++
+++    clock_seq = property(get_clock_seq)
+++
+++    def get_node(self):
+++        return self.int & 0xffffffffffff
+++
+++    node = property(get_node)
+++
+++    def get_hex(self):
+++        return '%032x' % self.int
+++
+++    hex = property(get_hex)
+++
+++    def get_urn(self):
+++        return 'urn:uuid:' + str(self)
+++
+++    urn = property(get_urn)
+++
+++    def get_variant(self):
+++        if not self.int & (0x8000 << 48L):
+++            return RESERVED_NCS
+++        elif not self.int & (0x4000 << 48L):
+++            return RFC_4122
+++        elif not self.int & (0x2000 << 48L):
+++            return RESERVED_MICROSOFT
+++        else:
+++            return RESERVED_FUTURE
+++
+++    variant = property(get_variant)
+++
+++    def get_version(self):
+++        # The version bits are only meaningful for RFC 4122 UUIDs.
+++        if self.variant == RFC_4122:
+++            return int((self.int >> 76L) & 0xf)
+++
+++    version = property(get_version)
+++
+++def _ifconfig_getnode():
+++    """Get the hardware address on Unix by running ifconfig."""
+++    import os
+++    for dir in ['', '/sbin/', '/usr/sbin']:
+++        try:
+++            pipe = os.popen(os.path.join(dir, 'ifconfig'))
+++        except IOError:
+++            continue
+++        for line in pipe:
+++            words = line.lower().split()
+++            for i in range(len(words)):
+++                if words[i] in ['hwaddr', 'ether']:
+++                    return int(words[i + 1].replace(':', ''), 16)
+++
+++def _ipconfig_getnode():
+++    """Get the hardware address on Windows by running ipconfig.exe."""
+++    import os, re
+++    dirs = ['', r'c:\windows\system32', r'c:\winnt\system32']
+++    try:
+++        import ctypes
+++        buffer = ctypes.create_string_buffer(300)
+++        ctypes.windll.kernel32.GetSystemDirectoryA(buffer, 300)
+++        dirs.insert(0, buffer.value.decode('mbcs'))
+++    except:
+++        pass
+++    for dir in dirs:
+++        try:
+++            pipe = os.popen(os.path.join(dir, 'ipconfig') + ' /all')
+++        except IOError:
+++            continue
+++        for line in pipe:
+++            value = line.split(':')[-1].strip().lower()
+++            if re.match('([0-9a-f][0-9a-f]-){5}[0-9a-f][0-9a-f]', value):
+++                return int(value.replace('-', ''), 16)
+++
+++def _netbios_getnode():
+++    """Get the hardware address on Windows using NetBIOS calls.
+++    See http://support.microsoft.com/kb/118623 for details."""
+++    import win32wnet, netbios
+++    ncb = netbios.NCB()
+++    ncb.Command = netbios.NCBENUM
+++    ncb.Buffer = adapters = netbios.LANA_ENUM()
+++    adapters._pack()
+++    if win32wnet.Netbios(ncb) != 0:
+++        return
+++    adapters._unpack()
+++    for i in range(adapters.length):
+++        ncb.Reset()
+++        ncb.Command = netbios.NCBRESET
+++        ncb.Lana_num = ord(adapters.lana[i])
+++        if win32wnet.Netbios(ncb) != 0:
+++            continue
+++        ncb.Reset()
+++        ncb.Command = netbios.NCBASTAT
+++        ncb.Lana_num = ord(adapters.lana[i])
+++        ncb.Callname = '*'.ljust(16)
+++        ncb.Buffer = status = netbios.ADAPTER_STATUS()
+++        if win32wnet.Netbios(ncb) != 0:
+++            continue
+++        status._unpack()
+++        bytes = map(ord, status.adapter_address)
+++        return ((bytes[0]<<40L) + (bytes[1]<<32L) + (bytes[2]<<24L) +
+++                (bytes[3]<<16L) + (bytes[4]<<8L) + bytes[5])
+++
+++# Thanks to Thomas Heller for ctypes and for his help with its use here.
+++
+++# If ctypes is available, use it to find system routines for UUID generation.
+++_uuid_generate_random = _uuid_generate_time = _UuidCreate = None
+++try:
+++    import ctypes, ctypes.util
+++    _buffer = ctypes.create_string_buffer(16)
+++
+++    # The uuid_generate_* routines are provided by libuuid on at least
+++    # Linux and FreeBSD, and provided by libc on Mac OS X.
+++    for libname in ['uuid', 'c']:
+++        try:
+++            lib = ctypes.CDLL(ctypes.util.find_library(libname))
+++        except:
+++            continue
+++        if hasattr(lib, 'uuid_generate_random'):
+++            _uuid_generate_random = lib.uuid_generate_random
+++        if hasattr(lib, 'uuid_generate_time'):
+++            _uuid_generate_time = lib.uuid_generate_time
+++
+++    # On Windows prior to 2000, UuidCreate gives a UUID containing the
+++    # hardware address.  On Windows 2000 and later, UuidCreate makes a
+++    # random UUID and UuidCreateSequential gives a UUID containing the
+++    # hardware address.  These routines are provided by the RPC runtime.
+++    try:
+++        lib = ctypes.windll.rpcrt4
+++    except:
+++        lib = None
+++    _UuidCreate = getattr(lib, 'UuidCreateSequential',
+++                          getattr(lib, 'UuidCreate', None))
+++except:
+++    pass
+++
+++def _unixdll_getnode():
+++    """Get the hardware address on Unix using ctypes."""
+++    _uuid_generate_time(_buffer)
+++    return UUID(bytes=_buffer.raw).node
+++
+++def _windll_getnode():
+++    """Get the hardware address on Windows using ctypes."""
+++    if _UuidCreate(_buffer) == 0:
+++        return UUID(bytes=_buffer.raw).node
+++
+++def _random_getnode():
+++    """Get a random node ID, with eighth bit set as suggested by RFC 4122."""
+++    import random
+++    return random.randrange(0, 1<<48L) | 0x010000000000L
+++
+++_node = None
+++
+++def getnode():
+++    """Get the hardware address as a 48-bit integer.  The first time this
+++    runs, it may launch a separate program, which could be quite slow.  If
+++    all attempts to obtain the hardware address fail, we choose a random
+++    48-bit number with its eighth bit set to 1 as recommended in RFC 4122."""
+++
+++    global _node
+++    if _node is not None:
+++        return _node
+++
+++    import sys
+++    if sys.platform == 'win32':
+++        getters = [_windll_getnode, _netbios_getnode, _ipconfig_getnode]
+++    else:
+++        getters = [_unixdll_getnode, _ifconfig_getnode]
+++
+++    for getter in getters + [_random_getnode]:
+++        try:
+++            _node = getter()
+++        except:
+++            continue
+++        if _node is not None:
+++            return _node
+++
+++def uuid1(node=None, clock_seq=None):
+++    """Generate a UUID from a host ID, sequence number, and the current time.
+++    If 'node' is not given, getnode() is used to obtain the hardware
+++    address.  If 'clock_seq' is given, it is used as the sequence number;
+++    otherwise a random 14-bit sequence number is chosen."""
+++
+++    # When the system provides a version-1 UUID generator, use it (but don't
+++    # use UuidCreate here because its UUIDs don't conform to RFC 4122).
+++    if _uuid_generate_time and node is clock_seq is None:
+++        _uuid_generate_time(_buffer)
+++        return UUID(bytes=_buffer.raw)
+++
+++    import time
+++    nanoseconds = int(time.time() * 1e9)
+++    # 0x01b21dd213814000 is the number of 100-ns intervals between the
+++    # UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
+++    timestamp = int(nanoseconds/100) + 0x01b21dd213814000L
+++    if clock_seq is None:
+++        import random
+++        clock_seq = random.randrange(1<<14L) # instead of stable storage
+++    time_low = timestamp & 0xffffffffL
+++    time_mid = (timestamp >> 32L) & 0xffffL
+++    time_hi_version = (timestamp >> 48L) & 0x0fffL
+++    clock_seq_low = clock_seq & 0xffL
+++    clock_seq_hi_variant = (clock_seq >> 8L) & 0x3fL
+++    if node is None:
+++        node = getnode()
+++    return UUID(fields=(time_low, time_mid, time_hi_version,
+++                        clock_seq_hi_variant, clock_seq_low, node), version=1)
+++
+++def uuid3(namespace, name):
+++    """Generate a UUID from the MD5 hash of a namespace UUID and a name."""
+++    import md5
+++    hash = md5.md5(namespace.bytes + name).digest()
+++    return UUID(bytes=hash[:16], version=3)
+++
+++def uuid4():
+++    """Generate a random UUID."""
+++
+++    # When the system provides a version-4 UUID generator, use it.
+++    if _uuid_generate_random:
+++        _uuid_generate_random(_buffer)
+++        return UUID(bytes=_buffer.raw)
+++
+++    # Otherwise, get randomness from urandom or the 'random' module.
+++    try:
+++        import os
+++        return UUID(bytes=os.urandom(16), version=4)
+++    except:
+++        import random
+++        bytes = [chr(random.randrange(256)) for i in range(16)]
+++        return UUID(bytes=bytes, version=4)
+++
+++def uuid5(namespace, name):
+++    """Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
+++    import sha
+++    hash = sha.sha(namespace.bytes + name).digest()
+++    return UUID(bytes=hash[:16], version=5)
+++
+++# The following standard UUIDs are for use with uuid3() or uuid5().
+++
+++NAMESPACE_DNS = UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
+++NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8')
+++NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8')
+++NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8')
diff --cc sources
index 1244ce3,0a4f031..5489530
--- a/sources
+++ b/sources
@@@ -1,4 -1,3 +1,6 @@@
- 689eece85bd132adc72413158c7a46df  lightning-2.6.5.source.tar.bz2
- aaeef94716b602924b539a7c700053ee  l10n-2.6.5.tar.xz
+ 3d9c8a52ba75fcee5655839ab00cbda4  lightning-3.3.source.tar.bz2
+ 620cbeb932d910e1e33bebc47fff2f9c  l10n-3.3.tar.xz
+ 0bbe3a2e5e4cac040013733aca159d89  simplejson-2.1.1.tar.gz
 +711afa1062a1d2c4a67acdf02a33d86e  pysqlite-2.6.3.tar.gz
 +bd639f9b0eac4c42497034dec2ec0c2b  setuptools-0.6c11-py2.4.egg
++a8ee9a58dc887d4a1942da4afec402f0  virtualtools-1.7.2.zip
diff --cc thunderbird-lightning-lightning.patch
index 0000000,0000000..abbbdef
new file mode 100644
--- /dev/null
+++ b/thunderbird-lightning-lightning.patch
@@@ -1,0 -1,0 +1,9 @@@
++diff -up thunderbird-lightning-3.3/comm-esr31/calendar/providers/gdata/makeversion.py.lightning thunderbird-lightning-3.3/comm-esr31/calendar/providers/gdata/makeversion.py
++--- thunderbird-lightning-3.3/comm-esr31/calendar/providers/gdata/makeversion.py.lightning	2014-07-17 18:04:05.000000000 -0600
+++++ thunderbird-lightning-3.3/comm-esr31/calendar/providers/gdata/makeversion.py	2014-10-23 16:40:44.959935874 -0600
++@@ -9,4 +9,4 @@ import re
++ #  Lightning 1.2 -> gdata-provider 0.11
++ #  Lightning 1.3a1 -> gdata-provider 0.12pre
++ v = re.search(r"(\d+\.\d+)([a-z]\d+)?", sys.argv[1])
++-print "{0:.2f}".format((float(v.group(1)) - 0.1)/10) + (v.lastindex == 2 and "pre" or "")
+++print "%.2f" % ((float(v.group(1)) - 0.1)/10) + (v.lastindex == 2 and "pre" or "")
diff --cc thunderbird-lightning.spec
index ee29246,b93efc4..6789e7a
--- a/thunderbird-lightning.spec
+++ b/thunderbird-lightning.spec
@@@ -43,36 -66,39 +66,45 @@@ Source1:        mklangsource.s
  Source2:        l10n-%{version}.tar.xz
  # Config file for compilation
  Source10:       thunderbird-mozconfig
 +Source31:       pysqlite-2.6.3.tar.gz
  # Finds requirements provided outside of the current file set
  Source100:      find-external-requires
+ Source200:      simplejson-2.1.1.tar.gz
 +Source201:      setuptools-0.6c11-py2.4.egg
++Source202:      virtualtools-1.7.2.zip
  
- # Mozilla (XULRunner) patches
- Patch0:         thunderbird-version.patch
+ # Build patches
  Patch1:         mozilla-build-arm.patch
- # Fix build on secondary arches (patches copied from xulrunner)
- Patch2:         xulrunner-10.0-secondary-ipc.patch
- 
- Patch099:       mozilla-build.patch
- Patch100:       xulrunner-2.0-chromium-types.patch
- Patch101:       mozilla-abort.patch
- Patch103:       xulrunner-gc-sections-ppc.patch
- # For RHEL5 only
- Patch201:       mozilla-python.patch
- Patch204:       xulrunner-missing-pysqlite.patch
- Patch210:	mozilla-python2.patch
+ Patch15:        disable-webm.patch
+ Patch16:        nullptr.patch
+ 
 -# EL6 Specific
 -# Use old python
 -Patch097:       mozilla-python.patch
++# Xulrunner patches
+ Patch104:       rhbz-966424.patch
+ Patch105:       xulrunner-24.0-jemalloc-ppc.patch
+ Patch106:       xulrunner-24.0-s390-inlines.patch
+ Patch107:       firefox-system-nss-3.16.2.patch
+ Patch108:       remove-ogg.patch
++Patch214:       pango-backport.patch
++Patch215:       mozilla-python3.patch
++Patch216:       rebase-dir.patch
  
  # Thunderbird specific
+ Patch301:       thunderbird-objdir.patch
+ Patch302:       array_len.patch
  
- # Lightning
++# Lightning specifig
++Patch400:       thunderbird-lightning-lightning.patch
 +
  BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+ %if %{?system_nss}
  BuildRequires:  nspr-devel >= %{nspr_version}
  BuildRequires:  nss-devel >= %{nss_version}
- %if 0%{?fedora} > 15
+ Requires:       nspr >= %{nspr_build_version}
+ Requires:       nss >= %{nss_build_version}
+ %if 0%{?fedora}
  BuildRequires:  nss-static
  %endif
+ %endif
 -BuildRequires:  cairo-devel >= %{cairo_version}
  BuildRequires:  libnotify-devel >= %{libnotify_version}
  BuildRequires:  libpng-devel
  BuildRequires:  libjpeg-devel
@@@ -89,6 -115,10 +121,9 @@@ BuildRequires:  pango-deve
  BuildRequires:  freetype-devel >= %{freetype_version}
  BuildRequires:  libXt-devel
  BuildRequires:  libXrender-devel
 -BuildRequires:  hunspell-devel
+ %if %{?system_sqlite}
+ BuildRequires:  sqlite-devel >= %{sqlite_version}
+ %endif
  BuildRequires:  startup-notification-devel
  BuildRequires:  alsa-lib-devel
  BuildRequires:  autoconf213
@@@ -97,10 -128,10 +132,10 @@@ BuildRequires:  python-setuptool
  BuildRequires:  python-simplejson
  BuildRequires:  yasm
  BuildRequires:  mesa-libGL-devel
- # FIXME should be omitted when building without system sqlite?
- BuildRequires:  sqlite-devel
 -BuildRequires:  pulseaudio-libs-devel
 +BuildRequires:  gcc44-c++
- 
+ %if %{?system_ffi}
+ BuildRequires:  libffi-devel
+ %endif
  Requires:       thunderbird >= %{thunderbird_version}
  Requires:       thunderbird < %{thunderbird_next_version}
  Obsoletes:      thunderbird-lightning-wcap <= 0.8
@@@ -108,12 -141,12 +145,16 @@@ Provides:       thunderbird-lightning-w
  AutoProv: 0
  %global _use_internal_dependency_generator 0
  %global __find_requires %{SOURCE100}
+ %else
+ %global __provides_exclude_from ^%{_libdir}/mozilla/.*$
+ %global __requires_exclude_from ^%{_libdir}/mozilla/.*$
+ %endif
  
 - 
 +# Build fails on ppc for now
 +# https://bugzilla.redhat.com/show_bug.cgi?id=924354
 +ExcludeArch:    ppc
 +
 +
  %description
  Lightning brings the Sunbird calendar to the popular email client,
  Mozilla Thunderbird. Since it's an extension, Lightning is tightly
@@@ -139,51 -171,77 +180,101 @@@ your bug already has a solution
  %setup -q -c -a 2
  cd %{tarballdir}
  
- sed -e 's/__RPM_VERSION_INTERNAL__/%{version_internal}/' %{P:%%PATCH0} \
-     > version.patch
- %{__patch} -p1 -b --suffix .version --fuzz=0 < version.patch
+ # xulrunner patches
+ cd mozilla
 -%patch097 -p1 -b .python
+ %patch104 -p1 -b .rhbz-966424
+ %patch105 -p2 -b .jemalloc-ppc
+ %patch106 -p1 -b .s390
+ %patch107 -p3 -b .system_nss
+ %patch108 -p1 -b .remove-ogg
++%patch214 -p1 -b .pango-backport
++%patch216 -p1 -b .rebase-dir
+ %patch15 -p1 -b .disable-webm
+ %patch16  -p1 -b .nullptr
+ cd -
+ 
+ # thunderbird specific patches
+ %patch301 -p2 -b .objdir
+ %patch302 -p1 -b .array_len
++%patch215 -p1 -b .python3
++
++# lightning specific
++%patch400 -p2 -b .lightning
+ 
+ #sed -e 's/__RPM_VERSION_INTERNAL__/%{version_internal}/' %{P:%%PATCH0} \
+ #    > version.patch
+ #%{__patch} -p1 -b --suffix .version --fuzz=0 < version.patch
  cd mozilla
  %patch1 -p2 -b .arm-fix
- %patch2 -p3 -b .secondary-ipc
- %patch099 -p1 -b .build
- %patch100 -p2 -b .chromium-types
- %patch101 -p1 -b .abort
- %patch201 -p1 -b .python
- %patch204 -p1 -b .pysqlite
- %patch210 -p1 -b .python2
- %patch103 -p2 -b .gc-sections
  cd ..
  
 +# thunderbird specific patches
 +
  %{__rm} -f .mozconfig
  %{__cp} %{SOURCE10} .mozconfig
+ 
++rm -rf mozilla/python/virtualenv
++unzip %{SOURCE202} -d mozilla/python/
++mv mozilla/python/virtualenv-1.7.2 mozilla/python/virtualenv
++tar xz -C `pwd`/mozilla/rebase --strip-components=1 -f %{SOURCE200} simplejson-2.1.1/simplejson
++#%{__cp} %{SOURCE200} python/virtualenv/
 +%{__cp} %{SOURCE201} mozilla/python/virtualenv/
 +
++cd mozilla/python/mozbuild/mozbuild/backend/
++ln -s ../preprocessor.py
++ln -s ../makeutil.py
++ln -s ../pythonutil.py
++ln -s ../util.py
++cd -
++
 +# RHEL 5 mozconfig changes:
 +echo "ac_add_options --disable-system-hunspell" >> .mozconfig
 +echo "ac_add_options --disable-libnotify" >> .mozconfig
 +echo "ac_add_options --disable-methodjit" >> .mozconfig
 +echo "ac_add_options --disable-skia" >> .mozconfig
 +
- # Disable webm
- echo "ac_add_options --without-system-libvpx" >> .mozconfig
- echo "ac_add_options --disable-webm" >> .mozconfig
- echo "ac_add_options --disable-webrtc" >> .mozconfig
- echo "ac_add_options --disable-ogg" >> .mozconfig
- 
- # s390(x) fails to start with jemalloc enabled
- %ifarch s390 s390x
- echo "ac_add_options --disable-jemalloc" >> .mozconfig
+ %if %{?system_nss}
+ echo "ac_add_options --with-system-nspr" >> .mozconfig
+ echo "ac_add_options --with-system-nss" >> .mozconfig
+ %else
+ echo "ac_add_options --without-system-nspr" >> .mozconfig
+ echo "ac_add_options --without-system-nss" >> .mozconfig
  %endif
  
  %ifarch %{arm}
  echo "ac_add_options --disable-elf-hack" >> .mozconfig
  %endif
  
 -%ifnarch %{ix86} x86_64
 -echo "ac_add_options --disable-webrtc" >> .mozconfig
 -%endif
 +# Copy pysqlite tarball to location from where it will be installed, for RHEL5 only
 +%{__cp} %{SOURCE31} mozilla/testing/mozbase/mozprofile
  
+ %if %{?system_sqlite}
+ echo "ac_add_options --enable-system-sqlite"  >> .mozconfig
+ %else
+ echo "ac_add_options --disable-system-sqlite" >> .mozconfig
+ %endif
+ 
+ %if %{?system_ffi}
+ echo "ac_add_options --enable-system-ffi" >> .mozconfig
+ %endif
+ 
+ %ifnarch %{ix86} x86_64
+ echo "ac_add_options --disable-methodjit" >> .mozconfig
+ echo "ac_add_options --disable-monoic" >> .mozconfig
+ echo "ac_add_options --disable-polyic" >> .mozconfig
+ echo "ac_add_options --disable-tracejit" >> .mozconfig
+ %endif
+ 
 -echo "ac_add_options --enable-system-hunspell" >> .mozconfig
 -echo "ac_add_options --enable-libnotify" >> .mozconfig
+ echo "ac_add_options --enable-startup-notification" >> .mozconfig
+ echo "ac_add_options --without-system-libvpx" >> .mozconfig
+ echo "ac_add_options --disable-webm" >> .mozconfig
+ echo "ac_add_options --disable-webrtc" >> .mozconfig
+ echo "ac_add_options --disable-ogg" >> .mozconfig
+ echo "ac_add_options --disable-opus" >> .mozconfig
+ 
+ echo "ac_add_options --disable-debug" >> .mozconfig
+ echo "ac_add_options --enable-optimize" >> .mozconfig
+ 
  # Fix permissions
  find -name \*.js -type f | xargs chmod -x
  
@@@ -203,20 -277,10 +313,18 @@@ MOZ_APP_DIR=%{mozappdir
  #
  # Disable C++ exceptions since Mozilla code is not exception-safe
  # 
 -MOZ_OPT_FLAGS=$(echo "$RPM_OPT_FLAGS -fpermissive" | \
 +MOZ_OPT_FLAGS=$(echo "$RPM_OPT_FLAGS" | \
                        %{__sed} -e 's/-Wall//')
 +%ifarch %{ix86}
 +# i386 target is missing sync_bool_compare_and_swap/sync_add_and_fetch
 +# gcc build-in functions
 +MOZ_OPT_FLAGS=$(echo "$MOZ_OPT_FLAGS" | %{__sed} -e 's/-march=i386/-march=i686/')
 +%endif
 +export CC=gcc44
 +export GCC=gcc44
 +export CXX=g++44
- # https://bugzilla.redhat.com/show_bug.cgi?id=1037355
- MOZ_OPT_FLAGS="$MOZ_OPT_FLAGS -Wformat-security -Wformat"
  export CFLAGS=$MOZ_OPT_FLAGS
--export CXXFLAGS=$MOZ_OPT_FLAGS
++export CXXFLAGS="$MOZ_OPT_FLAGS -fpermissive"
  
  export PREFIX='%{_prefix}'
  export LIBDIR='%{_libdir}'
diff --cc thunderbird-mozconfig
index ea72cff,2a45066..47f9744
--- a/thunderbird-mozconfig
+++ b/thunderbird-mozconfig
@@@ -33,10 -28,13 +28,15 @@@ ac_add_options --enable-startup-notific
  ac_add_options --disable-libjpeg-turbo
  ac_add_options --disable-cpp-exceptions
  ac_add_options --disable-updater
- ac_add_options --disable-elf-hack
  ac_add_options --disable-gstreamer
 +ac_add_options --disable-gio
- ac_add_options --enable-gnomevfs
+ ac_add_options --enable-cpp-rtti
++ac_add_options --disable-pulseaudio
+ 
+ # thunderbird related
+ ac_add_options --enable-xinerama
+ ac_add_options --disable-xprint
+ ac_add_options --enable-safe-browsing
  
  # lightning related
  ac_add_options --enable-calendar


More information about the scm-commits mailing list