diff --git a/app/soc/content/css/v2/gsoc/dashboard.css b/app/soc/content/css/v2/gsoc/dashboard.css
index 6ff6527..c94dca2 100644
--- a/app/soc/content/css/v2/gsoc/dashboard.css
+++ b/app/soc/content/css/v2/gsoc/dashboard.css
@@ -161,7 +161,8 @@
 }
 .column-entry.view_mentor_evaluation,
 .column-entry.view_student_evaluation,
-.column-entry.view_evaluation_group
+.column-entry.view_evaluation_group,
+.column-entry.projects
 {
   background-image: url(../../../images/soc/dashboard/view.png);
 }
diff --git a/app/soc/modules/gsoc/views/admin.py b/app/soc/modules/gsoc/views/admin.py
index 5b5532a..0031c8c 100644
--- a/app/soc/modules/gsoc/views/admin.py
+++ b/app/soc/modules/gsoc/views/admin.py
@@ -53,7 +53,7 @@
 from soc.modules.gsoc.views.dashboard import BIRTHDATE_FORMAT
 from soc.modules.gsoc.views.helper import url_names
 from soc.modules.gsoc.views.helper.url_patterns import url
-from soc.modules.gsoc.views.projects_list import ProjectList
+from soc.modules.gsoc.views import projects_list
 
 
 class LookupForm(gsoc_forms.GSoCModelForm):
@@ -1631,8 +1631,8 @@
 
   def jsonContext(self, data, check, mutator):
     list_query = project_logic.getProjectsQuery(program=data.program)
-    list_content = ProjectList(
-        data.request, data, list_query, self.LIST_IDX).getListData()
+    list_content = projects_list.ProjectList(
+        data, list_query, idx=self.LIST_IDX).getListData()
     if list_content:
       return list_content.content()
     else:
@@ -1642,8 +1642,7 @@
     list_query = project_logic.getProjectsQuery(program=data.program)
     return {
       'page_name': 'Projects list page',
-      # TODO(nathaniel): Drop the first parameter of ProjectList.
-      'list': ProjectList(data.request, data, list_query, self.LIST_IDX),
+      'list': projects_list.ProjectList(data, list_query, idx=self.LIST_IDX),
     }
 
 
diff --git a/app/soc/modules/gsoc/views/helper/access_checker.py b/app/soc/modules/gsoc/views/helper/access_checker.py
index 97526ab..5f38003 100644
--- a/app/soc/modules/gsoc/views/helper/access_checker.py
+++ b/app/soc/modules/gsoc/views/helper/access_checker.py
@@ -35,7 +35,7 @@
 from soc.modules.gsoc.models.grading_survey_group import GSoCGradingSurveyGroup
 from soc.modules.gsoc.models.grading_record import GSoCGradingRecord
 from soc.modules.gsoc.models.profile import GSoCProfile
-from soc.modules.gsoc.models.project import GSoCProject
+from soc.modules.gsoc.models import project as project_model
 from soc.modules.gsoc.models.project_survey import ProjectSurvey
 from soc.modules.gsoc.models.project_survey_record import \
     GSoCProjectSurveyRecord
@@ -178,7 +178,7 @@
     if not project_id:
       raise NotFound(ugettext('Proposal id must be a positive number'))
 
-    self.data.project = GSoCProject.get_by_id(
+    self.data.project = project_model.GSoCProject.get_by_id(
         project_id, parent=self.data.url_profile)
 
     if not self.data.project:
@@ -541,6 +541,77 @@
     elif status == 'withdrawn':
       self.data.is_pending = False
 
+  def canStudentUpdateProject(self):
+    """Checks if the student can edit the project details."""
+    assert access_checker.isSet(self.data.program)
+    assert access_checker.isSet(self.data.timeline)
+    assert access_checker.isSet(self.data.project)
+    assert access_checker.isSet(self.data.project_owner)
+
+    self.isProjectInURLValid()
+
+    # check if the timeline allows updating project
+    self.isProgramVisible()
+    self.acceptedStudentsAnnounced()
+
+    # check if the current used is an active student
+    self.isActiveStudent()
+
+    # check if the project belongs to the current user
+    expected_profile_key = self.data.project.parent_key()
+    if expected_profile_key != self.data.profile.key():
+      error_msg = access_checker.DEF_ENTITY_DOES_NOT_BELONG_TO_YOU % {
+          'name': 'project'
+          }
+      raise AccessViolation(error_msg)
+
+    # check if the status allows the project to be updated
+    if self.data.project.status in ['invalid', 'withdrawn', 'failed']:
+      raise AccessViolation(access_checker.DEF_CANNOT_UPDATE_ENTITY % {
+          'name': 'project'
+          })
+
+  def canOrgAdminUpdateProject(self):
+    """Checks if the organization admin can edit the project details."""
+    assert access_checker.isSet(self.data.program)
+    assert access_checker.isSet(self.data.timeline)
+    assert access_checker.isSet(self.data.project)
+    assert access_checker.isSet(self.data.project_owner)
+
+    self.isProjectInURLValid()
+
+    # check if the timeline allows updating project
+    self.isProgramVisible()
+    self.acceptedStudentsAnnounced()
+
+    # check if the person is an organization admin for the organization
+    # to which the project was assigned
+    org_key = project_model.GSoCProject.org.get_value_for_datastore(
+        self.data.project)
+    self.isOrgAdminForOrganization(org_key)
+
+    # check if the status allows the project to be updated
+    if self.data.project.status in ['invalid', 'withdrawn', 'failed']:
+      raise AccessViolation(access_checker.DEF_CANNOT_UPDATE_ENTITY % {
+          'name': 'project'
+          })
+
+  def canUpdateProject(self):
+    """Checks if the current user is allowed to update project details."""
+    self.isLoggedIn()
+    if not self.data.is_host:
+      self.hasProfile()
+      if self.data.profile.is_student:
+        # check if this is a student trying to update their project
+        self.canStudentUpdateProject()
+      elif self.data.is_org_admin:
+        # check if this is an organization admin trying to update a project
+        # belonging to one the students working for their organization
+        self.canOrgAdminUpdateProject()
+      else:
+        raise AccessViolation(access_checker.DEF_CANNOT_UPDATE_ENTITY % {
+            'name': 'project'
+        })
 
 class DeveloperAccessChecker(access_checker.DeveloperAccessChecker):
   pass
diff --git a/app/soc/modules/gsoc/views/project_details.py b/app/soc/modules/gsoc/views/project_details.py
index eab45e4..bdecbe9 100644
--- a/app/soc/modules/gsoc/views/project_details.py
+++ b/app/soc/modules/gsoc/views/project_details.py
@@ -25,6 +25,7 @@
 from django.utils.translation import ugettext
 
 from soc.logic import exceptions
+from soc.views.helper import access_checker
 from soc.views.helper import blobstore as bs_helper
 from soc.views.helper.access_checker import isSet
 from soc.views.template import Template
@@ -184,10 +185,8 @@
 
   def checkAccess(self, data, check, mutator):
     """Access checks for GSoC project details page."""
-    check.isLoggedIn()
-    check.isActiveStudent()
     mutator.projectFromKwargs()
-    check.canStudentUpdateProject()
+    check.canUpdateProject()
 
   def context(self, data, check, mutator):
     """Handler to for GSoC project details page HTTP get request."""
@@ -240,11 +239,9 @@
     ]
 
   def checkAccess(self, data, check, mutator):
-    check.isLoggedIn()
-    check.isActiveStudent()
     mutator.projectFromKwargs()
-    check.canStudentUpdateProject()
     check.isProjectCompleted()
+    check.canUpdateProject()
 
   def post(self, data, check, mutator):
     """Post handler for the code sample upload file."""
@@ -328,8 +325,8 @@
 
   def checkAccess(self, data, check, mutator):
     mutator.projectFromKwargs()
-    check.canStudentUpdateProject()
     check.isProjectCompleted()
+    check.canUpdateProject()
 
   def post(self, data, check, mutator):
     """Get handler for the code sample delete file."""
@@ -412,6 +409,54 @@
     return "v2/modules/gsoc/project_details/_user_action.html"
 
 
+def _isUpdateLinkVisible(data):
+  """Determines whether the current user is allowed to update the project
+  and therefore if the project update link should visible or not.
+
+  Args:
+    data: a RequestData object
+
+  Returns: True if the update link should be visible, False otherwise.
+  """
+  # program hosts are able to edit project details
+  if data.is_host:
+    return True
+
+  # users without active profiles cannot definitely update projects
+  if not data.profile or data.profile.status != 'active':
+    return False
+
+  # only passed and valid project can be updated
+  if data.project.status in ['invalid', 'withdrawn', 'failed']:
+    return False
+
+  # a student who own the project can update it
+  if data.project.parent_key() == data.profile.key():
+    return True
+
+  # org admins of the organization that manages the project can update it
+  org_key = GSoCProject.org.get_value_for_datastore(data.project)
+  if data.orgAdminFor(org_key):
+    return True
+
+  # no other users are permitted to update project
+  return False
+
+
+def _getUpdateLinkText(data):
+  """Returns text which may be used to display update project link.
+
+  Args:
+    request: a RequestData object
+
+  Returns: a string with the text to be used with update project link 
+  """
+  if data.timeline.afterFormSubmissionStart():
+    return 'Update or Upload Code Samples'
+  else:
+    return 'Update'
+
+
 class ProjectDetails(GSoCRequestHandler):
   """Encapsulate all the methods required to generate GSoC project
   details page.
@@ -446,11 +491,13 @@
     if data.orgAdminFor(data.project.org):
       context['user_actions'] = UserActions(data)
 
-    user_is_owner = data.user and \
-        (data.user.key() == data.project_owner.parent_key())
-    if user_is_owner:
-      context['update_link'] = data.redirect.project().urlOf(
+    if _isUpdateLinkVisible(data):
+      context['update_link_visible'] = True
+      context['update_link_url'] = data.redirect.project().urlOf(
           url_names.GSOC_PROJECT_UPDATE)
+      context['update_link_text'] = _getUpdateLinkText(data)
+    else:
+      context['update_link_visible'] = False
 
     if len(data.project.passed_evaluations) >= \
         project_logic.NUMBER_OF_EVALUATIONS:
diff --git a/app/soc/modules/gsoc/views/projects_list.py b/app/soc/modules/gsoc/views/projects_list.py
index 92203c8..8f276a1 100644
--- a/app/soc/modules/gsoc/views/projects_list.py
+++ b/app/soc/modules/gsoc/views/projects_list.py
@@ -32,7 +32,9 @@
 class ProjectList(Template):
   """Template for listing the student projects accepted in the program."""
 
-  def __init__(self, data, query, idx=0):
+  DEFAULT_IDX = 0
+
+  def __init__(self, data, query, idx=None):
     """Initializes a new object.
 
     Args:
@@ -42,7 +44,8 @@
     """
     self.data = data
     self.query = query
-    self.idx = idx
+
+    self.idx = self.DEFAULT_IDX if idx is None else idx
 
     r = data.redirect
     list_config = lists.ListConfiguration(add_key_column=False)
diff --git a/app/soc/templates/v2/modules/gsoc/homepage/base.html b/app/soc/templates/v2/modules/gsoc/homepage/base.html
index ba1260a..ce14085 100644
--- a/app/soc/templates/v2/modules/gsoc/homepage/base.html
+++ b/app/soc/templates/v2/modules/gsoc/homepage/base.html
@@ -21,7 +21,7 @@
   <h2 id="title-section-how-it-works">How Google Summer of Code Works</h2>
     <ol id="list-how-it-works">
       <li id="how-it-works-item1" class="first">
-        <strong>Propose a project <span>for approval by a participating open source organization</span></strong>
+        <strong>Propose a project <span>for approval by a mentoring open source organization</span></strong>
       </li>
       <li id="how-it-works-item2" class="second">
         <strong>Code the summer away</strong>
diff --git a/app/soc/templates/v2/modules/gsoc/project_details/base.html b/app/soc/templates/v2/modules/gsoc/project_details/base.html
index 6558374..bcabe0f 100644
--- a/app/soc/templates/v2/modules/gsoc/project_details/base.html
+++ b/app/soc/templates/v2/modules/gsoc/project_details/base.html
@@ -37,8 +37,8 @@
   </h3>
 
   <div id="edit-page" class="org-page-link">
-    {% if update_link %}
-      <a href="{{ update_link }}">Update</a>
+    {% if update_link_visible %}
+      <a href="{{ update_link_url }}">{{ update_link_text }}</a>
     {% endif %}
   </div>
 </div>
diff --git a/app/soc/views/base_templates.py b/app/soc/views/base_templates.py
index 665f89e..6d0f332 100644
--- a/app/soc/views/base_templates.py
+++ b/app/soc/views/base_templates.py
@@ -44,7 +44,7 @@
       context['user_email'] = self.data.gae_user.email()
 
     if self.data.user:
-      context['link_id'] = " [link_id: %s]" % self.data.user.link_id
+      context['link_id'] = " [username: %s]" % self.data.user.link_id
 
     if self.apply_link and self.data.timeline.studentSignup() and \
         self.data.student_info:
diff --git a/app/soc/views/helper/access_checker.py b/app/soc/views/helper/access_checker.py
index a698113..304bd04 100644
--- a/app/soc/views/helper/access_checker.py
+++ b/app/soc/views/helper/access_checker.py
@@ -1090,34 +1090,6 @@
           }
       raise AccessViolation(error_msg)
 
-  def canStudentUpdateProject(self):
-    """Checks if the student can edit the project details.
-    """
-    assert isSet(self.data.program)
-    assert isSet(self.data.timeline)
-    assert isSet(self.data.project)
-    assert isSet(self.data.project_owner)
-
-    self.isProjectInURLValid()
-
-    # check if the timeline allows updating project
-    self.isProgramVisible()
-    self.acceptedStudentsAnnounced()
-
-    # check if the project belongs to the current user
-    expected_profile_key = self.data.project.parent_key()
-    if expected_profile_key != self.data.profile.key():
-      error_msg = DEF_ENTITY_DOES_NOT_BELONG_TO_YOU % {
-          'name': 'project'
-          }
-      raise AccessViolation(error_msg)
-
-    # check if the status allows the project to be updated
-    if self.data.project.status in ['invalid', 'withdrawn', 'failed']:
-      raise AccessViolation(DEF_CANNOT_UPDATE_ENTITY % {
-          'name': 'project'
-          })
-
   def isSurveyActive(self, survey, show_url=None):
     """Checks if the survey in the request data is active.
 
diff --git a/app/soc/views/profile.py b/app/soc/views/profile.py
index 3405290..8586179 100644
--- a/app/soc/views/profile.py
+++ b/app/soc/views/profile.py
@@ -291,7 +291,7 @@
     return notification_form
 
   def validateStudent(self, data, dirty, profile):
-    if not data.student_info or data.kwargs.get('role') == 'student':
+    if not (data.student_info or data.kwargs.get('role') == 'student'):
       return EmptyForm(data.POST)
 
     student_form = self._getStudentInfoForm(data)
diff --git a/buildout.cfg b/buildout.cfg
index 8007272..2dbd4fd 100644
--- a/buildout.cfg
+++ b/buildout.cfg
@@ -2,6 +2,9 @@
 parts =
     python
     omelette
+    nodejs
+    node_modules_sym
+    jasmine_node_sym
 develop =
     .
     thirdparty/google_appengine/lib/yaml
@@ -50,3 +53,21 @@
 packages =
     ${buildout:directory}/app ./app
     ${buildout:directory}/thirdparty/google_appengine/google ./google
+
+[nodejs]
+recipe = gp.recipe.node
+url = http://nodejs.org/dist/v0.8.14/node-v0.8.14.tar.gz
+npms = jasmine-node testem phantomjs
+scripts = npm
+
+[node_modules_sym]
+recipe = cns.recipe.symlink
+symlink_base = ${buildout:directory}/parts/nodejs/lib/node_modules
+symlink_target = ${buildout:directory}/node_modules
+autocreate = true
+
+[jasmine_node_sym]
+recipe = cns.recipe.symlink
+symlink_base = ${buildout:directory}/parts/node-v0.8.14/bin
+symlink_target = ${buildout:directory}/bin
+autocreate = true
diff --git a/scripts/stats.py b/scripts/stats.py
index f8bd6f2..d4d7a7a 100755
--- a/scripts/stats.py
+++ b/scripts/stats.py
@@ -754,7 +754,7 @@
     super(StudentKeyRequest, self).__init__(post=dict(student_key=key))
 
 
-def main(args):
+def main():
   """Main routine.
   """
 
@@ -860,11 +860,11 @@
       'turnaroundTime': turnaroundTime,
   }
 
-  interactive.remote(args, context)
+  interactive.remote(sys.argv[1:], context)
 
 if __name__ == '__main__':
   if len(sys.argv) < 2:
     print "Usage: %s app_id [host]" % (sys.argv[0],)
     sys.exit(1)
 
-  main(sys.argv[1:])
+  main()
diff --git a/setup.py b/setup.py
index 2a811ba..3618e73 100644
--- a/setup.py
+++ b/setup.py
@@ -34,6 +34,7 @@
         ],
     entry_points = {'console_scripts': ['run-tests = tests.run:main',
                                         'gen-app-yaml = scripts.gen_app_yaml:main',
+                                        'stats = scripts.stats:main'
                                         ],
                     },
     include_package_data = True,
diff --git a/testem.json b/testem.json
new file mode 100644
index 0000000..be74e2b
--- /dev/null
+++ b/testem.json
@@ -0,0 +1,8 @@
+{
+  "framework":"jasmine",
+  "src_files": [
+    "app/jquery/jquery-1.6.4.js",
+    "tests/app/soc/content/js/jasmine-jquery-1.3.1.js",
+    "tests/app/soc/content/js/*_spec.js"
+  ]
+}
diff --git a/tests/app/soc/content/js/all_tests.js b/tests/app/soc/content/js/all_tests.js
new file mode 100644
index 0000000..d0f0edf
--- /dev/null
+++ b/tests/app/soc/content/js/all_tests.js
@@ -0,0 +1,2 @@
+jasmine.getFixtures().fixturesPath = '../js';
+loadFixtures('melange_fixture.html');
\ No newline at end of file
diff --git a/tests/app/soc/content/js/jasmine-jquery-1.3.1.js b/tests/app/soc/content/js/jasmine-jquery-1.3.1.js
new file mode 100644
index 0000000..7e85548
--- /dev/null
+++ b/tests/app/soc/content/js/jasmine-jquery-1.3.1.js
@@ -0,0 +1,288 @@
+var readFixtures = function() {
+  return jasmine.getFixtures().proxyCallTo_('read', arguments);
+};
+
+var preloadFixtures = function() {
+  jasmine.getFixtures().proxyCallTo_('preload', arguments);
+};
+
+var loadFixtures = function() {
+  jasmine.getFixtures().proxyCallTo_('load', arguments);
+};
+
+var setFixtures = function(html) {
+  jasmine.getFixtures().set(html);
+};
+
+var sandbox = function(attributes) {
+  return jasmine.getFixtures().sandbox(attributes);
+};
+
+var spyOnEvent = function(selector, eventName) {
+  jasmine.JQuery.events.spyOn(selector, eventName);
+}
+
+jasmine.getFixtures = function() {
+  return jasmine.currentFixtures_ = jasmine.currentFixtures_ || new jasmine.Fixtures();
+};
+
+jasmine.Fixtures = function() {
+  this.containerId = 'jasmine-fixtures';
+  this.fixturesCache_ = {};
+  this.fixturesPath = 'spec/javascripts/fixtures';
+};
+
+jasmine.Fixtures.prototype.set = function(html) {
+  this.cleanUp();
+  this.createContainer_(html);
+};
+
+jasmine.Fixtures.prototype.preload = function() {
+  this.read.apply(this, arguments);
+};
+
+jasmine.Fixtures.prototype.load = function() {
+  this.cleanUp();
+  this.createContainer_(this.read.apply(this, arguments));
+};
+
+jasmine.Fixtures.prototype.read = function() {
+  var htmlChunks = [];
+
+  var fixtureUrls = arguments;
+  for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) {
+    htmlChunks.push(this.getFixtureHtml_(fixtureUrls[urlIndex]));
+  }
+
+  return htmlChunks.join('');
+};
+
+jasmine.Fixtures.prototype.clearCache = function() {
+  this.fixturesCache_ = {};
+};
+
+jasmine.Fixtures.prototype.cleanUp = function() {
+  jQuery('#' + this.containerId).remove();
+};
+
+jasmine.Fixtures.prototype.sandbox = function(attributes) {
+  var attributesToSet = attributes || {};
+  return jQuery('<div id="sandbox" />').attr(attributesToSet);
+};
+
+jasmine.Fixtures.prototype.createContainer_ = function(html) {
+  var container;
+  if(html instanceof jQuery) {
+    container = jQuery('<div id="' + this.containerId + '" />');
+    container.html(html);
+  } else {
+    container = '<div id="' + this.containerId + '">' + html + '</div>'
+  }
+  jQuery('body').append(container);
+};
+
+jasmine.Fixtures.prototype.getFixtureHtml_ = function(url) {  
+  if (typeof this.fixturesCache_[url] == 'undefined') {
+    this.loadFixtureIntoCache_(url);
+  }
+  return this.fixturesCache_[url];
+};
+
+jasmine.Fixtures.prototype.loadFixtureIntoCache_ = function(relativeUrl) {
+  var self = this;
+  var url = this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl;
+  jQuery.ajax({
+    async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded
+    cache: false,
+    dataType: 'html',
+    url: url,
+    success: function(data) {
+      self.fixturesCache_[relativeUrl] = data;
+    },
+    error: function(jqXHR, status, errorThrown) {
+        throw Error('Fixture could not be loaded: ' + url + ' (status: ' + status + ', message: ' + errorThrown.message + ')');
+    }
+  });
+};
+
+jasmine.Fixtures.prototype.proxyCallTo_ = function(methodName, passedArguments) {
+  return this[methodName].apply(this, passedArguments);
+};
+
+
+jasmine.JQuery = function() {};
+
+jasmine.JQuery.browserTagCaseIndependentHtml = function(html) {
+  return jQuery('<div/>').append(html).html();
+};
+
+jasmine.JQuery.elementToString = function(element) {
+  return jQuery('<div />').append(element.clone()).html();
+};
+
+jasmine.JQuery.matchersClass = {};
+
+(function(namespace) {
+  var data = {
+    spiedEvents: {},
+    handlers:    []
+  };
+
+  namespace.events = {
+    spyOn: function(selector, eventName) {
+      var handler = function(e) {
+        data.spiedEvents[[selector, eventName]] = e;
+      };
+      jQuery(selector).bind(eventName, handler);
+      data.handlers.push(handler);
+    },
+
+    wasTriggered: function(selector, eventName) {
+      return !!(data.spiedEvents[[selector, eventName]]);
+    },
+
+    cleanUp: function() {
+      data.spiedEvents = {};
+      data.handlers    = [];
+    }
+  }
+})(jasmine.JQuery);
+
+(function(){
+  var jQueryMatchers = {
+    toHaveClass: function(className) {
+      return this.actual.hasClass(className);
+    },
+
+    toBeVisible: function() {
+      return this.actual.is(':visible');
+    },
+
+    toBeHidden: function() {
+      return this.actual.is(':hidden');
+    },
+
+    toBeSelected: function() {
+      return this.actual.is(':selected');
+    },
+
+    toBeChecked: function() {
+      return this.actual.is(':checked');
+    },
+
+    toBeEmpty: function() {
+      return this.actual.is(':empty');
+    },
+
+    toExist: function() {
+      return this.actual.size() > 0;
+    },
+
+    toHaveAttr: function(attributeName, expectedAttributeValue) {
+      return hasProperty(this.actual.attr(attributeName), expectedAttributeValue);
+    },
+
+    toHaveId: function(id) {
+      return this.actual.attr('id') == id;
+    },
+
+    toHaveHtml: function(html) {
+      return this.actual.html() == jasmine.JQuery.browserTagCaseIndependentHtml(html);
+    },
+
+    toHaveText: function(text) {
+      if (text && jQuery.isFunction(text.test)) {
+        return text.test(this.actual.text());
+      } else {
+        return this.actual.text() == text;
+      }
+    },
+
+    toHaveValue: function(value) {
+      return this.actual.val() == value;
+    },
+
+    toHaveData: function(key, expectedValue) {
+      return hasProperty(this.actual.data(key), expectedValue);
+    },
+
+    toBe: function(selector) {
+      return this.actual.is(selector);
+    },
+
+    toContain: function(selector) {
+      return this.actual.find(selector).size() > 0;
+    },
+
+    toBeDisabled: function(selector){
+      return this.actual.is(':disabled');
+    },
+
+    // tests the existence of a specific event binding
+    toHandle: function(eventName) {
+      var events = this.actual.data("events");
+      return events && events[eventName].length > 0;
+    },
+    
+    // tests the existence of a specific event binding + handler
+    toHandleWith: function(eventName, eventHandler) {
+      var stack = this.actual.data("events")[eventName];
+      var i;
+      for (i = 0; i < stack.length; i++) {
+        if (stack[i].handler == eventHandler) {
+          return true;
+        }
+      }
+      return false;
+    }
+  };
+
+  var hasProperty = function(actualValue, expectedValue) {
+    if (expectedValue === undefined) {
+      return actualValue !== undefined;
+    }
+    return actualValue == expectedValue;
+  };
+
+  var bindMatcher = function(methodName) {
+    var builtInMatcher = jasmine.Matchers.prototype[methodName];
+
+    jasmine.JQuery.matchersClass[methodName] = function() {
+      if (this.actual instanceof jQuery) {
+        var result = jQueryMatchers[methodName].apply(this, arguments);
+        this.actual = jasmine.JQuery.elementToString(this.actual);
+        return result;
+      }
+
+      if (builtInMatcher) {
+        return builtInMatcher.apply(this, arguments);
+      }
+
+      return false;
+    };
+  };
+
+  for(var methodName in jQueryMatchers) {
+    bindMatcher(methodName);
+  }
+})();
+
+beforeEach(function() {
+  this.addMatchers(jasmine.JQuery.matchersClass);
+  this.addMatchers({
+    toHaveBeenTriggeredOn: function(selector) {
+      this.message = function() {
+        return [
+          "Expected event " + this.actual + " to have been triggered on" + selector,
+          "Expected event " + this.actual + " not to have been triggered on" + selector
+        ];
+      };
+      return jasmine.JQuery.events.wasTriggered(selector, this.actual);
+    }
+  })
+});
+
+afterEach(function() {
+  jasmine.getFixtures().cleanUp();
+  jasmine.JQuery.events.cleanUp();
+});
diff --git a/tests/app/soc/content/js/melange_fixture.html b/tests/app/soc/content/js/melange_fixture.html
new file mode 100644
index 0000000..52b806a
--- /dev/null
+++ b/tests/app/soc/content/js/melange_fixture.html
@@ -0,0 +1,10 @@
+<html>
+  <head>
+    <script type="text/javascript" src="./app/json/json2.js"></script>
+    <script type="text/javascript" src="./app/jquery/jquery-cookie.js"></script>
+    <script type="text/javascript" src="./app/soc/content/js/melange.js"></script>
+    <script type="text/javascript">window.melange = {};</script>
+  </head>
+  <body>
+  </body>
+</html>
diff --git a/tests/app/soc/content/js/melange_spec.js b/tests/app/soc/content/js/melange_spec.js
new file mode 100644
index 0000000..e98bb83
--- /dev/null
+++ b/tests/app/soc/content/js/melange_spec.js
@@ -0,0 +1,9 @@
+describe('melange', function() {
+   beforeEach(function() {
+     jasmine.getFixtures().fixturesPath = 'tests/app/soc/content/js';
+     loadFixtures('melange_fixture.html');
+   });
+   it('should be defined', function(){
+      expect(melange).toBeDefined();
+   });
+});
\ No newline at end of file
diff --git a/tests/app/soc/modules/gsoc/views/test_profile.py b/tests/app/soc/modules/gsoc/views/test_profile.py
index 8d29416..dab090c 100644
--- a/tests/app/soc/modules/gsoc/views/test_profile.py
+++ b/tests/app/soc/modules/gsoc/views/test_profile.py
@@ -168,11 +168,18 @@
     })
 
     response = self.post(role_url, postdata)
-
     self.assertResponseRedirect(response, url + '?validated')
 
     # hacky
     profile = GSoCProfile.all().get()
+
+    self.assertEqual(postdata.get('given_name'), profile.given_name)
+    self.assertEqual(postdata.get('surname'), profile.surname)
+
+    # Make sure student info entity is created with right values.
+    self.assertEqual(postdata.get('school_name'),
+                      profile.student_info.school_name)
+
     profile.delete()
 
     postdata.update({
diff --git a/tests/app/soc/modules/gsoc/views/test_project_details.py b/tests/app/soc/modules/gsoc/views/test_project_details.py
index 43d83f5..f318321 100644
--- a/tests/app/soc/modules/gsoc/views/test_project_details.py
+++ b/tests/app/soc/modules/gsoc/views/test_project_details.py
@@ -12,16 +12,75 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Tests for project_detail views.
-"""
+"""Tests for project_detail views."""
+
+from tests import profile_utils
+from tests import program_utils
+from tests import test_utils
+
+from soc.modules.gsoc.models import project as project_model
+from soc.modules.gsoc.views import project_details
 
 
-from tests.profile_utils import GSoCProfileHelper
-from tests.test_utils import GSoCDjangoTestCase
+def _createProjectForStudent(program, org, dev_test, student=None):
+  """Returns a newly created GSoCProject for the specified student.
+  If a new student instance is not provided, a new profile is created.
 
-from soc.modules.gsoc.models.project import GSoCProject
+  Args:
+    program: GSoCProgram instance for which the project is to be created
+    org: GSoCOrganization instance for which the project is to be created
+    dev_test: whether it is dev test environment
+    student: the specified GSoCProfile student instance to mentor the project
 
-class ProjectDetailsTest(GSoCDjangoTestCase):
+  Returns:
+    the newly created GSoCProject instance
+  """
+  if not student:
+    student_helper = profile_utils.GSoCProfileHelper(program, dev_test)
+    student_helper.createOtherUser('student@example.com')
+    student = student_helper.createStudent()
+
+  mentor_helper = profile_utils.GSoCProfileHelper(program, dev_test)
+  mentor_helper.createOtherUser('mentor@example.com')
+  mentor_helper.createMentorWithProject(org, student)
+
+  project = project_model.GSoCProject.all().get()
+  project.is_featured = False
+  project.status = 'accepted'
+  project.put()
+
+  return project
+
+
+def _createProjectForMentor(program, org, dev_test, mentor=None):
+  """Returns a newly created GSoCProject for the specified mentor.
+  If a new mentor instance is not provided, a new profile is created.
+
+  Args:
+    program: GSoCProgram instance for which the project is to be created
+    org: GSoCOrganization instance for which the project is to be created
+    dev_test: whether it is dev test environment
+    mentor: the specified GSoCProfile mentor instance to mentor the project
+
+  Returns:
+    the newly created GSoCProject instance
+  """
+  if not mentor:
+    mentor_helper = profile_utils.GSoCProfileHelper(program, dev_test)
+    mentor_helper.createOtherUser('mentor@example.com')
+    mentor = mentor_helper.createMentor(org)
+
+  student_helper = profile_utils.GSoCProfileHelper(program, dev_test)
+  student_helper.createOtherUser('student@example.com')
+  student_helper.createStudentWithProject(org, mentor)
+  project = project_model.GSoCProject.all().get()
+  project.is_featured = False
+  project.status = 'accepted'
+  project.put()
+  return project
+
+
+class ProjectDetailsTest(test_utils.GSoCDjangoTestCase):
   """Tests project details page.
   """
 
@@ -37,14 +96,14 @@
         response, 'v2/modules/gsoc/project_details/base.html')
 
   def createProject(self):
-    mentor_helper = GSoCProfileHelper(self.gsoc, self.dev_test)
+    mentor_helper = profile_utils.GSoCProfileHelper(self.gsoc, self.dev_test)
     mentor_helper.createOtherUser('mentor@example.com')
     mentor = mentor_helper.createMentor(self.org)
-    student_helper = GSoCProfileHelper(self.gsoc, self.dev_test)
+    student_helper = profile_utils.GSoCProfileHelper(self.gsoc, self.dev_test)
     student_helper.createOtherUser('student@example.com')
     student_helper.createStudentWithProject(self.org, mentor)
-    print GSoCProject.all().fetch(100)
-    project = GSoCProject.all().get()
+
+    project = project_model.GSoCProject.all().get()
     project.is_featured = False
     project.status = 'accepted'
     project.put()
@@ -69,7 +128,7 @@
   def testFeaturedProjectButton(self):
     self.timeline.studentsAnnounced()
 
-    student = GSoCProfileHelper(self.gsoc, self.dev_test)
+    student = profile_utils.GSoCProfileHelper(self.gsoc, self.dev_test)
     student.createOtherUser('student@example.com')
     student.createStudent()
 
@@ -88,5 +147,176 @@
 
     self.assertResponseOK(response)
 
-    project = GSoCProject.all().get()
+    project = project_model.GSoCProject.all().get()
     self.assertEqual(project.is_featured, True)
+
+
+class ProjectDetailsUpdateTest(test_utils.GSoCDjangoTestCase):
+  """Unit tests project details update page."""
+
+  def setUp(self):
+    super(ProjectDetailsUpdateTest, self).setUp()
+    self.init()
+
+  def _getProjectUpdateUrl(self, project):
+    return '/gsoc/project/update/%s/%s' % (
+        project.parent_key().name(), project.key().id())
+
+  def testLoneUserAccessForbidden(self):
+    self.timeline.studentsAnnounced()
+    project = _createProjectForMentor(self.gsoc, self.org, self.dev_test)
+
+    url = self._getProjectUpdateUrl(project)
+    response = self.get(url)
+    self.assertErrorTemplatesUsed(response)
+    self.assertResponseForbidden(response)
+
+  def testMentorAccessForbidden(self):
+    self.timeline.studentsAnnounced()
+
+    mentor = self.data.createMentor(self.org)
+    project = _createProjectForMentor(
+        self.gsoc, self.org, self.dev_test, mentor=mentor)
+
+    url = self._getProjectUpdateUrl(project)
+    response = self.get(url)
+    self.assertErrorTemplatesUsed(response)
+    self.assertResponseForbidden(response)
+
+  def testOrgAdminAccessGranted(self):
+    self.timeline.studentsAnnounced()
+
+    self.data.createOrgAdmin(self.org)
+    project = _createProjectForMentor(self.gsoc, self.org, self.dev_test)
+
+    url = self._getProjectUpdateUrl(project)
+    response = self.get(url)
+    self.assertResponseOK(response)
+
+  def testOrgAdminForAnotherOrgForbidden(self):
+    self.timeline.studentsAnnounced()
+
+    another_org = self.createOrg()
+    self.data.createOrgAdmin(another_org)
+    project = _createProjectForMentor(self.gsoc, self.org, self.dev_test)
+
+    url = self._getProjectUpdateUrl(project)
+    response = self.get(url)
+    self.assertErrorTemplatesUsed(response)
+    self.assertResponseForbidden(response)
+
+  def testHostAccessGranted(self):
+    self.timeline.studentsAnnounced()
+
+    self.data.createHost()
+    project = _createProjectForMentor(self.gsoc, self.org, self.dev_test)
+
+    url = self._getProjectUpdateUrl(project)
+    response = self.get(url)
+    self.assertResponseOK(response)
+
+  def testStudentAccessTheirProjectGranted(self):
+    self.timeline.studentsAnnounced()
+
+    student = self.data.createStudent()
+    project = _createProjectForStudent(
+        self.gsoc, self.org, self.dev_test, student=student)
+
+    url = self._getProjectUpdateUrl(project)
+    response = self.get(url)
+    self.assertResponseOK(response)
+
+  def testStudentAccessOtherProjectForbidden(self):
+    self.timeline.studentsAnnounced()
+
+    student = self.data.createStudent()
+    project = _createProjectForStudent(self.gsoc, self.org, self.dev_test)
+
+    url = self._getProjectUpdateUrl(project)
+    response = self.get(url)
+    self.assertErrorTemplatesUsed(response)
+    self.assertResponseForbidden(response)
+
+
+class TestIsUpdateLinkVisible(test_utils.GSoCTestCase):
+  """Unit tests for _isUpdateLinkVisible function."""
+
+  def setUp(self):
+    super(TestIsUpdateLinkVisible, self).setUp()
+    self.init()
+
+  class MockRequestData(object):
+    """Mock class used to simulate RequestData which is passed as argument."""
+
+    def __init__(self, is_host=False, project=None, profile=None):
+      self.is_host = is_host
+      self.project = project
+      self.profile = profile
+
+    def orgAdminFor(self, org_key):
+      return org_key in self.profile.org_admin_for
+
+  def testForHost(self):
+    request_data = TestIsUpdateLinkVisible.MockRequestData(is_host=True)
+    result = project_details._isUpdateLinkVisible(request_data)
+    self.assertTrue(request_data)
+
+  def testForProjectStudent(self):
+    student = self.data.createStudent()
+    project = _createProjectForStudent(
+        self.gsoc, self.org, self.dev_test, student=student)
+
+    request_data = TestIsUpdateLinkVisible.MockRequestData(
+        project=project, profile=student)
+    self.assertTrue(project_details._isUpdateLinkVisible(request_data))
+
+  def testForOtherStudent(self):
+    student = self.data.createStudent()
+    project = _createProjectForStudent(self.gsoc, self.org, self.dev_test)
+
+    request_data = TestIsUpdateLinkVisible.MockRequestData(
+        project=project, profile=student)
+    self.assertFalse(project_details._isUpdateLinkVisible(request_data))
+
+  def testForProjectMentor(self):
+    mentor = self.data.createMentor(self.org)
+    project = _createProjectForMentor(
+        self.gsoc, self.org, self.dev_test, mentor=mentor)
+
+    request_data = TestIsUpdateLinkVisible.MockRequestData(
+        project=project, profile=mentor)
+    self.assertFalse(project_details._isUpdateLinkVisible(request_data))
+
+  def testForOtherMentor(self):
+    mentor = self.data.createMentor(self.org)
+    project = _createProjectForMentor(self.gsoc, self.org, self.dev_test)
+
+    request_data = TestIsUpdateLinkVisible.MockRequestData(
+        project=project, profile=mentor)
+    self.assertFalse(project_details._isUpdateLinkVisible(request_data))
+
+  def testForProjectOrgAdmin(self):
+    org_admin = self.data.createOrgAdmin(self.org)
+    project = _createProjectForMentor(self.gsoc, self.org, self.dev_test)
+
+    request_data = TestIsUpdateLinkVisible.MockRequestData(
+        project=project, profile=org_admin)
+    self.assertTrue(project_details._isUpdateLinkVisible(request_data))
+
+  def testForOtherOrgAdmin(self):
+    program_helper = program_utils.GSoCProgramHelper()
+    another_org = program_helper.createOrg()
+    org_admin = self.data.createOrgAdmin(self.org)
+    project = _createProjectForMentor(self.gsoc, another_org, self.dev_test)
+
+    request_data = TestIsUpdateLinkVisible.MockRequestData(
+        project=project, profile=org_admin)
+    self.assertFalse(project_details._isUpdateLinkVisible(request_data))
+
+  def testForLoneUser(self):
+    self.data.createUser()
+    project = _createProjectForMentor(self.gsoc, self.org, self.dev_test)
+
+    request_data = TestIsUpdateLinkVisible.MockRequestData(
+        project=project)
+    self.assertFalse(project_details._isUpdateLinkVisible(request_data))
diff --git a/tests/app/soc/views/test_org_app.py b/tests/app/soc/views/test_org_app.py
index 1dbb1db..2c58a34 100644
--- a/tests/app/soc/views/test_org_app.py
+++ b/tests/app/soc/views/test_org_app.py
@@ -135,7 +135,7 @@
         'agreed_to_admin_agreement': True,
         'backup_admin_id': backup_admin_profile.link_id,
         }
-    
+
   def testOrgAppCreateOrEditByProgramAdmin(self):
     """Tests that program admin can create an organization application.
     """
diff --git a/tests/run.py b/tests/run.py
index f21a008..6ca3b14 100644
--- a/tests/run.py
+++ b/tests/run.py
@@ -16,6 +16,7 @@
 
 import sys
 import os
+import subprocess
 
 HERE = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                      '..'))
@@ -252,8 +253,7 @@
       break
   log.debug("Worker %s ending", ix)
 
-
-def main():
+def run_pyunit_tests():
   sys.path = extra_paths + sys.path
   os.environ['SERVER_SOFTWARE'] = 'Development via nose'
   os.environ['SERVER_NAME'] = 'Foo'
@@ -310,6 +310,24 @@
   sys.argv += args
   nose.main(addplugins=plugins)
 
+def run_js_tests():
+  _environ = os.environ.copy()
+  _environ["PATH"] += ':./node_modules/phantomjs/lib/phantom/bin'
+  subprocess.call("./bin/node ./node_modules/testem/testem.js ci", env=_environ, shell=True)
+
+def main():
+  tests = set()
+  if '-t' in sys.argv:
+    i = sys.argv.index('-t')
+    tests.update(sys.argv[i+1].split(','))
+    del sys.argv[i:i+2]
+  else:
+    tests = {'js', 'pyunit'}
+
+  if 'pyunit' in tests:
+    run_pyunit_tests()
+  if 'js' in tests:
+    run_js_tests()
 
 if __name__ == '__main__':
   main()
diff --git a/thirdparty/chromium/LICENSE b/thirdparty/chromium/LICENSE
deleted file mode 100644
index 9314092..0000000
--- a/thirdparty/chromium/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/thirdparty/chromium/gcl.py b/thirdparty/chromium/gcl.py
deleted file mode 100755
index 5adbb51..0000000
--- a/thirdparty/chromium/gcl.py
+++ /dev/null
@@ -1,676 +0,0 @@
-#!/usr/bin/python
-# Wrapper script around Rietveld's upload.py that groups files into
-# changelists.
-
-import getpass
-import linecache
-import os
-import random
-import re
-import string
-import subprocess
-import sys
-import tempfile
-import upload
-import urllib2
-
-CODEREVIEW_SETTINGS = {
-  # Default values.
-  "CODE_REVIEW_SERVER": "codereviews.googleopensourceprograms.com",
-  "CC_LIST": "melange-soc-dev@googlegroups.com",
-  "VIEW_VC": "http://code.google.com/p/soc/source/detail?r=",
-}
-
-# Use a shell for subcommands on Windows to get a PATH search, and because svn
-# may be a batch file.
-use_shell = sys.platform.startswith("win")
-
-
-# globals that store the root of the current repositary and the directory where
-# we store information about changelists.
-repository_root = ""
-gcl_info_dir = ""
-
-
-def GetSVNFileInfo(file, field):
-  """Returns a field from the svn info output for the given file."""
-  output = RunShell(["svn", "info", file])
-  for line in output.splitlines():
-    search = field + ": "
-    if line.startswith(search):
-      return line[len(search):]
-  return ""
-
-
-def GetRepositoryRoot():
-  """Returns the top level directory of the current repository."""
-  global repository_root
-  if not repository_root:
-    cur_dir_repo_root = GetSVNFileInfo(os.getcwd(), "Repository Root")
-    if not cur_dir_repo_root:
-      ErrorExit("gcl run outside of repository")
-
-    repository_root = os.getcwd()
-    while True:
-      parent = os.path.dirname(repository_root)
-      if GetSVNFileInfo(parent, "Repository Root") != cur_dir_repo_root:
-        break
-      repository_root = parent
-  # Now read the code review settings for this repository.
-  settings_file = os.path.join(repository_root, "codereview.settings")
-  if os.path.exists(settings_file):
-    output = ReadFile(settings_file)
-    for line in output.splitlines():
-      if not line or line.startswith("#"):
-        continue
-      key, value = line.split(": ", 1)
-      CODEREVIEW_SETTINGS[key] = value
-  return repository_root
-
-
-def GetCodeReviewSetting(key):
-  """Returns a value for the given key for this repository."""
-  return CODEREVIEW_SETTINGS.get(key, "")
-
-
-def GetInfoDir():
-  """Returns the directory where gcl info files are stored."""
-  global gcl_info_dir
-  if not gcl_info_dir:
-    gcl_info_dir = os.path.join(GetRepositoryRoot(), '.svn', 'gcl_info')
-  return gcl_info_dir
-
-
-def ErrorExit(msg):
-  """Print an error message to stderr and exit."""
-  print >>sys.stderr, msg
-  sys.exit(1)
-
-
-def RunShell(command, print_output=False):
-  """Executes a command and returns the output."""
-  p = subprocess.Popen(command, stdout = subprocess.PIPE,
-                       stderr = subprocess.STDOUT, shell = use_shell,
-                       universal_newlines=True)
-  if print_output:
-    output_array = []
-    while True:
-      line = p.stdout.readline()
-      if not line:
-        break
-      if print_output:
-        print line.strip('\n')
-      output_array.append(line)
-    output = "".join(output_array)
-  else:
-    output = p.stdout.read()
-  p.wait()
-  p.stdout.close()
-  return output
-
-
-def ReadFile(filename):
-  """Returns the contents of a file."""
-  file = open(filename, 'r')
-  result = file.read()
-  file.close()
-  return result
-
-
-def WriteFile(filename, contents):
-  """Overwrites the file with the given contents."""
-  file = open(filename, 'w')
-  file.write(contents)
-  file.close()
-
-
-class ChangeInfo:
-  """Holds information about a changelist.
-  
-    issue: the Rietveld issue number, of "" if it hasn't been uploaded yet.
-    description: the description.
-    files: a list of 2 tuple containing (status, filename) of changed files,
-           with paths being relative to the top repository directory.
-  """
-  def __init__(self, name="", issue="", description="", files=[]):
-    self.name = name
-    self.issue = issue
-    self.description = description
-    self.files = files
-
-  def FileList(self):
-    """Returns a list of files."""
-    return [file[1] for file in self.files]
-
-  def Save(self):
-    """Writes the changelist information to disk."""
-    data = SEPARATOR.join([self.issue,
-                          "\n".join([f[0] + f[1] for f in self.files]),
-                          self.description])
-    WriteFile(GetChangelistInfoFile(self.name), data)
-
-  def Delete(self):
-    """Removes the changelist information from disk."""
-    os.remove(GetChangelistInfoFile(self.name))
-
-  def CloseIssue(self):
-    """Closes the Rietveld issue for this changelist."""
-    data = [("description", self.description),]
-    ctype, body = upload.EncodeMultipartFormData(data, [])
-    SendToRietveld("/" + self.issue + "/close", body, ctype)
-
-  def UpdateRietveldDescription(self):
-    """Sets the description for an issue on Rietveld."""
-    data = [("description", self.description),]
-    ctype, body = upload.EncodeMultipartFormData(data, [])
-    SendToRietveld("/" + self.issue + "/description", body, ctype)
-
-  
-SEPARATOR = "\n-----\n"
-# The info files have the following format:
-# issue_id\n
-# SEPARATOR\n
-# filepath1\n
-# filepath2\n
-# .
-# .
-# filepathn\n
-# SEPARATOR\n
-# description
-
-
-def GetChangelistInfoFile(changename):
-  """Returns the file that stores information about a changelist."""
-  if not changename or re.search(r'\W', changename):
-    ErrorExit("Invalid changelist name: " + changename)
-  return os.path.join(GetInfoDir(), changename)
-
-
-def LoadChangelistInfo(changename, fail_on_not_found=True,
-                       update_status=False):
-  """Gets information about a changelist.
-  
-  Args:
-    fail_on_not_found: if True, this function will quit the program if the
-      changelist doesn't exist.
-    update_status: if True, the svn status will be updated for all the files
-      and unchanged files will be removed.
-  
-  Returns: a ChangeInfo object.
-  """
-  info_file = GetChangelistInfoFile(changename)
-  if not os.path.exists(info_file):
-    if fail_on_not_found:
-      ErrorExit("Changelist " + changename + " not found.")
-    return ChangeInfo(changename)
-  data = ReadFile(info_file)
-  split_data = data.split(SEPARATOR, 2)
-  if len(split_data) != 3:
-    os.remove(info_file)
-    ErrorExit("Changelist file %s was corrupt and deleted" % info_file)
-  issue = split_data[0]
-  files = []
-  for line in split_data[1].splitlines():
-    status = line[:7]
-    file = line[7:]
-    files.append((status, file))
-  description = split_data[2]  
-  save = False
-  if update_status:
-    for file in files:
-      filename = os.path.join(GetRepositoryRoot(), file[1])
-      status = RunShell(["svn", "status", filename])[:7]
-      if not status:  # File has been reverted.
-        save = True
-        files.remove(file)
-      elif status != file[0]:
-        save = True
-        files[files.index(file)] = (status, file[1])
-  change_info = ChangeInfo(changename, issue, description, files)
-  if save:
-    change_info.Save()
-  return change_info
-
-
-def GetCLs():
-  """Returns a list of all the changelists in this repository."""
-  return os.listdir(GetInfoDir())
-
-
-def GenerateChangeName():
-  """Generate a random changelist name."""
-  random.seed()
-  current_cl_names = GetCLs()
-  while True:
-    cl_name = (random.choice(string.ascii_lowercase) +
-               random.choice(string.digits) +
-               random.choice(string.ascii_lowercase) +
-               random.choice(string.digits))
-    if cl_name not in current_cl_names:
-      return cl_name
-
-
-def GetModifiedFiles():
-  """Returns a set that maps from changelist name to (status,filename) tuples.
-
-  Files not in a changelist have an empty changelist name.  Filenames are in
-  relation to the top level directory of the current repositary.  Note that
-  only the current directory and subdirectories are scanned, in order to
-  improve performance while still being flexible.
-  """
-  files = {}
-  
-  # Since the files are normalized to the root folder of the repositary, figure
-  # out what we need to add to the paths.
-  dir_prefix = os.getcwd()[len(GetRepositoryRoot()):].strip(os.sep)
-
-  # Get a list of all files in changelists.
-  files_in_cl = {}
-  for cl in GetCLs():
-    change_info = LoadChangelistInfo(cl)
-    for status, filename in change_info.files:
-      files_in_cl[filename] = change_info.name
-
-  # Get all the modified files.
-  status = RunShell(["svn", "status"])
-  for line in status.splitlines():
-    if not len(line) or line[0] == "?":
-      continue
-    status = line[:7]
-    filename = line[7:]
-    if dir_prefix:
-      filename = os.path.join(dir_prefix, filename)
-    change_list_name = ""
-    if filename in files_in_cl:
-      change_list_name = files_in_cl[filename]
-    files.setdefault(change_list_name, []).append((status, filename))
-
-  return files
-
-
-def GetFilesNotInCL():
-  """Returns a list of tuples (status,filename) that aren't in any changelists.
-  
-  See docstring of GetModifiedFiles for information about path of files and
-  which directories are scanned.
-  """
-  modified_files = GetModifiedFiles()
-  if "" not in modified_files:
-    return []
-  return modified_files[""]
-
-
-def SendToRietveld(request_path, payload=None,
-                   content_type="application/octet-stream"):
-  """Send a POST/GET to Rietveld.  Returns the response body."""
-  def GetUserCredentials():
-    """Prompts the user for a username and password."""
-    email = raw_input("Email: ").strip()
-    password = getpass.getpass("Password for %s: " % email)
-    return email, password
-
-  server = GetCodeReviewSetting("CODE_REVIEW_SERVER")
-  rpc_server = upload.HttpRpcServer(server,
-                                    GetUserCredentials,
-                                    host_override=server,
-                                    save_cookies=True)
-  return rpc_server.Send(request_path, payload, content_type)
-
-
-def GetIssueDescription(issue):
-  """Returns the issue description from Rietveld."""
-  return SendToRietveld("/" + issue + "/description")
-
-
-def UnknownFiles(extra_args):
-  """Runs svn status and prints unknown files.
-
-  Any args in |extra_args| are passed to the tool to support giving alternate
-  code locations.
-  """
-  args = ["svn", "status"]
-  args += extra_args
-  p = subprocess.Popen(args, stdout = subprocess.PIPE,
-                       stderr = subprocess.STDOUT, shell = use_shell)
-  while 1:
-    line = p.stdout.readline()
-    if not line:
-      break
-    if line[0] != '?':
-      continue  # Not an unknown file to svn.
-    # The lines look like this:
-    # "?      foo.txt"
-    # and we want just "foo.txt"
-    print line[7:].strip()
-  p.wait()
-  p.stdout.close()
-
-
-def Opened():
-  """Prints a list of modified files in the current directory down."""
-  files = GetModifiedFiles()
-  cl_keys = files.keys()
-  cl_keys.sort()
-  for cl_name in cl_keys:
-    if cl_name:
-      note = ""
-      if len(LoadChangelistInfo(cl_name).files) != len(files[cl_name]):
-        note = " (Note: this changelist contains files outside this directory)"
-      print "\n--- Changelist " + cl_name + note + ":"
-    for file in files[cl_name]:
-      print "".join(file)
-
-
-def Help():
-  print ("GCL is a wrapper for Subversion that simplifies working with groups "
-         "of files.\n")
-  print "Basic commands:"
-  print "-----------------------------------------"
-  print "   gcl change change_name"
-  print ("      Add/remove files to a changelist.  Only scans the current "
-         "directory and subdirectories.\n")
-  print ("   gcl upload change_name [-r reviewer1@gmail.com,"
-         "reviewer2@gmail.com,...] [--send_mail]")
-  print "      Uploads the changelist to the server for review.\n"
-  print "   gcl commit change_name"
-  print "      Commits the changelist to the repository.\n"
-  print "Advanced commands:"
-  print "-----------------------------------------"
-  print "   gcl delete change_name"
-  print "      Deletes a changelist.\n"
-  print "   gcl diff change_name"
-  print "      Diffs all files in the changelist.\n"
-  print "   gcl diff"
-  print ("      Diffs all files in the current directory and subdirectories "
-         "that aren't in a changelist.\n")
-  print "   gcl changes"
-  print "      Lists all the the changelists and the files in them.\n"
-  print "   gcl nothave [optional directory]"
-  print "      Lists files unknown to Subversion.\n"
-  print "   gcl opened"
-  print ("      Lists modified files in the current directory and "
-         "subdirectories.\n")
-  print "   gcl try change_name"
-  print ("      Sends the change to the tryserver so a trybot can do a test"
-         " run on your code.\n")
-
-
-def GetEditor():
-  editor = os.environ.get("SVN_EDITOR")
-  if not editor:
-    editor = os.environ.get("EDITOR")
-
-  if not editor:
-    if sys.platform.startswith("win"):
-      editor = "notepad"
-    else:
-      editor = "vi"
-
-  return editor
-
-
-def GenerateDiff(files):
-  """Returns a string containing the diff for the given file list."""
-  diff = []
-  for file in files:
-    # Use svn info output instead of os.path.isdir because the latter fails
-    # when the file is deleted.
-    if GetSVNFileInfo(file, "Node Kind") == "directory":
-      continue
-    # If the user specified a custom diff command in their svn config file,
-    # then it'll be used when we do svn diff, which we don't want to happen
-    # since we want the unified diff.  Using --diff-cmd=diff doesn't always
-    # work, since they can have another diff executable in their path that
-    # gives different line endings.  So we use a bogus temp directory as the
-    # config directory, which gets around these problems.
-    if sys.platform.startswith("win"):
-      parent_dir = tempfile.gettempdir()
-    else:
-      parent_dir = sys.path[0]  # tempdir is not secure.
-    bogus_dir = os.path.join(parent_dir, "temp_svn_config")
-    if not os.path.exists(bogus_dir):
-      os.mkdir(bogus_dir)
-    diff.append(RunShell(["svn", "diff", "--config-dir", bogus_dir, file]))
-  return "".join(diff)
-
-
-def UploadCL(change_info, args):
-  if not change_info.FileList():
-    print "Nothing to upload, changelist is empty."
-    return
-
-  upload_arg = ["upload.py", "-y", "-l"]
-  upload_arg.append("--server=" + GetCodeReviewSetting("CODE_REVIEW_SERVER"))
-  upload_arg.extend(args)
-
-  desc_file = ""
-  if change_info.issue:  # Uploading a new patchset.
-    upload_arg.append("--message=''")
-    upload_arg.append("--issue=" + change_info.issue)
-  else: # First time we upload.
-    handle, desc_file = tempfile.mkstemp(text=True)
-    os.write(handle, change_info.description)
-    os.close(handle)
-
-    upload_arg.append("--cc=" + GetCodeReviewSetting("CC_LIST"))
-    upload_arg.append("--description_file=" + desc_file + "")
-    if change_info.description:
-      subject = change_info.description[:77]
-      if subject.find("\r\n") != -1:
-        subject = subject[:subject.find("\r\n")]
-      if subject.find("\n") != -1:
-        subject = subject[:subject.find("\n")]
-      if len(change_info.description) > 77:
-        subject = subject + "..."
-      upload_arg.append("--message=" + subject)
-  
-  # Change the current working directory before calling upload.py so that it
-  # shows the correct base.
-  os.chdir(GetRepositoryRoot())
-
-  # If we have a lot of files with long paths, then we won't be able to fit
-  # the command to "svn diff".  Instead, we generate the diff manually for
-  # each file and concatenate them before passing it to upload.py.
-  issue = upload.RealMain(upload_arg, GenerateDiff(change_info.FileList()))
-  if issue and issue != change_info.issue:
-    change_info.issue = issue
-    change_info.Save()
-
-  if desc_file:
-    os.remove(desc_file)
-
-
-def TryChange(change_info, args):
-  """Create a diff file of change_info and send it to the try server."""
-  try:
-    import trychange
-  except ImportError:
-    ErrorExit("You need to install trychange.py to use the try server.")
-
-  trychange.TryChange(args, change_info.name, change_info.FileList())
-
-
-def Commit(change_info):
-  if not change_info.FileList():
-    print "Nothing to commit, changelist is empty."
-    return
-
-  commit_cmd = ["svn", "commit"]
-  filename = ''
-  if change_info.issue:
-    # Get the latest description from Rietveld.
-    change_info.description = GetIssueDescription(change_info.issue)
-
-  commit_message = change_info.description.replace('\r\n', '\n')
-  if change_info.issue:
-    commit_message += ('\nReview URL: http://%s/%s' %
-                       (GetCodeReviewSetting("CODE_REVIEW_SERVER"),
-                        change_info.issue))
-
-  handle, commit_filename = tempfile.mkstemp(text=True)
-  os.write(handle, commit_message)
-  os.close(handle)
-
-  handle, targets_filename = tempfile.mkstemp(text=True)
-  os.write(handle, "\n".join(change_info.FileList()))
-  os.close(handle)
-
-  commit_cmd += ['--file=' + commit_filename]
-  commit_cmd += ['--targets=' + targets_filename]
-  # Change the current working directory before calling commit.
-  os.chdir(GetRepositoryRoot())
-  output = RunShell(commit_cmd, True)
-  os.remove(commit_filename)
-  os.remove(targets_filename)
-  if output.find("Committed revision") != -1:
-    change_info.Delete()
-
-    if change_info.issue:
-      revision = re.compile(".*?\nCommitted revision (\d+)",
-                            re.DOTALL).match(output).group(1)
-      viewvc_url = GetCodeReviewSetting("VIEW_VC")
-      change_info.description = (change_info.description +
-                                 "\n\nCommitted: " + viewvc_url + revision)
-      change_info.CloseIssue()
-
-
-def Change(change_info):
-  """Creates/edits a changelist."""
-  if change_info.issue:
-    try:
-      description = GetIssueDescription(change_info.issue)
-    except urllib2.HTTPError, err:
-      if err.code == 404:
-        # The user deleted the issue in Rietveld, so forget the old issue id.
-        description = change_info.description
-        change_info.issue = ""
-        change_info.Save()
-      else:
-        ErrorExit("Error getting the description from Rietveld: " + err)
-  else:
-    description = change_info.description
-
-  other_files = GetFilesNotInCL()
-
-  separator1 = ("\n---All lines above this line become the description.\n"
-                "---Repository Root: " + GetRepositoryRoot() + "\n"
-                "---Paths in this changelist (" + change_info.name + "):\n")
-  separator2 = "\n\n---Paths modified but not in any changelist:\n\n"
-  text = (description + separator1 + '\n' +
-          '\n'.join([f[0] + f[1] for f in change_info.files]) + separator2 +
-          '\n'.join([f[0] + f[1] for f in other_files]) + '\n')
-
-  handle, filename = tempfile.mkstemp(text=True)
-  os.write(handle, text)
-  os.close(handle)
-  
-  command = GetEditor() + " " + filename
-  os.system(command)
-
-  result = ReadFile(filename)
-  os.remove(filename)
-
-  if not result:
-    return
-
-  split_result = result.split(separator1, 1)
-  if len(split_result) != 2:
-    ErrorExit("Don't modify the text starting with ---!\n\n" + result)
-
-  new_description = split_result[0]
-  cl_files_text = split_result[1]
-  if new_description != description:
-    change_info.description = new_description
-    if change_info.issue:
-      # Update the Rietveld issue with the new description.
-      change_info.UpdateRietveldDescription()
-
-  new_cl_files = []
-  for line in cl_files_text.splitlines():
-    if not len(line):
-      continue
-    if line.startswith("---"):
-      break
-    status = line[:7]
-    file = line[7:]
-    new_cl_files.append((status, file))
-  change_info.files = new_cl_files
-
-  change_info.Save()
-  print change_info.name + " changelist saved."
-
-
-def Changes():
-  """Print all the changlists and their files."""
-  for cl in GetCLs():
-    change_info = LoadChangelistInfo(cl, True, True)
-    print "\n--- Changelist " + change_info.name + ":"
-    for file in change_info.files:
-      print "".join(file)
-
-
-def main(argv=None):
-  if argv is None:
-    argv = sys.argv
-  
-  if len(argv) == 1:
-    Help()
-    return 0;
-
-  # Create the directory where we store information about changelists if it
-  # doesn't exist.
-  if not os.path.exists(GetInfoDir()):
-    os.mkdir(GetInfoDir())
-
-  command = argv[1]
-  if command == "opened":
-    Opened()
-    return 0
-  if command == "nothave":
-    UnknownFiles(argv[2:])
-    return 0
-  if command == "changes":
-    Changes()
-    return 0
-  if command == "diff" and len(argv) == 2:
-    files = GetFilesNotInCL()
-    print GenerateDiff([os.path.join(GetRepositoryRoot(), x[1]) for x in files])
-    return 0
-
-  if len(argv) == 2:
-    if command == "change":
-      # Generate a random changelist name.
-      changename = GenerateChangeName()
-    elif command == "help":
-      Help()
-      return 0
-    else:
-      ErrorExit("Need a changelist name.")
-  else:
-    changename = argv[2]
-
-  fail_on_not_found = command != "change"
-  change_info = LoadChangelistInfo(changename, fail_on_not_found, True)
-
-  if command == "change":
-    Change(change_info)
-  elif command == "upload":
-    UploadCL(change_info, argv[3:])
-  elif command == "commit":
-    Commit(change_info)
-  elif command == "delete":
-    change_info.Delete()
-  elif command == "try":
-    TryChange(change_info, argv[3:])
-  else:
-    # Everything else that is passed into gcl we redirect to svn, after adding
-    # the files. This allows commands such as 'gcl diff xxx' to work.
-    args =["svn", command]
-    root = GetRepositoryRoot()
-    args.extend([os.path.join(root, x) for x in change_info.FileList()])
-    RunShell(args, True)
-  return 0
-
-
-if __name__ == "__main__":
-    sys.exit(main())
diff --git a/thirdparty/chromium/upload.py b/thirdparty/chromium/upload.py
deleted file mode 120000
index b8ba213..0000000
--- a/thirdparty/chromium/upload.py
+++ /dev/null
@@ -1 +0,0 @@
-../rietveld/upload.py
\ No newline at end of file
diff --git a/thirdparty/mocker/LICENSE b/thirdparty/mocker/LICENSE
deleted file mode 100644
index c5b5923..0000000
--- a/thirdparty/mocker/LICENSE
+++ /dev/null
@@ -1,259 +0,0 @@
-A. HISTORY OF THE SOFTWARE
-==========================
-
-Python was created in the early 1990s by Guido van Rossum at Stichting
-Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
-as a successor of a language called ABC.  Guido remains Python's
-principal author, although it includes many contributions from others.
-
-In 1995, Guido continued his work on Python at the Corporation for
-National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
-in Reston, Virginia where he released several versions of the
-software.
-
-In May 2000, Guido and the Python core development team moved to
-BeOpen.com to form the BeOpen PythonLabs team.  In October of the same
-year, the PythonLabs team moved to Digital Creations (now Zope
-Corporation, see http://www.zope.com).  In 2001, the Python Software
-Foundation (PSF, see http://www.python.org/psf/) was formed, a
-non-profit organization created specifically to own Python-related
-Intellectual Property.  Zope Corporation is a sponsoring member of
-the PSF.
-
-All Python releases are Open Source (see http://www.opensource.org for
-the Open Source Definition).  Historically, most, but not all, Python
-releases have also been GPL-compatible; the table below summarizes
-the various releases.
-
-    Release         Derived     Year        Owner       GPL-
-		    from                                compatible? (1)
-
-    0.9.0 thru 1.2              1991-1995   CWI         yes
-    1.3 thru 1.5.2  1.2         1995-1999   CNRI        yes
-    1.6             1.5.2       2000        CNRI        no
-    2.0             1.6         2000        BeOpen.com  no
-    1.6.1           1.6         2001        CNRI        yes (2)
-    2.1             2.0+1.6.1   2001        PSF         no
-    2.0.1           2.0+1.6.1   2001        PSF         yes
-    2.1.1           2.1+2.0.1   2001        PSF         yes
-    2.2             2.1.1       2001        PSF         yes
-    2.1.2           2.1.1       2002        PSF         yes
-    2.1.3           2.1.2       2002        PSF         yes
-    2.2.1           2.2         2002        PSF         yes
-    2.2.2           2.2.1       2002        PSF         yes
-    2.2.3           2.2.2       2003        PSF         yes
-    2.3             2.2.2       2002-2003   PSF         yes
-
-Footnotes:
-
-(1) GPL-compatible doesn't mean that we're distributing Python under
-    the GPL.  All Python licenses, unlike the GPL, let you distribute
-    a modified version without making your changes open source.  The
-    GPL-compatible licenses make it possible to combine Python with
-    other software that is released under the GPL; the others don't.
-
-(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
-    because its license has a choice of law clause.  According to
-    CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
-    is "not incompatible" with the GPL.
-
-Thanks to the many outside volunteers who have worked under Guido's
-direction to make these releases possible.
-
-
-B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
-===============================================================
-
-PSF LICENSE AGREEMENT FOR PYTHON 2.3
-------------------------------------
-
-1. This LICENSE AGREEMENT is between the Python Software Foundation
-("PSF"), and the Individual or Organization ("Licensee") accessing and
-otherwise using Python 2.3 software in source or binary form and its
-associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, PSF
-hereby grants Licensee a nonexclusive, royalty-free, world-wide
-license to reproduce, analyze, test, perform and/or display publicly,
-prepare derivative works, distribute, and otherwise use Python 2.3
-alone or in any derivative version, provided, however, that PSF's
-License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
-2001, 2002, 2003 Python Software Foundation; All Rights Reserved" are
-retained in Python 2.3 alone or in any derivative version prepared by
-Licensee.
-
-3. In the event Licensee prepares a derivative work that is based on
-or incorporates Python 2.3 or any part thereof, and wants to make
-the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to Python 2.3.
-
-4. PSF is making Python 2.3 available to Licensee on an "AS IS"
-basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.3 WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
-2.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
-A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3,
-OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. Nothing in this License Agreement shall be deemed to create any
-relationship of agency, partnership, or joint venture between PSF and
-Licensee.  This License Agreement does not grant permission to use PSF
-trademarks or trade name in a trademark sense to endorse or promote
-products or services of Licensee, or any third party.
-
-8. By copying, installing or otherwise using Python 2.3, Licensee
-agrees to be bound by the terms and conditions of this License
-Agreement.
-
-
-BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
--------------------------------------------
-
-BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
-
-1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
-office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
-Individual or Organization ("Licensee") accessing and otherwise using
-this software in source or binary form and its associated
-documentation ("the Software").
-
-2. Subject to the terms and conditions of this BeOpen Python License
-Agreement, BeOpen hereby grants Licensee a non-exclusive,
-royalty-free, world-wide license to reproduce, analyze, test, perform
-and/or display publicly, prepare derivative works, distribute, and
-otherwise use the Software alone or in any derivative version,
-provided, however, that the BeOpen Python License is retained in the
-Software, alone or in any derivative version prepared by Licensee.
-
-3. BeOpen is making the Software available to Licensee on an "AS IS"
-basis.  BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
-SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
-AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
-DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-5. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-6. This License Agreement shall be governed by and interpreted in all
-respects by the law of the State of California, excluding conflict of
-law provisions.  Nothing in this License Agreement shall be deemed to
-create any relationship of agency, partnership, or joint venture
-between BeOpen and Licensee.  This License Agreement does not grant
-permission to use BeOpen trademarks or trade names in a trademark
-sense to endorse or promote products or services of Licensee, or any
-third party.  As an exception, the "BeOpen Python" logos available at
-http://www.pythonlabs.com/logos.html may be used according to the
-permissions granted on that web page.
-
-7. By copying, installing or otherwise using the software, Licensee
-agrees to be bound by the terms and conditions of this License
-Agreement.
-
-
-CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
----------------------------------------
-
-1. This LICENSE AGREEMENT is between the Corporation for National
-Research Initiatives, having an office at 1895 Preston White Drive,
-Reston, VA 20191 ("CNRI"), and the Individual or Organization
-("Licensee") accessing and otherwise using Python 1.6.1 software in
-source or binary form and its associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, CNRI
-hereby grants Licensee a nonexclusive, royalty-free, world-wide
-license to reproduce, analyze, test, perform and/or display publicly,
-prepare derivative works, distribute, and otherwise use Python 1.6.1
-alone or in any derivative version, provided, however, that CNRI's
-License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
-1995-2001 Corporation for National Research Initiatives; All Rights
-Reserved" are retained in Python 1.6.1 alone or in any derivative
-version prepared by Licensee.  Alternately, in lieu of CNRI's License
-Agreement, Licensee may substitute the following text (omitting the
-quotes): "Python 1.6.1 is made available subject to the terms and
-conditions in CNRI's License Agreement.  This Agreement together with
-Python 1.6.1 may be located on the Internet using the following
-unique, persistent identifier (known as a handle): 1895.22/1013.  This
-Agreement may also be obtained from a proxy server on the Internet
-using the following URL: http://hdl.handle.net/1895.22/1013".
-
-3. In the event Licensee prepares a derivative work that is based on
-or incorporates Python 1.6.1 or any part thereof, and wants to make
-the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to Python 1.6.1.
-
-4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
-basis.  CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
-1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
-A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
-OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. This License Agreement shall be governed by the federal
-intellectual property law of the United States, including without
-limitation the federal copyright law, and, to the extent such
-U.S. federal law does not apply, by the law of the Commonwealth of
-Virginia, excluding Virginia's conflict of law provisions.
-Notwithstanding the foregoing, with regard to derivative works based
-on Python 1.6.1 that incorporate non-separable material that was
-previously distributed under the GNU General Public License (GPL), the
-law of the Commonwealth of Virginia shall govern this License
-Agreement only as to issues arising under or with respect to
-Paragraphs 4, 5, and 7 of this License Agreement.  Nothing in this
-License Agreement shall be deemed to create any relationship of
-agency, partnership, or joint venture between CNRI and Licensee.  This
-License Agreement does not grant permission to use CNRI trademarks or
-trade name in a trademark sense to endorse or promote products or
-services of Licensee, or any third party.
-
-8. By clicking on the "ACCEPT" button where indicated, or by copying,
-installing or otherwise using Python 1.6.1, Licensee agrees to be
-bound by the terms and conditions of this License Agreement.
-
-        ACCEPT
-
-
-CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
---------------------------------------------------
-
-Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
-The Netherlands.  All rights reserved.
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Stichting Mathematisch
-Centrum or CWI not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior
-permission.
-
-STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
-THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
-FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/thirdparty/mocker/__init__.py b/thirdparty/mocker/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/thirdparty/mocker/__init__.py
+++ /dev/null
diff --git a/thirdparty/mocker/mocker.py b/thirdparty/mocker/mocker.py
deleted file mode 100644
index 1e92f72..0000000
--- a/thirdparty/mocker/mocker.py
+++ /dev/null
@@ -1,2068 +0,0 @@
-"""
-Copyright (c) 2007  Gustavo Niemeyer <gustavo@niemeyer.net>
-
-Graceful platform for test doubles in Python (mocks, stubs, fakes, and dummies).
-"""
-import __builtin__
-import tempfile
-import unittest
-import inspect
-import shutil
-import types
-import sys
-import os
-import gc
-
-
-if sys.version_info < (2, 4):
-    from sets import Set as set # pragma: nocover
-
-
-__all__ = ["Mocker", "expect", "IS", "CONTAINS", "IN", "MATCH",
-           "ANY", "ARGS", "KWARGS"]
-
-
-__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
-__license__ = "PSF License"
-__version__ = "0.10.1"
-
-
-ERROR_PREFIX = "[Mocker] "
-
-
-# --------------------------------------------------------------------
-# Exceptions
-
-class MatchError(AssertionError):
-    """Raised when an unknown expression is seen in playback mode."""
-
-
-# --------------------------------------------------------------------
-# Helper for chained-style calling.
-
-class expect(object):
-    """This is a simple helper that allows a different call-style.
-
-    With this class one can comfortably do chaining of calls to the
-    mocker object responsible by the object being handled. For instance::
-
-        expect(obj.attr).result(3).count(1, 2)
-
-    Is the same as::
-
-        obj.attr
-        mocker.result(3)
-        mocker.count(1, 2)
-
-    """
-
-    def __init__(self, mock, attr=None):
-        self._mock = mock
-        self._attr = attr
-
-    def __getattr__(self, attr):
-        return self.__class__(self._mock, attr)
-
-    def __call__(self, *args, **kwargs):
-        getattr(self._mock.__mocker__, self._attr)(*args, **kwargs)
-        return self
-
-
-# --------------------------------------------------------------------
-# Extensions to Python's unittest.
-
-class MockerTestCase(unittest.TestCase):
-    """unittest.TestCase subclass with Mocker support.
-
-    @ivar mocker: The mocker instance.
-
-    This is a convenience only.  Mocker may easily be used with the
-    standard C{unittest.TestCase} class if wanted.
-
-    Test methods have a Mocker instance available on C{self.mocker}.
-    At the end of each test method, expectations of the mocker will
-    be verified, and any requested changes made to the environment
-    will be restored.
-
-    In addition to the integration with Mocker, this class provides
-    a few additional helper methods.
-    """
-
-    expect = expect
-
-    def __init__(self, methodName="runTest"):
-        # So here is the trick: we take the real test method, wrap it on
-        # a function that do the job we have to do, and insert it in the
-        # *instance* dictionary, so that getattr() will return our
-        # replacement rather than the class method.
-        test_method = getattr(self, methodName, None)
-        if test_method is not None:
-            def test_method_wrapper():
-                try:
-                    result = test_method()
-                except:
-                    raise
-                else:
-                    if (self.mocker.is_recording() and
-                        self.mocker.get_events()):
-                        raise RuntimeError("Mocker must be put in replay "
-                                           "mode with self.mocker.replay()")
-                    if (hasattr(result, "addCallback") and
-                        hasattr(result, "addErrback")):
-                        def verify(result):
-                            self.mocker.verify()
-                            return result
-                        result.addCallback(verify)
-                    else:
-                        self.mocker.verify()
-                    return result
-            # Copy all attributes from the original method..
-            for attr in dir(test_method):
-                # .. unless they're present in our wrapper already.
-                if not hasattr(test_method_wrapper, attr) or attr == "__doc__":
-                    setattr(test_method_wrapper, attr,
-                            getattr(test_method, attr))
-            setattr(self, methodName, test_method_wrapper)
-
-        # We could overload run() normally, but other well-known testing
-        # frameworks do it as well, and some of them won't call the super,
-        # which might mean that cleanup wouldn't happen.  With that in mind,
-        # we make integration easier by using the following trick.
-        run_method = self.run
-        def run_wrapper(*args, **kwargs):
-            try:
-                return run_method(*args, **kwargs)
-            finally:
-                self.__cleanup()
-        self.run = run_wrapper
-
-        self.mocker = Mocker()
-
-        self.__cleanup_funcs = []
-        self.__cleanup_paths = []
-
-        super(MockerTestCase, self).__init__(methodName)
-
-    def __cleanup(self):
-        for path in self.__cleanup_paths:
-            if os.path.isfile(path):
-                os.unlink(path)
-            elif os.path.isdir(path):
-                shutil.rmtree(path)
-        self.mocker.restore()
-        for func, args, kwargs in self.__cleanup_funcs:
-            func(*args, **kwargs)
-
-    def addCleanup(self, func, *args, **kwargs):
-        self.__cleanup_funcs.append((func, args, kwargs))
-
-    def makeFile(self, content=None, suffix="", prefix="tmp", basename=None,
-                 dirname=None, path=None):
-        """Create a temporary file and return the path to it.
-
-        @param content: Initial content for the file.
-        @param suffix: Suffix to be given to the file's basename.
-        @param prefix: Prefix to be given to the file's basename.
-        @param basename: Full basename for the file.
-        @param dirname: Put file inside this directory.
-
-        The file is removed after the test runs.
-        """
-        if path is not None:
-            self.__cleanup_paths.append(path)
-        elif basename is not None:
-            if dirname is None:
-                dirname = tempfile.mkdtemp()
-                self.__cleanup_paths.append(dirname)
-            path = os.path.join(dirname, basename)
-        else:
-            fd, path = tempfile.mkstemp(suffix, prefix, dirname)
-            self.__cleanup_paths.append(path)
-            os.close(fd)
-            if content is None:
-                os.unlink(path)
-        if content is not None:
-            file = open(path, "w")
-            file.write(content)
-            file.close()
-        return path
-
-    def makeDir(self, suffix="", prefix="tmp", dirname=None, path=None):
-        """Create a temporary directory and return the path to it.
-
-        @param suffix: Suffix to be given to the file's basename.
-        @param prefix: Prefix to be given to the file's basename.
-        @param dirname: Put directory inside this parent directory.
-
-        The directory is removed after the test runs.
-        """
-        if path is not None:
-            os.makedirs(path)
-        else:
-            path = tempfile.mkdtemp(suffix, prefix, dirname)
-        self.__cleanup_paths.append(path)
-        return path
-
-    def failUnlessIs(self, first, second, msg=None):
-        """Assert that C{first} is the same object as C{second}."""
-        if first is not second:
-            raise self.failureException(msg or "%r is not %r" % (first, second))
-
-    def failIfIs(self, first, second, msg=None):
-        """Assert that C{first} is not the same object as C{second}."""
-        if first is second:
-            raise self.failureException(msg or "%r is %r" % (first, second))
-
-    def failUnlessIn(self, first, second, msg=None):
-        """Assert that C{first} is contained in C{second}."""
-        if first not in second:
-            raise self.failureException(msg or "%r not in %r" % (first, second))
-
-    def failUnlessStartsWith(self, first, second, msg=None):
-        """Assert that C{first} starts with C{second}."""
-        if first[:len(second)] != second:
-            raise self.failureException(msg or "%r doesn't start with %r" %
-                                               (first, second))
-
-    def failIfStartsWith(self, first, second, msg=None):
-        """Assert that C{first} doesn't start with C{second}."""
-        if first[:len(second)] == second:
-            raise self.failureException(msg or "%r starts with %r" %
-                                               (first, second))
-
-    def failUnlessEndsWith(self, first, second, msg=None):
-        """Assert that C{first} starts with C{second}."""
-        if first[len(first)-len(second):] != second:
-            raise self.failureException(msg or "%r doesn't end with %r" %
-                                               (first, second))
-
-    def failIfEndsWith(self, first, second, msg=None):
-        """Assert that C{first} doesn't start with C{second}."""
-        if first[len(first)-len(second):] == second:
-            raise self.failureException(msg or "%r ends with %r" %
-                                               (first, second))
-
-    def failIfIn(self, first, second, msg=None):
-        """Assert that C{first} is not contained in C{second}."""
-        if first in second:
-            raise self.failureException(msg or "%r in %r" % (first, second))
-
-    def failUnlessApproximates(self, first, second, tolerance, msg=None):
-        """Assert that C{first} is near C{second} by at most C{tolerance}."""
-        if abs(first - second) > tolerance:
-            raise self.failureException(msg or "abs(%r - %r) > %r" %
-                                        (first, second, tolerance))
-
-    def failIfApproximates(self, first, second, tolerance, msg=None):
-        """Assert that C{first} is far from C{second} by at least C{tolerance}.
-        """
-        if abs(first - second) <= tolerance:
-            raise self.failureException(msg or "abs(%r - %r) <= %r" %
-                                        (first, second, tolerance))
-
-    def failUnlessMethodsMatch(self, first, second):
-        """Assert that public methods in C{first} are present in C{second}.
-
-        This method asserts that all public methods found in C{first} are also
-        present in C{second} and accept the same arguments.  C{first} may
-        have its own private methods, though, and may not have all methods
-        found in C{second}.  Note that if a private method in C{first} matches
-        the name of one in C{second}, their specification is still compared.
-
-        This is useful to verify if a fake or stub class have the same API as
-        the real class being simulated.
-        """
-        first_methods = dict(inspect.getmembers(first, inspect.ismethod))
-        second_methods = dict(inspect.getmembers(second, inspect.ismethod))
-        for name, first_method in first_methods.items():
-            first_argspec = inspect.getargspec(first_method)
-            first_formatted = inspect.formatargspec(*first_argspec)
-
-            second_method = second_methods.get(name)
-            if second_method is None:
-                if name[:1] == "_":
-                    continue # First may have its own private methods.
-                raise self.failureException("%s.%s%s not present in %s" %
-                    (first.__name__, name, first_formatted, second.__name__))
-
-            second_argspec = inspect.getargspec(second_method)
-            if first_argspec != second_argspec:
-                second_formatted = inspect.formatargspec(*second_argspec)
-                raise self.failureException("%s.%s%s != %s.%s%s" %
-                    (first.__name__, name, first_formatted,
-                     second.__name__, name, second_formatted))
-
-
-    assertIs = failUnlessIs
-    assertIsNot = failIfIs
-    assertIn = failUnlessIn
-    assertNotIn = failIfIn
-    assertStartsWith = failUnlessStartsWith
-    assertNotStartsWith = failIfStartsWith
-    assertEndsWith = failUnlessEndsWith
-    assertNotEndsWith = failIfEndsWith
-    assertApproximates = failUnlessApproximates
-    assertNotApproximates = failIfApproximates
-    assertMethodsMatch = failUnlessMethodsMatch
-
-    # The following are missing in Python < 2.4.
-    assertTrue = unittest.TestCase.failUnless
-    assertFalse = unittest.TestCase.failIf
-
-    # The following is provided for compatibility with Twisted's trial.
-    assertIdentical = assertIs
-    assertNotIdentical = assertIsNot
-    failUnlessIdentical = failUnlessIs
-    failIfIdentical = failIfIs
-
-
-# --------------------------------------------------------------------
-# Mocker.
-
-class classinstancemethod(object):
-
-    def __init__(self, method):
-        self.method = method
-
-    def __get__(self, obj, cls=None):
-        def bound_method(*args, **kwargs):
-            return self.method(cls, obj, *args, **kwargs)
-        return bound_method
-
-
-class MockerBase(object):
-    """Controller of mock objects.
-
-    A mocker instance is used to command recording and replay of
-    expectations on any number of mock objects.
-
-    Expectations should be expressed for the mock object while in
-    record mode (the initial one) by using the mock object itself,
-    and using the mocker (and/or C{expect()} as a helper) to define
-    additional behavior for each event.  For instance::
-
-        mock = mocker.mock()
-        mock.hello()
-        mocker.result("Hi!")
-        mocker.replay()
-        assert mock.hello() == "Hi!"
-        mock.restore()
-        mock.verify()
-
-    In this short excerpt a mock object is being created, then an
-    expectation of a call to the C{hello()} method was recorded, and
-    when called the method should return the value C{10}.  Then, the
-    mocker is put in replay mode, and the expectation is satisfied by
-    calling the C{hello()} method, which indeed returns 10.  Finally,
-    a call to the L{restore()} method is performed to undo any needed
-    changes made in the environment, and the L{verify()} method is
-    called to ensure that all defined expectations were met.
-
-    The same logic can be expressed more elegantly using the
-    C{with mocker:} statement, as follows::
-
-        mock = mocker.mock()
-        mock.hello()
-        mocker.result("Hi!")
-        with mocker:
-            assert mock.hello() == "Hi!"
-
-    Also, the MockerTestCase class, which integrates the mocker on
-    a unittest.TestCase subclass, may be used to reduce the overhead
-    of controlling the mocker.  A test could be written as follows::
-
-        class SampleTest(MockerTestCase):
-
-            def test_hello(self):
-                mock = self.mocker.mock()
-                mock.hello()
-                self.mocker.result("Hi!")
-                self.mocker.replay()
-                self.assertEquals(mock.hello(), "Hi!")
-    """
-
-    _recorders = []
-
-    # For convenience only.
-    on = expect
-
-    class __metaclass__(type):
-        def __init__(self, name, bases, dict):
-            # Make independent lists on each subclass, inheriting from parent.
-            self._recorders = list(getattr(self, "_recorders", ()))
-
-    def __init__(self):
-        self._recorders = self._recorders[:]
-        self._events = []
-        self._recording = True
-        self._ordering = False
-        self._last_orderer = None
-
-    def is_recording(self):
-        """Return True if in recording mode, False if in replay mode.
-
-        Recording is the initial state.
-        """
-        return self._recording
-
-    def replay(self):
-        """Change to replay mode, where recorded events are reproduced.
-
-        If already in replay mode, the mocker will be restored, with all
-        expectations reset, and then put again in replay mode.
-
-        An alternative and more comfortable way to replay changes is
-        using the 'with' statement, as follows::
-
-            mocker = Mocker()
-            <record events>
-            with mocker:
-                <reproduce events>
-
-        The 'with' statement will automatically put mocker in replay
-        mode, and will also verify if all events were correctly reproduced
-        at the end (using L{verify()}), and also restore any changes done
-        in the environment (with L{restore()}).
-
-        Also check the MockerTestCase class, which integrates the
-        unittest.TestCase class with mocker.
-        """
-        if not self._recording:
-            for event in self._events:
-                event.restore()
-        else:
-            self._recording = False
-        for event in self._events:
-            event.replay()
-
-    def restore(self):
-        """Restore changes in the environment, and return to recording mode.
-
-        This should always be called after the test is complete (succeeding
-        or not).  There are ways to call this method automatically on
-        completion (e.g. using a C{with mocker:} statement, or using the
-        L{MockerTestCase} class.
-        """
-        if not self._recording:
-            self._recording = True
-            for event in self._events:
-                event.restore()
-
-    def reset(self):
-        """Reset the mocker state.
-
-        This will restore environment changes, if currently in replay
-        mode, and then remove all events previously recorded.
-        """
-        if not self._recording:
-            self.restore()
-        self.unorder()
-        del self._events[:]
-
-    def get_events(self):
-        """Return all recorded events."""
-        return self._events[:]
-
-    def add_event(self, event):
-        """Add an event.
-
-        This method is used internally by the implementation, and
-        shouldn't be needed on normal mocker usage.
-        """
-        self._events.append(event)
-        if self._ordering:
-            orderer = event.add_task(Orderer(event.path))
-            if self._last_orderer:
-                orderer.add_dependency(self._last_orderer)
-            self._last_orderer = orderer
-        return event
-
-    def verify(self):
-        """Check if all expectations were met, and raise AssertionError if not.
-
-        The exception message will include a nice description of which
-        expectations were not met, and why.
-        """
-        errors = []
-        for event in self._events:
-            try:
-                event.verify()
-            except AssertionError, e:
-                error = str(e)
-                if not error:
-                    raise RuntimeError("Empty error message from %r"
-                                       % event)
-                errors.append(error)
-        if errors:
-            message = [ERROR_PREFIX + "Unmet expectations:", ""]
-            for error in errors:
-                lines = error.splitlines()
-                message.append("=> " + lines.pop(0))
-                message.extend([" " + line for line in lines])
-                message.append("")
-            raise AssertionError(os.linesep.join(message))
-
-    def mock(self, spec_and_type=None, spec=None, type=None,
-             name=None, count=True):
-        """Return a new mock object.
-
-        @param spec_and_type: Handy positional argument which sets both
-                     spec and type.
-        @param spec: Method calls will be checked for correctness against
-                     the given class.
-        @param type: If set, the Mock's __class__ attribute will return
-                     the given type.  This will make C{isinstance()} calls
-                     on the object work.
-        @param name: Name for the mock object, used in the representation of
-                     expressions.  The name is rarely needed, as it's usually
-                     guessed correctly from the variable name used.
-        @param count: If set to false, expressions may be executed any number
-                     of times, unless an expectation is explicitly set using
-                     the L{count()} method.  By default, expressions are
-                     expected once.
-        """
-        if spec_and_type is not None:
-            spec = type = spec_and_type
-        return Mock(self, spec=spec, type=type, name=name, count=count)
-
-    def proxy(self, object, spec=True, type=True, name=None, count=True,
-              passthrough=True):
-        """Return a new mock object which proxies to the given object.
- 
-        Proxies are useful when only part of the behavior of an object
-        is to be mocked.  Unknown expressions may be passed through to
-        the real implementation implicitly (if the C{passthrough} argument
-        is True), or explicitly (using the L{passthrough()} method
-        on the event).
-
-        @param object: Real object to be proxied, and replaced by the mock
-                       on replay mode.  It may also be an "import path",
-                       such as C{"time.time"}, in which case the object
-                       will be the C{time} function from the C{time} module.
-        @param spec: Method calls will be checked for correctness against
-                     the given object, which may be a class or an instance
-                     where attributes will be looked up.  Defaults to the
-                     the C{object} parameter.  May be set to None explicitly,
-                     in which case spec checking is disabled.  Checks may
-                     also be disabled explicitly on a per-event basis with
-                     the L{nospec()} method.
-        @param type: If set, the Mock's __class__ attribute will return
-                     the given type.  This will make C{isinstance()} calls
-                     on the object work.  Defaults to the type of the
-                     C{object} parameter.  May be set to None explicitly.
-        @param name: Name for the mock object, used in the representation of
-                     expressions.  The name is rarely needed, as it's usually
-                     guessed correctly from the variable name used.
-        @param count: If set to false, expressions may be executed any number
-                     of times, unless an expectation is explicitly set using
-                     the L{count()} method.  By default, expressions are
-                     expected once.
-        @param passthrough: If set to False, passthrough of actions on the
-                            proxy to the real object will only happen when
-                            explicitly requested via the L{passthrough()}
-                            method.
-        """
-        if isinstance(object, basestring):
-            if name is None:
-                name = object
-            import_stack = object.split(".")
-            attr_stack = []
-            while import_stack:
-                module_path = ".".join(import_stack)
-                try:
-                    object = __import__(module_path, {}, {}, [""])
-                except ImportError:
-                    attr_stack.insert(0, import_stack.pop())
-                    if not import_stack:
-                        raise
-                    continue
-                else:
-                    for attr in attr_stack:
-                        object = getattr(object, attr)
-                    break
-        if spec is True:
-            spec = object
-        if type is True:
-            type = __builtin__.type(object)
-        return Mock(self, spec=spec, type=type, object=object,
-                    name=name, count=count, passthrough=passthrough)
-
-    def replace(self, object, spec=True, type=True, name=None, count=True,
-                passthrough=True):
-        """Create a proxy, and replace the original object with the mock.
-
-        On replay, the original object will be replaced by the returned
-        proxy in all dictionaries found in the running interpreter via
-        the garbage collecting system.  This should cover module
-        namespaces, class namespaces, instance namespaces, and so on.
-
-        @param object: Real object to be proxied, and replaced by the mock
-                       on replay mode.  It may also be an "import path",
-                       such as C{"time.time"}, in which case the object
-                       will be the C{time} function from the C{time} module.
-        @param spec: Method calls will be checked for correctness against
-                     the given object, which may be a class or an instance
-                     where attributes will be looked up.  Defaults to the
-                     the C{object} parameter.  May be set to None explicitly,
-                     in which case spec checking is disabled.  Checks may
-                     also be disabled explicitly on a per-event basis with
-                     the L{nospec()} method.
-        @param type: If set, the Mock's __class__ attribute will return
-                     the given type.  This will make C{isinstance()} calls
-                     on the object work.  Defaults to the type of the
-                     C{object} parameter.  May be set to None explicitly.
-        @param name: Name for the mock object, used in the representation of
-                     expressions.  The name is rarely needed, as it's usually
-                     guessed correctly from the variable name used.
-        @param passthrough: If set to False, passthrough of actions on the
-                            proxy to the real object will only happen when
-                            explicitly requested via the L{passthrough()}
-                            method.
-        """
-        mock = self.proxy(object, spec, type, name, count, passthrough)
-        event = self._get_replay_restore_event()
-        event.add_task(ProxyReplacer(mock))
-        return mock
-
-    def patch(self, object, spec=True):
-        """Patch an existing object to reproduce recorded events.
-
-        @param object: Class or instance to be patched.
-        @param spec: Method calls will be checked for correctness against
-                     the given object, which may be a class or an instance
-                     where attributes will be looked up.  Defaults to the
-                     the C{object} parameter.  May be set to None explicitly,
-                     in which case spec checking is disabled.  Checks may
-                     also be disabled explicitly on a per-event basis with
-                     the L{nospec()} method.
-
-        The result of this method is still a mock object, which can be
-        used like any other mock object to record events.  The difference
-        is that when the mocker is put on replay mode, the *real* object
-        will be modified to behave according to recorded expectations.
-
-        Patching works in individual instances, and also in classes.
-        When an instance is patched, recorded events will only be
-        considered on this specific instance, and other instances should
-        behave normally.  When a class is patched, the reproduction of
-        events will be considered on any instance of this class once
-        created (collectively).
-
-        Observe that, unlike with proxies which catch only events done
-        through the mock object, *all* accesses to recorded expectations
-        will be considered;  even these coming from the object itself
-        (e.g. C{self.hello()} is considered if this method was patched).
-        While this is a very powerful feature, and many times the reason
-        to use patches in the first place, it's important to keep this
-        behavior in mind.
-
-        Patching of the original object only takes place when the mocker
-        is put on replay mode, and the patched object will be restored
-        to its original state once the L{restore()} method is called
-        (explicitly, or implicitly with alternative conventions, such as
-        a C{with mocker:} block, or a MockerTestCase class).
-        """
-        if spec is True:
-            spec = object
-        patcher = Patcher()
-        event = self._get_replay_restore_event()
-        event.add_task(patcher)
-        mock = Mock(self, object=object, patcher=patcher,
-                    passthrough=True, spec=spec)
-        object.__mocker_mock__ = mock
-        return mock
-
-    def act(self, path):
-        """This is called by mock objects whenever something happens to them.
-
-        This method is part of the implementation between the mocker
-        and mock objects.
-        """
-        if self._recording:
-            event = self.add_event(Event(path))
-            for recorder in self._recorders:
-                recorder(self, event)
-            return Mock(self, path)
-        else:
-            # First run events that may run, then run unsatisfied events, then
-            # ones not previously run. We put the index in the ordering tuple
-            # instead of the actual event because we want a stable sort
-            # (ordering between 2 events is undefined).
-            events = self._events
-            order = [(events[i].satisfied()*2 + events[i].has_run(), i)
-                     for i in range(len(events))]
-            order.sort()
-            postponed = None
-            for weight, i in order:
-                event = events[i]
-                if event.matches(path):
-                    if event.may_run(path):
-                        return event.run(path)
-                    elif postponed is None:
-                        postponed = event
-            if postponed is not None:
-                return postponed.run(path)
-            raise MatchError(ERROR_PREFIX + "Unexpected expression: %s" % path)
-
-    def get_recorders(cls, self):
-        """Return recorders associated with this mocker class or instance.
-
-        This method may be called on mocker instances and also on mocker
-        classes.  See the L{add_recorder()} method for more information.
-        """
-        return (self or cls)._recorders[:]
-    get_recorders = classinstancemethod(get_recorders)
-
-    def add_recorder(cls, self, recorder):
-        """Add a recorder to this mocker class or instance.
-
-        @param recorder: Callable accepting C{(mocker, event)} as parameters.
-
-        This is part of the implementation of mocker.
-
-        All registered recorders are called for translating events that
-        happen during recording into expectations to be met once the state
-        is switched to replay mode.
-
-        This method may be called on mocker instances and also on mocker
-        classes.  When called on a class, the recorder will be used by
-        all instances, and also inherited on subclassing.  When called on
-        instances, the recorder is added only to the given instance.
-        """
-        (self or cls)._recorders.append(recorder)
-        return recorder
-    add_recorder = classinstancemethod(add_recorder)
-
-    def remove_recorder(cls, self, recorder):
-        """Remove the given recorder from this mocker class or instance.
-
-        This method may be called on mocker classes and also on mocker
-        instances.  See the L{add_recorder()} method for more information.
-        """
-        (self or cls)._recorders.remove(recorder)
-    remove_recorder = classinstancemethod(remove_recorder)
-
-    def result(self, value):
-        """Make the last recorded event return the given value on replay.
-        
-        @param value: Object to be returned when the event is replayed.
-        """
-        self.call(lambda *args, **kwargs: value)
-
-    def generate(self, sequence):
-        """Last recorded event will return a generator with the given sequence.
-
-        @param sequence: Sequence of values to be generated.
-        """
-        def generate(*args, **kwargs):
-            for value in sequence:
-                yield value
-        self.call(generate)
-
-    def throw(self, exception):
-        """Make the last recorded event raise the given exception on replay.
-
-        @param exception: Class or instance of exception to be raised.
-        """
-        def raise_exception(*args, **kwargs):
-            raise exception
-        self.call(raise_exception)
-
-    def call(self, func):
-        """Make the last recorded event cause the given function to be called.
-
-        @param func: Function to be called.
-
-        The result of the function will be used as the event result.
-        """
-        self._events[-1].add_task(FunctionRunner(func))
-
-    def count(self, min, max=False):
-        """Last recorded event must be replayed between min and max times.
-
-        @param min: Minimum number of times that the event must happen.
-        @param max: Maximum number of times that the event must happen.  If
-                    not given, it defaults to the same value of the C{min}
-                    parameter.  If set to None, there is no upper limit, and
-                    the expectation is met as long as it happens at least
-                    C{min} times.
-        """
-        event = self._events[-1]
-        for task in event.get_tasks():
-            if isinstance(task, RunCounter):
-                event.remove_task(task)
-        event.add_task(RunCounter(min, max))
-
-    def is_ordering(self):
-        """Return true if all events are being ordered.
-
-        See the L{order()} method.
-        """
-        return self._ordering
-
-    def unorder(self):
-        """Disable the ordered mode.
-        
-        See the L{order()} method for more information.
-        """
-        self._ordering = False
-        self._last_orderer = None
-
-    def order(self, *path_holders):
-        """Create an expectation of order between two or more events.
-
-        @param path_holders: Objects returned as the result of recorded events.
-
-        By default, mocker won't force events to happen precisely in
-        the order they were recorded.  Calling this method will change
-        this behavior so that events will only match if reproduced in
-        the correct order.
-
-        There are two ways in which this method may be used.  Which one
-        is used in a given occasion depends only on convenience.
-
-        If no arguments are passed, the mocker will be put in a mode where
-        all the recorded events following the method call will only be met
-        if they happen in order.  When that's used, the mocker may be put
-        back in unordered mode by calling the L{unorder()} method, or by
-        using a 'with' block, like so::
-
-            with mocker.ordered():
-                <record events>
-
-        In this case, only expressions in <record events> will be ordered,
-        and the mocker will be back in unordered mode after the 'with' block.
-
-        The second way to use it is by specifying precisely which events
-        should be ordered.  As an example::
-
-            mock = mocker.mock()
-            expr1 = mock.hello()
-            expr2 = mock.world
-            expr3 = mock.x.y.z
-            mocker.order(expr1, expr2, expr3)
-
-        This method of ordering only works when the expression returns
-        another object.
-
-        Also check the L{after()} and L{before()} methods, which are
-        alternative ways to perform this.
-        """
-        if not path_holders:
-            self._ordering = True
-            return OrderedContext(self)
-
-        last_orderer = None
-        for path_holder in path_holders:
-            if type(path_holder) is Path:
-                path = path_holder
-            else:
-                path = path_holder.__mocker_path__
-            for event in self._events:
-                if event.path is path:
-                    for task in event.get_tasks():
-                        if isinstance(task, Orderer):
-                            orderer = task
-                            break
-                    else:
-                        orderer = Orderer(path)
-                        event.add_task(orderer)
-                    if last_orderer:
-                        orderer.add_dependency(last_orderer)
-                    last_orderer = orderer
-                    break
-
-    def after(self, *path_holders):
-        """Last recorded event must happen after events referred to.
-
-        @param path_holders: Objects returned as the result of recorded events
-                             which should happen before the last recorded event
-
-        As an example, the idiom::
-
-            expect(mock.x).after(mock.y, mock.z)
-
-        is an alternative way to say::
-
-            expr_x = mock.x
-            expr_y = mock.y
-            expr_z = mock.z
-            mocker.order(expr_y, expr_x)
-            mocker.order(expr_z, expr_x)
-
-        See L{order()} for more information.
-        """
-        last_path = self._events[-1].path
-        for path_holder in path_holders:
-            self.order(path_holder, last_path)
-
-    def before(self, *path_holders):
-        """Last recorded event must happen before events referred to.
-
-        @param path_holders: Objects returned as the result of recorded events
-                             which should happen after the last recorded event
-
-        As an example, the idiom::
-
-            expect(mock.x).before(mock.y, mock.z)
-
-        is an alternative way to say::
-
-            expr_x = mock.x
-            expr_y = mock.y
-            expr_z = mock.z
-            mocker.order(expr_x, expr_y)
-            mocker.order(expr_x, expr_z)
-
-        See L{order()} for more information.
-        """
-        last_path = self._events[-1].path
-        for path_holder in path_holders:
-            self.order(last_path, path_holder)
-
-    def nospec(self):
-        """Don't check method specification of real object on last event.
-
-        By default, when using a mock created as the result of a call to
-        L{proxy()}, L{replace()}, and C{patch()}, or when passing the spec
-        attribute to the L{mock()} method, method calls on the given object
-        are checked for correctness against the specification of the real
-        object (or the explicitly provided spec).
-
-        This method will disable that check specifically for the last
-        recorded event.
-        """
-        event = self._events[-1]
-        for task in event.get_tasks():
-            if isinstance(task, SpecChecker):
-                event.remove_task(task)
-
-    def passthrough(self, result_callback=None):
-        """Make the last recorded event run on the real object once seen.
-
-        @param result_callback: If given, this function will be called with
-            the result of the *real* method call as the only argument.
-
-        This can only be used on proxies, as returned by the L{proxy()}
-        and L{replace()} methods, or on mocks representing patched objects,
-        as returned by the L{patch()} method.
-        """
-        event = self._events[-1]
-        if event.path.root_object is None:
-            raise TypeError("Mock object isn't a proxy")
-        event.add_task(PathExecuter(result_callback))
-
-    def __enter__(self):
-        """Enter in a 'with' context.  This will run replay()."""
-        self.replay()
-        return self
-
-    def __exit__(self, type, value, traceback):
-        """Exit from a 'with' context.
-
-        This will run restore() at all times, but will only run verify()
-        if the 'with' block itself hasn't raised an exception.  Exceptions
-        in that block are never swallowed.
-        """
-        self.restore()
-        if type is None:
-            self.verify()
-        return False
-
-    def _get_replay_restore_event(self):
-        """Return unique L{ReplayRestoreEvent}, creating if needed.
-
-        Some tasks only want to replay/restore.  When that's the case,
-        they shouldn't act on other events during replay.  Also, they
-        can all be put in a single event when that's the case.  Thus,
-        we add a single L{ReplayRestoreEvent} as the first element of
-        the list.
-        """
-        if not self._events or type(self._events[0]) != ReplayRestoreEvent:
-            self._events.insert(0, ReplayRestoreEvent())
-        return self._events[0]
-
-
-class OrderedContext(object):
-
-    def __init__(self, mocker):
-        self._mocker = mocker
-
-    def __enter__(self):
-        return None
-
-    def __exit__(self, type, value, traceback):
-        self._mocker.unorder()
-
-
-class Mocker(MockerBase):
-    __doc__ = MockerBase.__doc__
-
-# Decorator to add recorders on the standard Mocker class.
-recorder = Mocker.add_recorder
-
-
-# --------------------------------------------------------------------
-# Mock object.
-
-class Mock(object):
-
-    def __init__(self, mocker, path=None, name=None, spec=None, type=None,
-                 object=None, passthrough=False, patcher=None, count=True):
-        self.__mocker__ = mocker
-        self.__mocker_path__ = path or Path(self, object)
-        self.__mocker_name__ = name
-        self.__mocker_spec__ = spec
-        self.__mocker_object__ = object
-        self.__mocker_passthrough__ = passthrough
-        self.__mocker_patcher__ = patcher
-        self.__mocker_replace__ = False
-        self.__mocker_type__ = type
-        self.__mocker_count__ = count
-
-    def __mocker_act__(self, kind, args=(), kwargs={}, object=None):
-        if self.__mocker_name__ is None:
-            self.__mocker_name__ = find_object_name(self, 2)
-        action = Action(kind, args, kwargs, self.__mocker_path__)
-        path = self.__mocker_path__ + action
-        if object is not None:
-            path.root_object = object
-        try:
-            return self.__mocker__.act(path)
-        except MatchError, exception:
-            root_mock = path.root_mock
-            if (path.root_object is not None and
-                root_mock.__mocker_passthrough__):
-                return path.execute(path.root_object)
-            # Reinstantiate to show raise statement on traceback, and
-            # also to make the traceback shown shorter.
-            raise MatchError(str(exception))
-        except AssertionError, e:
-            lines = str(e).splitlines()
-            message = [ERROR_PREFIX + "Unmet expectation:", ""]
-            message.append("=> " + lines.pop(0))
-            message.extend([" " + line for line in lines])
-            message.append("")
-            raise AssertionError(os.linesep.join(message))
-
-    def __getattribute__(self, name):
-        if name.startswith("__mocker_"):
-            return super(Mock, self).__getattribute__(name)
-        if name == "__class__":
-            if self.__mocker__.is_recording() or self.__mocker_type__ is None:
-                return type(self)
-            return self.__mocker_type__
-        return self.__mocker_act__("getattr", (name,))
-
-    def __setattr__(self, name, value):
-        if name.startswith("__mocker_"):
-            return super(Mock, self).__setattr__(name, value)
-        return self.__mocker_act__("setattr", (name, value))
-
-    def __delattr__(self, name):
-        return self.__mocker_act__("delattr", (name,))
-
-    def __call__(self, *args, **kwargs):
-        return self.__mocker_act__("call", args, kwargs)
-
-    def __contains__(self, value):
-        return self.__mocker_act__("contains", (value,))
-
-    def __getitem__(self, key):
-        return self.__mocker_act__("getitem", (key,))
-
-    def __setitem__(self, key, value):
-        return self.__mocker_act__("setitem", (key, value))
-
-    def __delitem__(self, key):
-        return self.__mocker_act__("delitem", (key,))
-
-    def __len__(self):
-        # MatchError is turned on an AttributeError so that list() and
-        # friends act properly when trying to get length hints on
-        # something that doesn't offer them.
-        try:
-            result = self.__mocker_act__("len")
-        except MatchError, e:
-            raise AttributeError(str(e))
-        if type(result) is Mock:
-            return 0
-        return result
-
-    def __nonzero__(self):
-        try:
-            return self.__mocker_act__("nonzero")
-        except MatchError, e:
-            return True
-
-    def __iter__(self):
-        # XXX On py3k, when next() becomes __next__(), we'll be able
-        #     to return the mock itself because it will be considered
-        #     an iterator (we'll be mocking __next__ as well, which we
-        #     can't now).
-        result = self.__mocker_act__("iter")
-        if type(result) is Mock:
-            return iter([])
-        return result
-
-    # When adding a new action kind here, also add support for it on
-    # Action.execute() and Path.__str__().
-
-
-def find_object_name(obj, depth=0):
-    """Try to detect how the object is named on a previous scope."""
-    try:
-        frame = sys._getframe(depth+1)
-    except:
-        return None
-    for name, frame_obj in frame.f_locals.iteritems():
-        if frame_obj is obj:
-            return name
-    self = frame.f_locals.get("self")
-    if self is not None:
-        try:
-            items = list(self.__dict__.iteritems())
-        except:
-            pass
-        else:
-            for name, self_obj in items:
-                if self_obj is obj:
-                    return name
-    return None
-
-
-# --------------------------------------------------------------------
-# Action and path.
-
-class Action(object):
-
-    def __init__(self, kind, args, kwargs, path=None):
-        self.kind = kind
-        self.args = args
-        self.kwargs = kwargs
-        self.path = path
-        self._execute_cache = {}
-
-    def __repr__(self):
-        if self.path is None:
-            return "Action(%r, %r, %r)" % (self.kind, self.args, self.kwargs)
-        return "Action(%r, %r, %r, %r)" % \
-               (self.kind, self.args, self.kwargs, self.path)
-
-    def __eq__(self, other):
-        return (self.kind == other.kind and
-                self.args == other.args and
-                self.kwargs == other.kwargs)
-
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def matches(self, other):
-        return (self.kind == other.kind and
-                match_params(self.args, self.kwargs, other.args, other.kwargs))
-
-    def execute(self, object):
-        # This caching scheme may fail if the object gets deallocated before
-        # the action, as the id might get reused.  It's somewhat easy to fix
-        # that with a weakref callback.  For our uses, though, the object
-        # should never get deallocated before the action itself, so we'll
-        # just keep it simple.
-        if id(object) in self._execute_cache:
-            return self._execute_cache[id(object)]
-        execute = getattr(object, "__mocker_execute__", None)
-        if execute is not None:
-            result = execute(self, object)
-        else:
-            kind = self.kind
-            if kind == "getattr":
-                result = getattr(object, self.args[0])
-            elif kind == "setattr":
-                result = setattr(object, self.args[0], self.args[1])
-            elif kind == "delattr":
-                result = delattr(object, self.args[0])
-            elif kind == "call":
-                result = object(*self.args, **self.kwargs)
-            elif kind == "contains":
-                result = self.args[0] in object
-            elif kind == "getitem":
-                result = object[self.args[0]]
-            elif kind == "setitem":
-                result = object[self.args[0]] = self.args[1]
-            elif kind == "delitem":
-                del object[self.args[0]]
-                result = None
-            elif kind == "len":
-                result = len(object)
-            elif kind == "nonzero":
-                result = bool(object)
-            elif kind == "iter":
-                result = iter(object)
-            else:
-                raise RuntimeError("Don't know how to execute %r kind." % kind)
-        self._execute_cache[id(object)] = result
-        return result
-
-
-class Path(object):
-
-    def __init__(self, root_mock, root_object=None, actions=()):
-        self.root_mock = root_mock
-        self.root_object = root_object
-        self.actions = tuple(actions)
-        self.__mocker_replace__ = False
-
-    def parent_path(self):
-        if not self.actions:
-            return None
-        return self.actions[-1].path
-    parent_path = property(parent_path)
- 
-    def __add__(self, action):
-        """Return a new path which includes the given action at the end."""
-        return self.__class__(self.root_mock, self.root_object,
-                              self.actions + (action,))
-
-    def __eq__(self, other):
-        """Verify if the two paths are equal.
-        
-        Two paths are equal if they refer to the same mock object, and
-        have the actions with equal kind, args and kwargs.
-        """
-        if (self.root_mock is not other.root_mock or
-            self.root_object is not other.root_object or
-            len(self.actions) != len(other.actions)):
-            return False
-        for action, other_action in zip(self.actions, other.actions):
-            if action != other_action:
-                return False
-        return True
-
-    def matches(self, other):
-        """Verify if the two paths are equivalent.
-        
-        Two paths are equal if they refer to the same mock object, and
-        have the same actions performed on them.
-        """
-        if (self.root_mock is not other.root_mock or
-            len(self.actions) != len(other.actions)):
-            return False
-        for action, other_action in zip(self.actions, other.actions):
-            if not action.matches(other_action):
-                return False
-        return True
-
-    def execute(self, object):
-        """Execute all actions sequentially on object, and return result.
-        """
-        for action in self.actions:
-            object = action.execute(object)
-        return object
-
-    def __str__(self):
-        """Transform the path into a nice string such as obj.x.y('z')."""
-        result = self.root_mock.__mocker_name__ or "<mock>"
-        for action in self.actions:
-            if action.kind == "getattr":
-                result = "%s.%s" % (result, action.args[0])
-            elif action.kind == "setattr":
-                result = "%s.%s = %r" % (result, action.args[0], action.args[1])
-            elif action.kind == "delattr":
-                result = "del %s.%s" % (result, action.args[0])
-            elif action.kind == "call":
-                args = [repr(x) for x in action.args]
-                items = list(action.kwargs.iteritems())
-                items.sort()
-                for pair in items:
-                    args.append("%s=%r" % pair)
-                result = "%s(%s)" % (result, ", ".join(args))
-            elif action.kind == "contains":
-                result = "%r in %s" % (action.args[0], result)
-            elif action.kind == "getitem":
-                result = "%s[%r]" % (result, action.args[0])
-            elif action.kind == "setitem":
-                result = "%s[%r] = %r" % (result, action.args[0],
-                                          action.args[1])
-            elif action.kind == "delitem":
-                result = "del %s[%r]" % (result, action.args[0])
-            elif action.kind == "len":
-                result = "len(%s)" % result
-            elif action.kind == "nonzero":
-                result = "bool(%s)" % result
-            elif action.kind == "iter":
-                result = "iter(%s)" % result
-            else:
-                raise RuntimeError("Don't know how to format kind %r" %
-                                   action.kind)
-        return result
-
-
-class SpecialArgument(object):
-    """Base for special arguments for matching parameters."""
-
-    def __init__(self, object=None):
-        self.object = object
-
-    def __repr__(self):
-        if self.object is None:
-            return self.__class__.__name__
-        else:
-            return "%s(%r)" % (self.__class__.__name__, self.object)
-
-    def matches(self, other):
-        return True
-
-    def __eq__(self, other):
-        return type(other) == type(self) and self.object == other.object
-
-
-class ANY(SpecialArgument):
-    """Matches any single argument."""
-
-ANY = ANY()
-
-
-class ARGS(SpecialArgument):
-    """Matches zero or more positional arguments."""
-
-ARGS = ARGS()
-
-
-class KWARGS(SpecialArgument):
-    """Matches zero or more keyword arguments."""
-
-KWARGS = KWARGS()
-
-
-class IS(SpecialArgument):
-
-    def matches(self, other):
-        return self.object is other
-
-    def __eq__(self, other):
-        return type(other) == type(self) and self.object is other.object
-
-
-class CONTAINS(SpecialArgument):
-
-    def matches(self, other):
-        try:
-            other.__contains__
-        except AttributeError:
-            try:
-                iter(other)
-            except TypeError:
-                # If an object can't be iterated, and has no __contains__
-                # hook, it'd blow up on the test below.  We test this in
-                # advance to prevent catching more errors than we really
-                # want.
-                return False
-        return self.object in other
-
-
-class IN(SpecialArgument):
-
-    def matches(self, other):
-        return other in self.object
-
-
-class MATCH(SpecialArgument):
-
-    def matches(self, other):
-        return bool(self.object(other))
-
-    def __eq__(self, other):
-        return type(other) == type(self) and self.object is other.object
-
-
-def match_params(args1, kwargs1, args2, kwargs2):
-    """Match the two sets of parameters, considering special parameters."""
-
-    has_args = ARGS in args1
-    has_kwargs = KWARGS in args1
-
-    if has_kwargs:
-        args1 = [arg1 for arg1 in args1 if arg1 is not KWARGS]
-    elif len(kwargs1) != len(kwargs2):
-        return False
-
-    if not has_args and len(args1) != len(args2):
-        return False
-
-    # Either we have the same number of kwargs, or unknown keywords are
-    # accepted (KWARGS was used), so check just the ones in kwargs1.
-    for key, arg1 in kwargs1.iteritems():
-        if key not in kwargs2:
-            return False
-        arg2 = kwargs2[key]
-        if isinstance(arg1, SpecialArgument):
-            if not arg1.matches(arg2):
-                return False
-        elif arg1 != arg2:
-            return False
-
-    # Keywords match.  Now either we have the same number of
-    # arguments, or ARGS was used.  If ARGS wasn't used, arguments
-    # must match one-on-one necessarily.
-    if not has_args:
-        for arg1, arg2 in zip(args1, args2):
-            if isinstance(arg1, SpecialArgument):
-                if not arg1.matches(arg2):
-                    return False
-            elif arg1 != arg2:
-                return False
-        return True
-
-    # Easy choice. Keywords are matching, and anything on args is accepted.
-    if (ARGS,) == args1:
-        return True
-
-    # We have something different there. If we don't have positional
-    # arguments on the original call, it can't match.
-    if not args2:
-        # Unless we have just several ARGS (which is bizarre, but..).
-        for arg1 in args1:
-            if arg1 is not ARGS:
-                return False
-        return True
-
-    # Ok, all bets are lost.  We have to actually do the more expensive
-    # matching.  This is an algorithm based on the idea of the Levenshtein
-    # Distance between two strings, but heavily hacked for this purpose.
-    args2l = len(args2)
-    if args1[0] is ARGS:
-        args1 = args1[1:]
-        array = [0]*args2l
-    else:
-        array = [1]*args2l
-    for i in range(len(args1)):
-        last = array[0]
-        if args1[i] is ARGS:
-            for j in range(1, args2l):
-                last, array[j] = array[j], min(array[j-1], array[j], last)
-        else:
-            array[0] = i or int(args1[i] != args2[0])
-            for j in range(1, args2l):
-                last, array[j] = array[j], last or int(args1[i] != args2[j])
-        if 0 not in array:
-            return False
-    if array[-1] != 0:
-        return False
-    return True
-
-
-# --------------------------------------------------------------------
-# Event and task base.
-
-class Event(object):
-    """Aggregation of tasks that keep track of a recorded action.
-
-    An event represents something that may or may not happen while the
-    mocked environment is running, such as an attribute access, or a
-    method call.  The event is composed of several tasks that are
-    orchestrated together to create a composed meaning for the event,
-    including for which actions it should be run, what happens when it
-    runs, and what's the expectations about the actions run.
-    """
-
-    def __init__(self, path=None):
-        self.path = path
-        self._tasks = []
-        self._has_run = False
-
-    def add_task(self, task):
-        """Add a new task to this taks."""
-        self._tasks.append(task)
-        return task
-
-    def remove_task(self, task):
-        self._tasks.remove(task)
-
-    def get_tasks(self):
-        return self._tasks[:]
-
-    def matches(self, path):
-        """Return true if *all* tasks match the given path."""
-        for task in self._tasks:
-            if not task.matches(path):
-                return False
-        return bool(self._tasks)
-
-    def has_run(self):
-        return self._has_run
-
-    def may_run(self, path):
-        """Verify if any task would certainly raise an error if run.
-
-        This will call the C{may_run()} method on each task and return
-        false if any of them returns false.
-        """
-        for task in self._tasks:
-            if not task.may_run(path):
-                return False
-        return True
-
-    def run(self, path):
-        """Run all tasks with the given action.
-
-        @param path: The path of the expression run.
-
-        Running an event means running all of its tasks individually and in
-        order.  An event should only ever be run if all of its tasks claim to
-        match the given action.
-
-        The result of this method will be the last result of a task
-        which isn't None, or None if they're all None.
-        """
-        self._has_run = True
-        result = None
-        errors = []
-        for task in self._tasks:
-            try:
-                task_result = task.run(path)
-            except AssertionError, e:
-                error = str(e)
-                if not error:
-                    raise RuntimeError("Empty error message from %r" % task)
-                errors.append(error)
-            else:
-                if task_result is not None:
-                    result = task_result
-        if errors:
-            message = [str(self.path)]
-            if str(path) != message[0]:
-                message.append("- Run: %s" % path)
-            for error in errors:
-                lines = error.splitlines()
-                message.append("- " + lines.pop(0))
-                message.extend(["  " + line for line in lines])
-            raise AssertionError(os.linesep.join(message))
-        return result
-
-    def satisfied(self):
-        """Return true if all tasks are satisfied.
-
-        Being satisfied means that there are no unmet expectations.
-        """
-        for task in self._tasks:
-            try:
-                task.verify()
-            except AssertionError:
-                return False
-        return True
-
-    def verify(self):
-        """Run verify on all tasks.
-
-        The verify method is supposed to raise an AssertionError if the
-        task has unmet expectations, with a one-line explanation about
-        why this item is unmet.  This method should be safe to be called
-        multiple times without side effects.
-        """
-        errors = []
-        for task in self._tasks:
-            try:
-                task.verify()
-            except AssertionError, e:
-                error = str(e)
-                if not error:
-                    raise RuntimeError("Empty error message from %r" % task)
-                errors.append(error)
-        if errors:
-            message = [str(self.path)]
-            for error in errors:
-                lines = error.splitlines()
-                message.append("- " + lines.pop(0))
-                message.extend(["  " + line for line in lines])
-            raise AssertionError(os.linesep.join(message))
-
-    def replay(self):
-        """Put all tasks in replay mode."""
-        self._has_run = False
-        for task in self._tasks:
-            task.replay()
-
-    def restore(self):
-        """Restore the state of all tasks."""
-        for task in self._tasks:
-            task.restore()
-
-
-class ReplayRestoreEvent(Event):
-    """Helper event for tasks which need replay/restore but shouldn't match."""
-
-    def matches(self, path):
-        return False
-
-
-class Task(object):
-    """Element used to track one specific aspect on an event.
-
-    A task is responsible for adding any kind of logic to an event.
-    Examples of that are counting the number of times the event was
-    made, verifying parameters if any, and so on.
-    """
-
-    def matches(self, path):
-        """Return true if the task is supposed to be run for the given path.
-        """
-        return True
-
-    def may_run(self, path):
-        """Return false if running this task would certainly raise an error."""
-        return True
-
-    def run(self, path):
-        """Perform the task item, considering that the given action happened.
-        """
-
-    def verify(self):
-        """Raise AssertionError if expectations for this item are unmet.
-
-        The verify method is supposed to raise an AssertionError if the
-        task has unmet expectations, with a one-line explanation about
-        why this item is unmet.  This method should be safe to be called
-        multiple times without side effects.
-        """
-
-    def replay(self):
-        """Put the task in replay mode.
-
-        Any expectations of the task should be reset.
-        """
-
-    def restore(self):
-        """Restore any environmental changes made by the task.
-
-        Verify should continue to work after this is called.
-        """
-
-
-# --------------------------------------------------------------------
-# Task implementations.
-
-class OnRestoreCaller(Task):
-    """Call a given callback when restoring."""
-
-    def __init__(self, callback):
-        self._callback = callback
-
-    def restore(self):
-        self._callback()
-
-
-class PathMatcher(Task):
-    """Match the action path against a given path."""
-
-    def __init__(self, path):
-        self.path = path
-
-    def matches(self, path):
-        return self.path.matches(path)
-
-def path_matcher_recorder(mocker, event):
-    event.add_task(PathMatcher(event.path))
-
-Mocker.add_recorder(path_matcher_recorder)
-
-
-class RunCounter(Task):
-    """Task which verifies if the number of runs are within given boundaries.
-    """
-
-    def __init__(self, min, max=False):
-        self.min = min
-        if max is None:
-            self.max = sys.maxint
-        elif max is False:
-            self.max = min
-        else:
-            self.max = max
-        self._runs = 0
-
-    def replay(self):
-        self._runs = 0
-
-    def may_run(self, path):
-        return self._runs < self.max
-
-    def run(self, path):
-        self._runs += 1
-        if self._runs > self.max:
-            self.verify()
-
-    def verify(self):
-        if not self.min <= self._runs <= self.max:
-            if self._runs < self.min:
-                raise AssertionError("Performed fewer times than expected.")
-            raise AssertionError("Performed more times than expected.")
-
-
-class ImplicitRunCounter(RunCounter):
-    """RunCounter inserted by default on any event.
-
-    This is a way to differentiate explicitly added counters and
-    implicit ones.
-    """
-
-def run_counter_recorder(mocker, event):
-    """Any event may be repeated once, unless disabled by default."""
-    if event.path.root_mock.__mocker_count__:
-        event.add_task(ImplicitRunCounter(1))
-
-Mocker.add_recorder(run_counter_recorder)
-
-def run_counter_removal_recorder(mocker, event):
-    """
-    Events created by getattr actions which lead to other events
-    may be repeated any number of times. For that, we remove implicit
-    run counters of any getattr actions leading to the current one.
-    """
-    parent_path = event.path.parent_path
-    for event in mocker.get_events()[::-1]:
-        if (event.path is parent_path and
-            event.path.actions[-1].kind == "getattr"):
-            for task in event.get_tasks():
-                if type(task) is ImplicitRunCounter:
-                    event.remove_task(task)
-
-Mocker.add_recorder(run_counter_removal_recorder)
-
-
-class MockReturner(Task):
-    """Return a mock based on the action path."""
-
-    def __init__(self, mocker):
-        self.mocker = mocker
-
-    def run(self, path):
-        return Mock(self.mocker, path)
-
-def mock_returner_recorder(mocker, event):
-    """Events that lead to other events must return mock objects."""
-    parent_path = event.path.parent_path
-    for event in mocker.get_events():
-        if event.path is parent_path:
-            for task in event.get_tasks():
-                if isinstance(task, MockReturner):
-                    break
-            else:
-                event.add_task(MockReturner(mocker))
-            break
-
-Mocker.add_recorder(mock_returner_recorder)
-
-
-class FunctionRunner(Task):
-    """Task that runs a function everything it's run.
-
-    Arguments of the last action in the path are passed to the function,
-    and the function result is also returned.
-    """
-
-    def __init__(self, func):
-        self._func = func
-
-    def run(self, path):
-        action = path.actions[-1]
-        return self._func(*action.args, **action.kwargs)
-
-
-class PathExecuter(Task):
-    """Task that executes a path in the real object, and returns the result."""
-
-    def __init__(self, result_callback=None):
-        self._result_callback = result_callback
-
-    def get_result_callback(self):
-        return self._result_callback
-
-    def run(self, path):
-        result = path.execute(path.root_object)
-        if self._result_callback is not None:
-            self._result_callback(result)
-        return result
-
-
-class Orderer(Task):
-    """Task to establish an order relation between two events.
-
-    An orderer task will only match once all its dependencies have
-    been run.
-    """
-
-    def __init__(self, path):
-        self.path = path
-        self._run = False 
-        self._dependencies = []
-
-    def replay(self):
-        self._run = False
-
-    def has_run(self):
-        return self._run
-
-    def may_run(self, path):
-        for dependency in self._dependencies:
-            if not dependency.has_run():
-                return False
-        return True
-
-    def run(self, path):
-        for dependency in self._dependencies:
-            if not dependency.has_run():
-                raise AssertionError("Should be after: %s" % dependency.path)
-        self._run = True
-
-    def add_dependency(self, orderer):
-        self._dependencies.append(orderer)
-
-    def get_dependencies(self):
-        return self._dependencies
-
-
-class SpecChecker(Task):
-    """Task to check if arguments of the last action conform to a real method.
-    """
-
-    def __init__(self, method):
-        self._method = method
-        self._unsupported = False
-
-        if method:
-            try:
-                self._args, self._varargs, self._varkwargs, self._defaults = \
-                    inspect.getargspec(method)
-            except TypeError:
-                self._unsupported = True
-            else:
-                if self._defaults is None:
-                    self._defaults = ()
-                if type(method) is type(self.run):
-                    self._args = self._args[1:]
-
-    def get_method(self):
-        return self._method
-
-    def _raise(self, message):
-        spec = inspect.formatargspec(self._args, self._varargs,
-                                     self._varkwargs, self._defaults)
-        raise AssertionError("Specification is %s%s: %s" %
-                             (self._method.__name__, spec, message))
-
-    def verify(self):
-        if not self._method:
-            raise AssertionError("Method not found in real specification")
-
-    def may_run(self, path):
-        try:
-            self.run(path)
-        except AssertionError:
-            return False
-        return True
-
-    def run(self, path):
-        if not self._method:
-            raise AssertionError("Method not found in real specification")
-        if self._unsupported:
-            return # Can't check it. Happens with builtin functions. :-(
-        action = path.actions[-1]
-        obtained_len = len(action.args)
-        obtained_kwargs = action.kwargs.copy()
-        nodefaults_len = len(self._args) - len(self._defaults)
-        for i, name in enumerate(self._args):
-            if i < obtained_len and name in action.kwargs:
-                self._raise("%r provided twice" % name)
-            if (i >= obtained_len and i < nodefaults_len and
-                name not in action.kwargs):
-                self._raise("%r not provided" % name)
-            obtained_kwargs.pop(name, None)
-        if obtained_len > len(self._args) and not self._varargs:
-            self._raise("too many args provided")
-        if obtained_kwargs and not self._varkwargs:
-            self._raise("unknown kwargs: %s" % ", ".join(obtained_kwargs))
-
-def spec_checker_recorder(mocker, event):
-    spec = event.path.root_mock.__mocker_spec__
-    if spec:
-        actions = event.path.actions
-        if len(actions) == 1:
-            if actions[0].kind == "call":
-                method = getattr(spec, "__call__", None)
-                event.add_task(SpecChecker(method))
-        elif len(actions) == 2:
-            if actions[0].kind == "getattr" and actions[1].kind == "call":
-                method = getattr(spec, actions[0].args[0], None)
-                event.add_task(SpecChecker(method))
-
-Mocker.add_recorder(spec_checker_recorder)
-
-
-class ProxyReplacer(Task):
-    """Task which installs and deinstalls proxy mocks.
-
-    This task will replace a real object by a mock in all dictionaries
-    found in the running interpreter via the garbage collecting system.
-    """
-
-    def __init__(self, mock):
-        self.mock = mock
-        self.__mocker_replace__ = False
-
-    def replay(self):
-        global_replace(self.mock.__mocker_object__, self.mock)
-
-    def restore(self):
-        global_replace(self.mock, self.mock.__mocker_object__)
-
-
-def global_replace(remove, install):
-    """Replace object 'remove' with object 'install' on all dictionaries."""
-    for referrer in gc.get_referrers(remove):
-        if (type(referrer) is dict and
-            referrer.get("__mocker_replace__", True)):
-            for key, value in referrer.items():
-                if value is remove:
-                    referrer[key] = install
-
-
-class Undefined(object):
-
-    def __repr__(self):
-        return "Undefined"
-
-Undefined = Undefined()
-
-
-class Patcher(Task):
-
-    def __init__(self):
-        super(Patcher, self).__init__()
-        self._monitored = {} # {kind: {id(object): object}}
-        self._patched = {}
-
-    def is_monitoring(self, obj, kind):
-        monitored = self._monitored.get(kind)
-        if monitored:
-            if id(obj) in monitored:
-                return True
-            cls = type(obj)
-            if issubclass(cls, type):
-                cls = obj
-            bases = set([id(base) for base in cls.__mro__])
-            bases.intersection_update(monitored)
-            return bool(bases)
-        return False
-
-    def monitor(self, obj, kind):
-        if kind not in self._monitored:
-            self._monitored[kind] = {}
-        self._monitored[kind][id(obj)] = obj
-
-    def patch_attr(self, obj, attr, value):
-        original = obj.__dict__.get(attr, Undefined)
-        self._patched[id(obj), attr] = obj, attr, original
-        setattr(obj, attr, value)
-
-    def get_unpatched_attr(self, obj, attr):
-        cls = type(obj)
-        if issubclass(cls, type):
-            cls = obj
-        result = Undefined
-        for mro_cls in cls.__mro__:
-            key = (id(mro_cls), attr)
-            if key in self._patched:
-                result = self._patched[key][2]
-                if result is not Undefined:
-                    break
-            elif attr in mro_cls.__dict__:
-                result = mro_cls.__dict__.get(attr, Undefined)
-                break
-        if isinstance(result, object) and hasattr(type(result), "__get__"):
-            if cls is obj:
-                obj = None
-            return result.__get__(obj, cls)
-        return result
-
-    def _get_kind_attr(self, kind):
-        if kind == "getattr":
-            return "__getattribute__"
-        return "__%s__" % kind
-
-    def replay(self):
-        for kind in self._monitored:
-            attr = self._get_kind_attr(kind)
-            seen = set()
-            for obj in self._monitored[kind].itervalues():
-                cls = type(obj)
-                if issubclass(cls, type):
-                    cls = obj
-                if cls not in seen:
-                    seen.add(cls)
-                    unpatched = getattr(cls, attr, Undefined)
-                    self.patch_attr(cls, attr,
-                                    PatchedMethod(kind, unpatched,
-                                                  self.is_monitoring))
-                    self.patch_attr(cls, "__mocker_execute__",
-                                    self.execute)
-
-    def restore(self):
-        for obj, attr, original in self._patched.itervalues():
-            if original is Undefined:
-                delattr(obj, attr)
-            else:
-                setattr(obj, attr, original)
-        self._patched.clear()
-
-    def execute(self, action, object):
-        attr = self._get_kind_attr(action.kind)
-        unpatched = self.get_unpatched_attr(object, attr)
-        try:
-            return unpatched(*action.args, **action.kwargs)
-        except AttributeError:
-            if action.kind == "getattr":
-                # The normal behavior of Python is to try __getattribute__,
-                # and if it raises AttributeError, try __getattr__.   We've
-                # tried the unpatched __getattribute__ above, and we'll now
-                # try __getattr__.
-                try:
-                    __getattr__ = unpatched("__getattr__")
-                except AttributeError:
-                    pass
-                else:
-                    return __getattr__(*action.args, **action.kwargs)
-            raise
-
-
-class PatchedMethod(object):
-
-    def __init__(self, kind, unpatched, is_monitoring):
-        self._kind = kind
-        self._unpatched = unpatched
-        self._is_monitoring = is_monitoring
-
-    def __get__(self, obj, cls=None):
-        object = obj or cls
-        if not self._is_monitoring(object, self._kind):
-            return self._unpatched.__get__(obj, cls)
-        def method(*args, **kwargs):
-            if self._kind == "getattr" and args[0].startswith("__mocker_"):
-                return self._unpatched.__get__(obj, cls)(args[0])
-            mock = object.__mocker_mock__
-            return mock.__mocker_act__(self._kind, args, kwargs, object)
-        return method
-
-    def __call__(self, obj, *args, **kwargs):
-        # At least with __getattribute__, Python seems to use *both* the
-        # descriptor API and also call the class attribute directly.  It
-        # looks like an interpreter bug, or at least an undocumented
-        # inconsistency.
-        return self.__get__(obj)(*args, **kwargs)
-
-
-def patcher_recorder(mocker, event):
-    mock = event.path.root_mock
-    if mock.__mocker_patcher__ and len(event.path.actions) == 1:
-        patcher = mock.__mocker_patcher__
-        patcher.monitor(mock.__mocker_object__, event.path.actions[0].kind)
-
-Mocker.add_recorder(patcher_recorder)
diff --git a/thirdparty/rietveld/COPYING b/thirdparty/rietveld/COPYING
deleted file mode 100644
index d645695..0000000
--- a/thirdparty/rietveld/COPYING
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/thirdparty/rietveld/upload.py b/thirdparty/rietveld/upload.py
deleted file mode 100755
index f6f45ff..0000000
--- a/thirdparty/rietveld/upload.py
+++ /dev/null
@@ -1,1339 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2007 Google Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Tool for uploading diffs from a version control system to the codereview app.
-
-Usage summary: upload.py [options] [-- diff_options]
-
-Diff options are passed to the diff command of the underlying system.
-
-Supported version control systems:
-  Git
-  Mercurial
-  Subversion
-
-It is important for Git/Mercurial users to specify a tree/node/branch to diff
-against by using the '--rev' option.
-"""
-# This code is derived from appcfg.py in the App Engine SDK (open source),
-# and from ASPN recipe #146306.
-
-import cookielib
-import getpass
-import logging
-import md5
-import mimetypes
-import optparse
-import os
-import re
-import socket
-import subprocess
-import sys
-import urllib
-import urllib2
-import urlparse
-
-try:
-  import readline
-except ImportError:
-  pass
-
-# The logging verbosity:
-#  0: Errors only.
-#  1: Status messages.
-#  2: Info logs.
-#  3: Debug logs.
-verbosity = 1
-
-# Max size of patch or base file.
-MAX_UPLOAD_SIZE = 900 * 1024
-
-
-def StatusUpdate(msg):
-  """Print a status message to stdout.
-
-  If 'verbosity' is greater than 0, print the message.
-
-  Args:
-    msg: The string to print.
-  """
-  if verbosity > 0:
-    print msg
-
-
-def ErrorExit(msg):
-  """Print an error message to stderr and exit."""
-  print >>sys.stderr, msg
-  sys.exit(1)
-
-
-class ClientLoginError(urllib2.HTTPError):
-  """Raised to indicate there was an error authenticating with ClientLogin."""
-
-  def __init__(self, url, code, msg, headers, args):
-    urllib2.HTTPError.__init__(self, url, code, msg, headers, None)
-    self.args = args
-    self.reason = args["Error"]
-
-
-class AbstractRpcServer(object):
-  """Provides a common interface for a simple RPC server."""
-
-  def __init__(self, host, auth_function, host_override=None, extra_headers={},
-               save_cookies=False):
-    """Creates a new HttpRpcServer.
-
-    Args:
-      host: The host to send requests to.
-      auth_function: A function that takes no arguments and returns an
-        (email, password) tuple when called. Will be called if authentication
-        is required.
-      host_override: The host header to send to the server (defaults to host).
-      extra_headers: A dict of extra headers to append to every request.
-      save_cookies: If True, save the authentication cookies to local disk.
-        If False, use an in-memory cookiejar instead.  Subclasses must
-        implement this functionality.  Defaults to False.
-    """
-    self.host = host
-    self.host_override = host_override
-    self.auth_function = auth_function
-    self.authenticated = False
-    self.extra_headers = extra_headers
-    self.save_cookies = save_cookies
-    self.opener = self._GetOpener()
-    if self.host_override:
-      logging.info("Server: %s; Host: %s", self.host, self.host_override)
-    else:
-      logging.info("Server: %s", self.host)
-
-  def _GetOpener(self):
-    """Returns an OpenerDirector for making HTTP requests.
-
-    Returns:
-      A urllib2.OpenerDirector object.
-    """
-    raise NotImplementedError()
-
-  def _CreateRequest(self, url, data=None):
-    """Creates a new urllib request."""
-    logging.debug("Creating request for: '%s' with payload:\n%s", url, data)
-    req = urllib2.Request(url, data=data)
-    if self.host_override:
-      req.add_header("Host", self.host_override)
-    for key, value in self.extra_headers.iteritems():
-      req.add_header(key, value)
-    return req
-
-  def _GetAuthToken(self, email, password):
-    """Uses ClientLogin to authenticate the user, returning an auth token.
-
-    Args:
-      email:    The user's email address
-      password: The user's password
-
-    Raises:
-      ClientLoginError: If there was an error authenticating with ClientLogin.
-      HTTPError: If there was some other form of HTTP error.
-
-    Returns:
-      The authentication token returned by ClientLogin.
-    """
-    account_type = "HOSTED_OR_GOOGLE"
-    if self.host.endswith(".google.com"):
-      # Needed for use inside Google.
-      account_type = "HOSTED"
-    req = self._CreateRequest(
-        url="https://www.google.com/accounts/ClientLogin",
-        data=urllib.urlencode({
-            "Email": email,
-            "Passwd": password,
-            "service": "ah",
-            "source": "rietveld-codereview-upload",
-            "accountType": account_type,
-        }),
-    )
-    try:
-      response = self.opener.open(req)
-      response_body = response.read()
-      response_dict = dict(x.split("=")
-                           for x in response_body.split("\n") if x)
-      return response_dict["Auth"]
-    except urllib2.HTTPError, e:
-      if e.code == 403:
-        body = e.read()
-        response_dict = dict(x.split("=", 1) for x in body.split("\n") if x)
-        raise ClientLoginError(req.get_full_url(), e.code, e.msg,
-                               e.headers, response_dict)
-      else:
-        raise
-
-  def _GetAuthCookie(self, auth_token):
-    """Fetches authentication cookies for an authentication token.
-
-    Args:
-      auth_token: The authentication token returned by ClientLogin.
-
-    Raises:
-      HTTPError: If there was an error fetching the authentication cookies.
-    """
-    # This is a dummy value to allow us to identify when we're successful.
-    continue_location = "http://localhost/"
-    args = {"continue": continue_location, "auth": auth_token}
-    req = self._CreateRequest("http://%s/_ah/login?%s" %
-                              (self.host, urllib.urlencode(args)))
-    try:
-      response = self.opener.open(req)
-    except urllib2.HTTPError, e:
-      response = e
-    if (response.code != 302 or
-        response.info()["location"] != continue_location):
-      raise urllib2.HTTPError(req.get_full_url(), response.code, response.msg,
-                              response.headers, response.fp)
-    self.authenticated = True
-
-  def _Authenticate(self):
-    """Authenticates the user.
-
-    The authentication process works as follows:
-     1) We get a username and password from the user
-     2) We use ClientLogin to obtain an AUTH token for the user
-        (see http://code.google.com/apis/accounts/AuthForInstalledApps.html).
-     3) We pass the auth token to /_ah/login on the server to obtain an
-        authentication cookie. If login was successful, it tries to redirect
-        us to the URL we provided.
-
-    If we attempt to access the upload API without first obtaining an
-    authentication cookie, it returns a 401 response and directs us to
-    authenticate ourselves with ClientLogin.
-    """
-    for i in range(3):
-      credentials = self.auth_function()
-      try:
-        auth_token = self._GetAuthToken(credentials[0], credentials[1])
-      except ClientLoginError, e:
-        if e.reason == "BadAuthentication":
-          print >>sys.stderr, "Invalid username or password."
-          continue
-        if e.reason == "CaptchaRequired":
-          print >>sys.stderr, (
-              "Please go to\n"
-              "https://www.google.com/accounts/DisplayUnlockCaptcha\n"
-              "and verify you are a human.  Then try again.")
-          break
-        if e.reason == "NotVerified":
-          print >>sys.stderr, "Account not verified."
-          break
-        if e.reason == "TermsNotAgreed":
-          print >>sys.stderr, "User has not agreed to TOS."
-          break
-        if e.reason == "AccountDeleted":
-          print >>sys.stderr, "The user account has been deleted."
-          break
-        if e.reason == "AccountDisabled":
-          print >>sys.stderr, "The user account has been disabled."
-          break
-        if e.reason == "ServiceDisabled":
-          print >>sys.stderr, ("The user's access to the service has been "
-                               "disabled.")
-          break
-        if e.reason == "ServiceUnavailable":
-          print >>sys.stderr, "The service is not available; try again later."
-          break
-        raise
-      self._GetAuthCookie(auth_token)
-      return
-
-  def Send(self, request_path, payload=None,
-           content_type="application/octet-stream",
-           timeout=None,
-           **kwargs):
-    """Sends an RPC and returns the response.
-
-    Args:
-      request_path: The path to send the request to, eg /api/appversion/create.
-      payload: The body of the request, or None to send an empty request.
-      content_type: The Content-Type header to use.
-      timeout: timeout in seconds; default None i.e. no timeout.
-        (Note: for large requests on OS X, the timeout doesn't work right.)
-      kwargs: Any keyword arguments are converted into query string parameters.
-
-    Returns:
-      The response body, as a string.
-    """
-    # TODO: Don't require authentication.  Let the server say
-    # whether it is necessary.
-    if not self.authenticated:
-      self._Authenticate()
-
-    old_timeout = socket.getdefaulttimeout()
-    socket.setdefaulttimeout(timeout)
-    try:
-      tries = 0
-      while True:
-        tries += 1
-        args = dict(kwargs)
-        url = "http://%s%s" % (self.host, request_path)
-        if args:
-          url += "?" + urllib.urlencode(args)
-        req = self._CreateRequest(url=url, data=payload)
-        req.add_header("Content-Type", content_type)
-        try:
-          f = self.opener.open(req)
-          response = f.read()
-          f.close()
-          return response
-        except urllib2.HTTPError, e:
-          if tries > 3:
-            raise
-          elif e.code == 401:
-            self._Authenticate()
-##           elif e.code >= 500 and e.code < 600:
-##             # Server Error - try again.
-##             continue
-          else:
-            raise
-    finally:
-      socket.setdefaulttimeout(old_timeout)
-
-
-class HttpRpcServer(AbstractRpcServer):
-  """Provides a simplified RPC-style interface for HTTP requests."""
-
-  def _Authenticate(self):
-    """Save the cookie jar after authentication."""
-    super(HttpRpcServer, self)._Authenticate()
-    if self.save_cookies:
-      StatusUpdate("Saving authentication cookies to %s" % self.cookie_file)
-      self.cookie_jar.save()
-
-  def _GetOpener(self):
-    """Returns an OpenerDirector that supports cookies and ignores redirects.
-
-    Returns:
-      A urllib2.OpenerDirector object.
-    """
-    opener = urllib2.OpenerDirector()
-    opener.add_handler(urllib2.ProxyHandler())
-    opener.add_handler(urllib2.UnknownHandler())
-    opener.add_handler(urllib2.HTTPHandler())
-    opener.add_handler(urllib2.HTTPDefaultErrorHandler())
-    opener.add_handler(urllib2.HTTPSHandler())
-    opener.add_handler(urllib2.HTTPErrorProcessor())
-    if self.save_cookies:
-      self.cookie_file = os.path.expanduser("~/.codereview_upload_cookies")
-      self.cookie_jar = cookielib.MozillaCookieJar(self.cookie_file)
-      if os.path.exists(self.cookie_file):
-        try:
-          self.cookie_jar.load()
-          self.authenticated = True
-          StatusUpdate("Loaded authentication cookies from %s" %
-                       self.cookie_file)
-        except (cookielib.LoadError, IOError):
-          # Failed to load cookies - just ignore them.
-          pass
-      else:
-        # Create an empty cookie file with mode 600
-        fd = os.open(self.cookie_file, os.O_CREAT, 0600)
-        os.close(fd)
-      # Always chmod the cookie file
-      os.chmod(self.cookie_file, 0600)
-    else:
-      # Don't save cookies across runs of update.py.
-      self.cookie_jar = cookielib.CookieJar()
-    opener.add_handler(urllib2.HTTPCookieProcessor(self.cookie_jar))
-    return opener
-
-
-parser = optparse.OptionParser(usage="%prog [options] [-- diff_options]")
-parser.add_option("-y", "--assume_yes", action="store_true",
-                  dest="assume_yes", default=False,
-                  help="Assume that the answer to yes/no questions is 'yes'.")
-# Logging
-group = parser.add_option_group("Logging options")
-group.add_option("-q", "--quiet", action="store_const", const=0,
-                 dest="verbose", help="Print errors only.")
-group.add_option("-v", "--verbose", action="store_const", const=2,
-                 dest="verbose", default=1,
-                 help="Print info level logs (default).")
-group.add_option("--noisy", action="store_const", const=3,
-                 dest="verbose", help="Print all logs.")
-# Review server
-group = parser.add_option_group("Review server options")
-group.add_option("-s", "--server", action="store", dest="server",
-                 default="codereviews.googleopensourceprograms.com",
-                 metavar="SERVER",
-                 help=("The server to upload to. The format is host[:port]. "
-                       "Defaults to '%default'."))
-group.add_option("-e", "--email", action="store", dest="email",
-                 metavar="EMAIL", default=None,
-                 help="The username to use. Will prompt if omitted.")
-group.add_option("-H", "--host", action="store", dest="host",
-                 metavar="HOST", default=None,
-                 help="Overrides the Host header sent with all RPCs.")
-group.add_option("--no_cookies", action="store_false",
-                 dest="save_cookies", default=True,
-                 help="Do not save authentication cookies to local disk.")
-# Issue
-group = parser.add_option_group("Issue options")
-group.add_option("-d", "--description", action="store", dest="description",
-                 metavar="DESCRIPTION", default=None,
-                 help="Optional description when creating an issue.")
-group.add_option("-f", "--description_file", action="store",
-                 dest="description_file", metavar="DESCRIPTION_FILE",
-                 default=None,
-                 help="Optional path of a file that contains "
-                      "the description when creating an issue.")
-group.add_option("-r", "--reviewers", action="store", dest="reviewers",
-                 metavar="REVIEWERS", default=None,
-                 help="Add reviewers (comma separated email addresses).")
-group.add_option("--cc", action="store", dest="cc",
-                 metavar="CC", default=None,
-                 help="Add CC (comma separated email addresses).")
-# Upload options
-group = parser.add_option_group("Patch options")
-group.add_option("-m", "--message", action="store", dest="message",
-                 metavar="MESSAGE", default=None,
-                 help="A message to identify the patch. "
-                      "Will prompt if omitted.")
-group.add_option("-i", "--issue", type="int", action="store",
-                 metavar="ISSUE", default=None,
-                 help="Issue number to which to add. Defaults to new issue.")
-group.add_option("--download_base", action="store_true",
-                 dest="download_base", default=False,
-                 help="Base files will be downloaded by the server "
-                 "(side-by-side diffs may not work on files with CRs).")
-group.add_option("--rev", action="store", dest="revision",
-                 metavar="REV", default=None,
-                 help="Branch/tree/revision to diff against (used by DVCS).")
-group.add_option("--send_mail", action="store_true",
-                 dest="send_mail", default=False,
-                 help="Send notification email to reviewers.")
-
-
-def GetRpcServer(options):
-  """Returns an instance of an AbstractRpcServer.
-
-  Returns:
-    A new AbstractRpcServer, on which RPC calls can be made.
-  """
-
-  rpc_server_class = HttpRpcServer
-
-  def GetUserCredentials():
-    """Prompts the user for a username and password."""
-    email = options.email
-    if email is None:
-      prompt = "Email (login for uploading to %s): " % options.server
-      email = raw_input(prompt).strip()
-    password = getpass.getpass("Password for %s: " % email)
-    return (email, password)
-
-  # If this is the dev_appserver, use fake authentication.
-  host = (options.host or options.server).lower()
-  if host == "localhost" or host.startswith("localhost:"):
-    email = options.email
-    if email is None:
-      email = "test@example.com"
-      logging.info("Using debug user %s.  Override with --email" % email)
-    server = rpc_server_class(
-        options.server,
-        lambda: (email, "password"),
-        host_override=options.host,
-        extra_headers={"Cookie":
-                       'dev_appserver_login="%s:False"' % email},
-        save_cookies=options.save_cookies)
-    # Don't try to talk to ClientLogin.
-    server.authenticated = True
-    return server
-
-  return rpc_server_class(options.server, GetUserCredentials,
-                          host_override=options.host,
-                          save_cookies=options.save_cookies)
-
-
-def EncodeMultipartFormData(fields, files):
-  """Encode form fields for multipart/form-data.
-
-  Args:
-    fields: A sequence of (name, value) elements for regular form fields.
-    files: A sequence of (name, filename, value) elements for data to be
-           uploaded as files.
-  Returns:
-    (content_type, body) ready for httplib.HTTP instance.
-
-  Source:
-    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306
-  """
-  BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-'
-  CRLF = '\r\n'
-  lines = []
-  for (key, value) in fields:
-    lines.append('--' + BOUNDARY)
-    lines.append('Content-Disposition: form-data; name="%s"' % key)
-    lines.append('')
-    lines.append(value)
-  for (key, filename, value) in files:
-    lines.append('--' + BOUNDARY)
-    lines.append('Content-Disposition: form-data; name="%s"; filename="%s"' %
-             (key, filename))
-    lines.append('Content-Type: %s' % GetContentType(filename))
-    lines.append('')
-    lines.append(value)
-  lines.append('--' + BOUNDARY + '--')
-  lines.append('')
-  body = CRLF.join(lines)
-  content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
-  return content_type, body
-
-
-def GetContentType(filename):
-  """Helper to guess the content-type from the filename."""
-  return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
-
-
-# Use a shell for subcommands on Windows to get a PATH search.
-use_shell = sys.platform.startswith("win")
-
-def RunShellWithReturnCode(command, print_output=False,
-                           universal_newlines=True):
-  """Executes a command and returns the output from stdout and the return code.
-
-  Args:
-    command: Command to execute.
-    print_output: If True, the output is printed to stdout.
-                  If False, both stdout and stderr are ignored.
-    universal_newlines: Use universal_newlines flag (default: True).
-
-  Returns:
-    Tuple (output, return code)
-  """
-  logging.info("Running %s", command)
-  p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
-                       shell=use_shell, universal_newlines=universal_newlines)
-  if print_output:
-    output_array = []
-    while True:
-      line = p.stdout.readline()
-      if not line:
-        break
-      print line.strip("\n")
-      output_array.append(line)
-    output = "".join(output_array)
-  else:
-    output = p.stdout.read()
-  p.wait()
-  errout = p.stderr.read()
-  if print_output and errout:
-    print >>sys.stderr, errout
-  p.stdout.close()
-  p.stderr.close()
-  return output, p.returncode
-
-
-def RunShell(command, silent_ok=False, universal_newlines=True,
-             print_output=False):
-  data, retcode = RunShellWithReturnCode(command, print_output,
-                                         universal_newlines)
-  if retcode:
-    ErrorExit("Got error status from %s:\n%s" % (command, data))
-  if not silent_ok and not data:
-    ErrorExit("No output from %s" % command)
-  return data
-
-
-class VersionControlSystem(object):
-  """Abstract base class providing an interface to the VCS."""
-
-  def __init__(self, options):
-    """Constructor.
-
-    Args:
-      options: Command line options.
-    """
-    self.options = options
-
-  def GenerateDiff(self, args):
-    """Return the current diff as a string.
-
-    Args:
-      args: Extra arguments to pass to the diff command.
-    """
-    raise NotImplementedError(
-        "abstract method -- subclass %s must override" % self.__class__)
-
-  def GetUnknownFiles(self):
-    """Return a list of files unknown to the VCS."""
-    raise NotImplementedError(
-        "abstract method -- subclass %s must override" % self.__class__)
-
-  def CheckForUnknownFiles(self):
-    """Show an "are you sure?" prompt if there are unknown files."""
-    unknown_files = self.GetUnknownFiles()
-    if unknown_files:
-      print "The following files are not added to version control:"
-      for line in unknown_files:
-        print line
-      prompt = "Are you sure to continue?(y/N) "
-      answer = raw_input(prompt).strip()
-      if answer != "y":
-        ErrorExit("User aborted")
-
-  def GetBaseFile(self, filename):
-    """Get the content of the upstream version of a file.
-
-    Returns:
-      A tuple (base_content, new_content, is_binary, status)
-        base_content: The contents of the base file.
-        new_content: For text files, this is empty.  For binary files, this is
-          the contents of the new file, since the diff output won't contain
-          information to reconstruct the current file.
-        is_binary: True iff the file is binary.
-        status: The status of the file.
-    """
-
-    raise NotImplementedError(
-        "abstract method -- subclass %s must override" % self.__class__)
-
-
-  def GetBaseFiles(self, diff):
-    """Helper that calls GetBase file for each file in the patch.
-    
-    Returns:
-      A dictionary that maps from filename to GetBaseFile's tuple.  Filenames
-      are retrieved based on lines that start with "Index:" or
-      "Property changes on:".
-    """
-    files = {}
-    for line in diff.splitlines(True):
-      if line.startswith('Index:') or line.startswith('Property changes on:'):
-        unused, filename = line.split(':', 1)
-        # On Windows if a file has property changes its filename uses '\'
-        # instead of '/'.
-        filename = filename.strip().replace('\\', '/')
-        files[filename] = self.GetBaseFile(filename)
-    return files
-
-
-  def UploadBaseFiles(self, issue, rpc_server, patch_list, patchset, options,
-                      files):
-    """Uploads the base files (and if necessary, the current ones as well)."""
-
-    def UploadFile(filename, file_id, content, is_binary, status, is_base):
-      """Uploads a file to the server."""
-      file_too_large = False
-      if is_base:
-        type = "base"
-      else:
-        type = "current"
-      if len(content) > MAX_UPLOAD_SIZE:
-        print ("Not uploading the %s file for %s because it's too large." %
-               (type, filename))
-        file_too_large = True
-        content = ""
-      checksum = md5.new(content).hexdigest()
-      if options.verbose > 0 and not file_too_large:
-        print "Uploading %s file for %s" % (type, filename)
-      url = "/%d/upload_content/%d/%d" % (int(issue), int(patchset), file_id)
-      form_fields = [("filename", filename),
-                     ("status", status),
-                     ("checksum", checksum),
-                     ("is_binary", str(is_binary)),
-                     ("is_current", str(not is_base)),
-                    ]
-      if file_too_large:
-        form_fields.append(("file_too_large", "1"))
-      if options.email:
-        form_fields.append(("user", options.email))
-      ctype, body = EncodeMultipartFormData(form_fields,
-                                            [("data", filename, content)])
-      response_body = rpc_server.Send(url, body,
-                                      content_type=ctype)
-      if not response_body.startswith("OK"):
-        StatusUpdate("  --> %s" % response_body)
-        sys.exit(1)
-
-    patches = dict()
-    [patches.setdefault(v, k) for k, v in patch_list]
-    for filename in patches.keys():
-      base_content, new_content, is_binary, status = files[filename]
-      file_id_str = patches.get(filename)
-      if file_id_str.find("nobase") != -1:
-        base_content = None
-        file_id_str = file_id_str[file_id_str.rfind("_") + 1:]
-      file_id = int(file_id_str)
-      if base_content != None:
-        UploadFile(filename, file_id, base_content, is_binary, status, True)
-      if new_content != None:
-        UploadFile(filename, file_id, new_content, is_binary, status, False)
-
-  def IsImage(self, filename):
-    """Returns true if the filename has an image extension."""
-    mimetype =  mimetypes.guess_type(filename)[0]
-    if not mimetype:
-      return False
-    return mimetype.startswith("image/")
-
-
-class SubversionVCS(VersionControlSystem):
-  """Implementation of the VersionControlSystem interface for Subversion."""
-
-  def __init__(self, options):
-    super(SubversionVCS, self).__init__(options)
-    if self.options.revision:
-      match = re.match(r"(\d+)(:(\d+))?", self.options.revision)
-      if not match:
-        ErrorExit("Invalid Subversion revision %s." % self.options.revision)
-      self.rev_start = match.group(1)
-      self.rev_end = match.group(3)
-    else:
-      self.rev_start = self.rev_end = None
-    # Cache output from "svn list -r REVNO dirname".
-    # Keys: dirname, Values: 2-tuple (ouput for start rev and end rev).
-    self.svnls_cache = {}
-    # SVN base URL is required to fetch files deleted in an older revision.
-    # Result is cached to not guess it over and over again in GetBaseFile().
-    required = self.options.download_base or self.options.revision is not None
-    self.svn_base = self._GuessBase(required)
-
-  def GuessBase(self, required):
-    """Wrapper for _GuessBase."""
-    return self.svn_base
-
-  def _GuessBase(self, required):
-    """Returns the SVN base URL.
-
-    Args:
-      required: If true, exits if the url can't be guessed, otherwise None is
-        returned.
-    """
-    info = RunShell(["svn", "info"])
-    for line in info.splitlines():
-      words = line.split()
-      if len(words) == 2 and words[0] == "URL:":
-        url = words[1]
-        scheme, netloc, path, params, query, fragment = urlparse.urlparse(url)
-        username, netloc = urllib.splituser(netloc)
-        if username:
-          logging.info("Removed username from base URL")
-        if netloc.endswith("svn.python.org"):
-          if netloc == "svn.python.org":
-            if path.startswith("/projects/"):
-              path = path[9:]
-          elif netloc != "pythondev@svn.python.org":
-            ErrorExit("Unrecognized Python URL: %s" % url)
-          base = "http://svn.python.org/view/*checkout*%s/" % path
-          logging.info("Guessed Python base = %s", base)
-        elif netloc.endswith("svn.collab.net"):
-          if path.startswith("/repos/"):
-            path = path[6:]
-          base = "http://svn.collab.net/viewvc/*checkout*%s/" % path
-          logging.info("Guessed CollabNet base = %s", base)
-        elif netloc.endswith(".googlecode.com"):
-          path = path + "/"
-          base = urlparse.urlunparse(("http", netloc, path, params,
-                                      query, fragment))
-          logging.info("Guessed Google Code base = %s", base)
-        else:
-          path = path + "/"
-          base = urlparse.urlunparse((scheme, netloc, path, params,
-                                      query, fragment))
-          logging.info("Guessed base = %s", base)
-        return base
-    if required:
-      ErrorExit("Can't find URL in output from svn info")
-    return None
-
-  def GenerateDiff(self, args):
-    cmd = ["svn", "diff"]
-    if self.options.revision:
-      cmd += ["-r", self.options.revision]
-    cmd.extend(args)
-    data = RunShell(cmd)
-    count = 0
-    for line in data.splitlines():
-      if line.startswith("Index:") or line.startswith("Property changes on:"):
-        count += 1
-        logging.info(line)
-    if not count:
-      ErrorExit("No valid patches found in output from svn diff")
-    return data
-
-  def _CollapseKeywords(self, content, keyword_str):
-    """Collapses SVN keywords."""
-    # svn cat translates keywords but svn diff doesn't. As a result of this
-    # behavior patching.PatchChunks() fails with a chunk mismatch error.
-    # This part was originally written by the Review Board development team
-    # who had the same problem (http://reviews.review-board.org/r/276/).
-    # Mapping of keywords to known aliases
-    svn_keywords = {
-      # Standard keywords
-      'Date':                ['Date', 'LastChangedDate'],
-      'Revision':            ['Revision', 'LastChangedRevision', 'Rev'],
-      'Author':              ['Author', 'LastChangedBy'],
-      'HeadURL':             ['HeadURL', 'URL'],
-      'Id':                  ['Id'],
-
-      # Aliases
-      'LastChangedDate':     ['LastChangedDate', 'Date'],
-      'LastChangedRevision': ['LastChangedRevision', 'Rev', 'Revision'],
-      'LastChangedBy':       ['LastChangedBy', 'Author'],
-      'URL':                 ['URL', 'HeadURL'],
-    }
-
-    def repl(m):
-       if m.group(2):
-         return "$%s::%s$" % (m.group(1), " " * len(m.group(3)))
-       return "$%s$" % m.group(1)
-    keywords = [keyword
-                for name in keyword_str.split(" ")
-                for keyword in svn_keywords.get(name, [])]
-    return re.sub(r"\$(%s):(:?)([^\$]+)\$" % '|'.join(keywords), repl, content)
-
-  def GetUnknownFiles(self):
-    status = RunShell(["svn", "status", "--ignore-externals"], silent_ok=True)
-    unknown_files = []
-    for line in status.split("\n"):
-      if line and line[0] == "?":
-        unknown_files.append(line)
-    return unknown_files
-
-  def ReadFile(self, filename):
-    """Returns the contents of a file."""
-    file = open(filename, 'rb')
-    result = ""
-    try:
-      result = file.read()
-    finally:
-      file.close()
-    return result
-
-  def GetStatus(self, filename):
-    """Returns the status of a file."""
-    if not self.options.revision:
-      status = RunShell(["svn", "status", "--ignore-externals", filename])
-      if not status:
-        ErrorExit("svn status returned no output for %s" % filename)
-      status_lines = status.splitlines()
-      # If file is in a cl, the output will begin with
-      # "\n--- Changelist 'cl_name':\n".  See
-      # http://svn.collab.net/repos/svn/trunk/notes/changelist-design.txt
-      if (len(status_lines) == 3 and
-          not status_lines[0] and
-          status_lines[1].startswith("--- Changelist")):
-        status = status_lines[2]
-      else:
-        status = status_lines[0]
-    # If we have a revision to diff against we need to run "svn list"
-    # for the old and the new revision and compare the results to get
-    # the correct status for a file.
-    else:
-      dirname, relfilename = os.path.split(filename)
-      if dirname not in self.svnls_cache:
-        cmd = ["svn", "list", "-r", self.rev_start, dirname or "."]
-        out, returncode = RunShellWithReturnCode(cmd)
-        if returncode:
-          ErrorExit("Failed to get status for %s." % filename)
-        old_files = out.splitlines()
-        args = ["svn", "list"]
-        if self.rev_end:
-          args += ["-r", self.rev_end]
-        cmd = args + [dirname or "."]
-        out, returncode = RunShellWithReturnCode(cmd)
-        if returncode:
-          ErrorExit("Failed to run command %s" % cmd)
-        self.svnls_cache[dirname] = (old_files, out.splitlines())
-      old_files, new_files = self.svnls_cache[dirname]
-      if relfilename in old_files and relfilename not in new_files:
-        status = "D   "
-      elif relfilename in old_files and relfilename in new_files:
-        status = "M   "
-      else:
-        status = "A   "
-    return status
-
-  def GetBaseFile(self, filename):
-    status = self.GetStatus(filename)
-    base_content = None
-    new_content = None
-
-    # If a file is copied its status will be "A  +", which signifies
-    # "addition-with-history".  See "svn st" for more information.  We need to
-    # upload the original file or else diff parsing will fail if the file was
-    # edited.
-    if status[0] == "A" and status[3] != "+":
-      # We'll need to upload the new content if we're adding a binary file
-      # since diff's output won't contain it.
-      mimetype = RunShell(["svn", "propget", "svn:mime-type", filename],
-                          silent_ok=True)
-      base_content = ""
-      is_binary = mimetype and not mimetype.startswith("text/")
-      if is_binary and self.IsImage(filename):
-        new_content = self.ReadFile(filename)
-    elif (status[0] in ("M", "D", "R") or
-          (status[0] == "A" and status[3] == "+") or  # Copied file.
-          (status[0] == " " and status[1] == "M")):  # Property change.
-      args = []
-      if self.options.revision:
-        url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start)
-      else:
-        # Don't change filename, it's needed later.
-        url = filename
-        args += ["-r", "BASE"]
-      cmd = ["svn"] + args + ["propget", "svn:mime-type", url]
-      mimetype, returncode = RunShellWithReturnCode(cmd)
-      if returncode:
-        # File does not exist in the requested revision.
-        # Reset mimetype, it contains an error message.
-        mimetype = ""
-      get_base = False
-      is_binary = mimetype and not mimetype.startswith("text/")
-      if status[0] == " ":
-        # Empty base content just to force an upload.
-        base_content = ""
-      elif is_binary:
-        if self.IsImage(filename):
-          get_base = True
-          if status[0] == "M":
-            if not self.rev_end:
-              new_content = self.ReadFile(filename)
-            else:
-              url = "%s/%s@%s" % (self.svn_base, filename, self.rev_end)
-              new_content = RunShell(["svn", "cat", url],
-                                     universal_newlines=True)
-        else:
-          base_content = ""
-      else:
-        get_base = True
-
-      if get_base:
-        if is_binary:
-          universal_newlines = False
-        else:
-          universal_newlines = True
-        if self.rev_start:
-          # "svn cat -r REV delete_file.txt" doesn't work. cat requires
-          # the full URL with "@REV" appended instead of using "-r" option.
-          url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start)
-          base_content = RunShell(["svn", "cat", url],
-                                  universal_newlines=universal_newlines)
-        else:
-          base_content = RunShell(["svn", "cat", filename],
-                                  universal_newlines=universal_newlines)
-        if not is_binary:
-          args = []
-          if self.rev_start:
-            url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start)
-          else:
-            url = filename
-            args += ["-r", "BASE"]
-          cmd = ["svn"] + args + ["propget", "svn:keywords", url]
-          keywords, returncode = RunShellWithReturnCode(cmd)
-          if keywords and not returncode:
-            base_content = self._CollapseKeywords(base_content, keywords)
-    else:
-      StatusUpdate("svn status returned unexpected output: %s" % status)
-      sys.exit(1)
-    return base_content, new_content, is_binary, status[0:5]
-
-
-class GitVCS(VersionControlSystem):
-  """Implementation of the VersionControlSystem interface for Git."""
-
-  def __init__(self, options):
-    super(GitVCS, self).__init__(options)
-    # Map of filename -> hash of base file.
-    self.base_hashes = {}
-
-  def GenerateDiff(self, extra_args):
-    # This is more complicated than svn's GenerateDiff because we must convert
-    # the diff output to include an svn-style "Index:" line as well as record
-    # the hashes of the base files, so we can upload them along with our diff.
-    if self.options.revision:
-      extra_args = [self.options.revision] + extra_args
-    gitdiff = RunShell(["git", "diff", "--full-index"] + extra_args)
-    svndiff = []
-    filecount = 0
-    filename = None
-    for line in gitdiff.splitlines():
-      match = re.match(r"diff --git a/(.*) b/.*$", line)
-      if match:
-        filecount += 1
-        filename = match.group(1)
-        svndiff.append("Index: %s\n" % filename)
-      else:
-        # The "index" line in a git diff looks like this (long hashes elided):
-        #   index 82c0d44..b2cee3f 100755
-        # We want to save the left hash, as that identifies the base file.
-        match = re.match(r"index (\w+)\.\.", line)
-        if match:
-          self.base_hashes[filename] = match.group(1)
-      svndiff.append(line + "\n")
-    if not filecount:
-      ErrorExit("No valid patches found in output from git diff")
-    return "".join(svndiff)
-
-  def GetUnknownFiles(self):
-    status = RunShell(["git", "ls-files", "--exclude-standard", "--others"],
-                      silent_ok=True)
-    return status.splitlines()
-
-  def GetBaseFile(self, filename):
-    hash = self.base_hashes[filename]
-    base_content = None
-    new_content = None
-    is_binary = False
-    if hash == "0" * 40:  # All-zero hash indicates no base file.
-      status = "A"
-      base_content = ""
-    else:
-      status = "M"
-      base_content = RunShell(["git", "show", hash])
-    return (base_content, new_content, is_binary, status)
-
-
-class MercurialVCS(VersionControlSystem):
-  """Implementation of the VersionControlSystem interface for Mercurial."""
-
-  def __init__(self, options, repo_dir):
-    super(MercurialVCS, self).__init__(options)
-    # Absolute path to repository (we can be in a subdir)
-    self.repo_dir = os.path.normpath(repo_dir)
-    # Compute the subdir
-    cwd = os.path.normpath(os.getcwd())
-    assert cwd.startswith(self.repo_dir)
-    self.subdir = cwd[len(self.repo_dir):].lstrip(r"\/")
-    if self.options.revision:
-      self.base_rev = self.options.revision
-    else:
-      self.base_rev = RunShell(["hg", "parent", "-q"]).split(':')[1].strip()
-
-  def _GetRelPath(self, filename):
-    """Get relative path of a file according to the current directory,
-    given its logical path in the repo."""
-    assert filename.startswith(self.subdir), filename
-    return filename[len(self.subdir):].lstrip(r"\/")
-
-  def GenerateDiff(self, extra_args):
-    # If no file specified, restrict to the current subdir
-    extra_args = extra_args or ["."]
-    cmd = ["hg", "diff", "--git", "-r", self.base_rev] + extra_args
-    data = RunShell(cmd, silent_ok=True)
-    svndiff = []
-    filecount = 0
-    for line in data.splitlines():
-      m = re.match("diff --git a/(\S+) b/(\S+)", line)
-      if m:
-        # Modify line to make it look like as it comes from svn diff.
-        # With this modification no changes on the server side are required
-        # to make upload.py work with Mercurial repos.
-        # NOTE: for proper handling of moved/copied files, we have to use
-        # the second filename.
-        filename = m.group(2)
-        svndiff.append("Index: %s" % filename)
-        svndiff.append("=" * 67)
-        filecount += 1
-        logging.info(line)
-      else:
-        svndiff.append(line)
-    if not filecount:
-      ErrorExit("No valid patches found in output from hg diff")
-    return "\n".join(svndiff) + "\n"
-
-  def GetUnknownFiles(self):
-    """Return a list of files unknown to the VCS."""
-    args = []
-    status = RunShell(["hg", "status", "--rev", self.base_rev, "-u", "."],
-        silent_ok=True)
-    unknown_files = []
-    for line in status.splitlines():
-      st, fn = line.split(" ", 1)
-      if st == "?":
-        unknown_files.append(fn)
-    return unknown_files
-
-  def GetBaseFile(self, filename):
-    # "hg status" and "hg cat" both take a path relative to the current subdir
-    # rather than to the repo root, but "hg diff" has given us the full path
-    # to the repo root.
-    base_content = ""
-    new_content = None
-    is_binary = False
-    oldrelpath = relpath = self._GetRelPath(filename)
-    # "hg status -C" returns two lines for moved/copied files, one otherwise
-    out = RunShell(["hg", "status", "-C", "--rev", self.base_rev, relpath])
-    out = out.splitlines()
-    # HACK: strip error message about missing file/directory if it isn't in
-    # the working copy
-    if out[0].startswith('%s: ' % relpath):
-      out = out[1:]
-    if len(out) > 1:
-      # Moved/copied => considered as modified, use old filename to 
-      # retrieve base contents
-      oldrelpath = out[1].strip()
-      status = "M"
-    else:
-      status, _ = out[0].split(' ', 1)
-    if status != "A":
-      base_content = RunShell(["hg", "cat", "-r", self.base_rev, oldrelpath],
-        silent_ok=True)
-      is_binary = "\0" in base_content  # Mercurial's heuristic
-    if status != "R":
-      new_content = open(relpath, "rb").read()
-      is_binary = is_binary or "\0" in new_content
-    if is_binary and base_content:
-      # Fetch again without converting newlines
-      base_content = RunShell(["hg", "cat", "-r", self.base_rev, oldrelpath],
-        silent_ok=True, universal_newlines=False)
-    if not is_binary or not self.IsImage(relpath):
-      new_content = None
-    return base_content, new_content, is_binary, status
-
-
-# NOTE: The SplitPatch function is duplicated in engine.py, keep them in sync.
-def SplitPatch(data):
-  """Splits a patch into separate pieces for each file.
-
-  Args:
-    data: A string containing the output of svn diff.
-
-  Returns:
-    A list of 2-tuple (filename, text) where text is the svn diff output
-      pertaining to filename.
-  """
-  patches = []
-  filename = None
-  diff = []
-  for line in data.splitlines(True):
-    new_filename = None
-    if line.startswith('Index:'):
-      unused, new_filename = line.split(':', 1)
-      new_filename = new_filename.strip()
-    elif line.startswith('Property changes on:'):
-      unused, temp_filename = line.split(':', 1)
-      # When a file is modified, paths use '/' between directories, however
-      # when a property is modified '\' is used on Windows.  Make them the same
-      # otherwise the file shows up twice.
-      temp_filename = temp_filename.strip().replace('\\', '/')
-      if temp_filename != filename:
-        # File has property changes but no modifications, create a new diff.
-        new_filename = temp_filename
-    if new_filename:
-      if filename and diff:
-        patches.append((filename, ''.join(diff)))
-      filename = new_filename
-      diff = [line]
-      continue
-    if diff is not None:
-      diff.append(line)
-  if filename and diff:
-    patches.append((filename, ''.join(diff)))
-  return patches
-
-
-def UploadSeparatePatches(issue, rpc_server, patchset, data, options):
-  """Uploads a separate patch for each file in the diff output.
-
-  Returns a list of [patch_key, filename] for each file.
-  """
-  patches = SplitPatch(data)
-  rv = []
-  for patch in patches:
-    if len(patch[1]) > MAX_UPLOAD_SIZE:
-      print ("Not uploading the patch for " + patch[0] +
-             " because the file is too large.")
-      continue
-    form_fields = [("filename", patch[0])]
-    if not options.download_base:
-      form_fields.append(("content_upload", "1"))
-    files = [("data", "data.diff", patch[1])]
-    ctype, body = EncodeMultipartFormData(form_fields, files)
-    url = "/%d/upload_patch/%d" % (int(issue), int(patchset))
-    print "Uploading patch for " + patch[0]
-    response_body = rpc_server.Send(url, body, content_type=ctype)
-    lines = response_body.splitlines()
-    if not lines or lines[0] != "OK":
-      StatusUpdate("  --> %s" % response_body)
-      sys.exit(1)
-    rv.append([lines[1], patch[0]])
-  return rv
-
-
-def GuessVCS(options):
-  """Helper to guess the version control system.
-
-  This examines the current directory, guesses which VersionControlSystem
-  we're using, and returns an instance of the appropriate class.  Exit with an
-  error if we can't figure it out.
-
-  Returns:
-    A VersionControlSystem instance. Exits if the VCS can't be guessed.
-  """
-  # Mercurial has a command to get the base directory of a repository
-  # Try running it, but don't die if we don't have hg installed.
-  # NOTE: we try Mercurial first as it can sit on top of an SVN working copy.
-  try:
-    out, returncode = RunShellWithReturnCode(["hg", "root"])
-    if returncode == 0:
-      return MercurialVCS(options, out.strip())
-  except OSError, (errno, message):
-    if errno != 2:  # ENOENT -- they don't have hg installed.
-      raise
-
-  # Subversion has a .svn in all working directories.
-  if os.path.isdir('.svn'):
-    logging.info("Guessed VCS = Subversion")
-    return SubversionVCS(options)
-
-  # Git has a command to test if you're in a git tree.
-  # Try running it, but don't die if we don't have git installed.
-  try:
-    out, returncode = RunShellWithReturnCode(["git", "rev-parse",
-                                              "--is-inside-work-tree"])
-    if returncode == 0:
-      return GitVCS(options)
-  except OSError, (errno, message):
-    if errno != 2:  # ENOENT -- they don't have git installed.
-      raise
-
-  ErrorExit(("Could not guess version control system. "
-             "Are you in a working copy directory?"))
-
-
-def RealMain(argv, data=None):
-  logging.basicConfig(format=("%(asctime).19s %(levelname)s %(filename)s:"
-                              "%(lineno)s %(message)s "))
-  os.environ['LC_ALL'] = 'C'
-  options, args = parser.parse_args(argv[1:])
-  global verbosity
-  verbosity = options.verbose
-  if verbosity >= 3:
-    logging.getLogger().setLevel(logging.DEBUG)
-  elif verbosity >= 2:
-    logging.getLogger().setLevel(logging.INFO)
-  vcs = GuessVCS(options)
-  if isinstance(vcs, SubversionVCS):
-    # base field is only allowed for Subversion.
-    # Note: Fetching base files may become deprecated in future releases.
-    base = vcs.GuessBase(options.download_base)
-  else:
-    base = None
-  if not base and options.download_base:
-    options.download_base = True
-    logging.info("Enabled upload of base file")
-  if not options.assume_yes:
-    vcs.CheckForUnknownFiles()
-  if data is None:
-    data = vcs.GenerateDiff(args)
-  files = vcs.GetBaseFiles(data)
-  if verbosity >= 1:
-    print "Upload server:", options.server, "(change with -s/--server)"
-  if options.issue:
-    prompt = "Message describing this patch set: "
-  else:
-    prompt = "New issue subject: "
-  message = options.message or raw_input(prompt).strip()
-  if not message:
-    ErrorExit("A non-empty message is required")
-  rpc_server = GetRpcServer(options)
-  form_fields = [("subject", message)]
-  if base:
-    form_fields.append(("base", base))
-  if options.issue:
-    form_fields.append(("issue", str(options.issue)))
-  if options.email:
-    form_fields.append(("user", options.email))
-  if options.reviewers:
-    for reviewer in options.reviewers.split(','):
-      if "@" in reviewer and not reviewer.split("@")[1].count(".") == 1:
-        ErrorExit("Invalid email address: %s" % reviewer)
-    form_fields.append(("reviewers", options.reviewers))
-  if options.cc:
-    for cc in options.cc.split(','):
-      if "@" in cc and not cc.split("@")[1].count(".") == 1:
-        ErrorExit("Invalid email address: %s" % cc)
-    form_fields.append(("cc", options.cc))
-  description = options.description
-  if options.description_file:
-    if options.description:
-      ErrorExit("Can't specify description and description_file")
-    file = open(options.description_file, 'r')
-    description = file.read()
-    file.close()
-  if description:
-    form_fields.append(("description", description))
-  # Send a hash of all the base file so the server can determine if a copy
-  # already exists in an earlier patchset.
-  base_hashes = ""
-  for file, info in files.iteritems():
-    if not info[0] is None:
-      checksum = md5.new(info[0]).hexdigest()
-      if base_hashes:
-        base_hashes += "|"
-      base_hashes += checksum + ":" + file
-  form_fields.append(("base_hashes", base_hashes))
-  # If we're uploading base files, don't send the email before the uploads, so
-  # that it contains the file status.
-  if options.send_mail and options.download_base:
-    form_fields.append(("send_mail", "1"))
-  if not options.download_base:
-    form_fields.append(("content_upload", "1"))
-  if len(data) > MAX_UPLOAD_SIZE:
-    print "Patch is large, so uploading file patches separately."
-    uploaded_diff_file = []
-    form_fields.append(("separate_patches", "1"))
-  else:
-    uploaded_diff_file = [("data", "data.diff", data)]
-  ctype, body = EncodeMultipartFormData(form_fields, uploaded_diff_file)
-  response_body = rpc_server.Send("/upload", body, content_type=ctype)
-  if not options.download_base or not uploaded_diff_file:
-    lines = response_body.splitlines()
-    if len(lines) >= 2:
-      msg = lines[0]
-      patchset = lines[1].strip()
-      patches = [x.split(" ", 1) for x in lines[2:]]
-    else:
-      msg = response_body
-  else:
-    msg = response_body
-  StatusUpdate(msg)
-  if not response_body.startswith("Issue created.") and \
-  not response_body.startswith("Issue updated."):
-    sys.exit(0)
-  issue = msg[msg.rfind("/")+1:]
-
-  if not uploaded_diff_file:
-    result = UploadSeparatePatches(issue, rpc_server, patchset, data, options)
-    if not options.download_base:
-      patches = result
-
-  if not options.download_base:
-    vcs.UploadBaseFiles(issue, rpc_server, patches, patchset, options, files)
-    if options.send_mail:
-      rpc_server.Send("/" + issue + "/mail", payload="")
-  return issue
-
-
-def main():
-  try:
-    RealMain(sys.argv)
-  except KeyboardInterrupt:
-    print
-    StatusUpdate("Interrupted.")
-    sys.exit(1)
-
-
-if __name__ == "__main__":
-  main()
diff --git a/thirdparty/svn/svn_load_dirs.pl b/thirdparty/svn/svn_load_dirs.pl
deleted file mode 100755
index 388ce68..0000000
--- a/thirdparty/svn/svn_load_dirs.pl
+++ /dev/null
@@ -1,2043 +0,0 @@
-#!/usr/bin/perl -w
-
-# $HeadURL$
-# $LastChangedDate$
-# $LastChangedBy$
-# $LastChangedRevision$
-
-$| = 1;
-
-use strict;
-use Carp;
-use Cwd;
-use Digest::MD5  2.20;
-use File::Copy   2.03;
-use File::Find;
-use File::Path   1.0404;
-use File::Temp   0.12   qw(tempdir tempfile);
-use Getopt::Long 2.25;
-use Text::Wrap;
-use URI          1.17;
-use English;
-
-$Text::Wrap::columns = 72;
-
-# Specify the location of the svn command.
-my $svn = 'svn';
-
-# Process the command line options.
-
-# The base URL for the portion of the repository to work in.  Note
-# that this does not have to be the root of the subversion repository,
-# it can point to a subdirectory in the repository.
-my $repos_base_url;
-
-# The relative path from the repository base URL to work in to the
-# directory to load the input directories into.
-my $repos_load_rel_path;
-
-# To specify where tags, which are simply copies of the imported
-# directory, should be placed relative to the repository base URL, use
-# the -t command line option.  This value must contain regular
-# expressions that match portions of the input directory names to
-# create an unique tag for each input directory.  The regular
-# expressions are surrounded by a specified character to distinguish
-# the regular expression from the normal directory path.
-my $opt_import_tag_location;
-
-# Do not ask for any user input.  Just go ahead and do everything.
-my $opt_no_user_input;
-
-# Do not automatically set the svn:executable property based on the
-# file's exe bit.
-my $opt_no_auto_exe;
-
-# Username to use for commits.
-my $opt_svn_username;
-
-# Password to use for commits.
-my $opt_svn_password;
-
-# Verbosity level.
-my $opt_verbose;
-
-# Path to already checked-out working copy.
-my $opt_existing_wc_dir;
-
-# List of filename patterns to ignore (as in .subversion/config's
-# "global-ignores" option).
-my $opt_glob_ignores;
-
-# This is the character used to separate regular expressions occuring
-# in the tag directory path from the path itself.
-my $REGEX_SEP_CHAR = '@';
-
-# This specifies a configuration file that contains a list of regular
-# expressions to check against a file and the properties to set on
-# matching files.
-my $property_config_filename;
-
-GetOptions('no_user_input'           => \$opt_no_user_input,
-           'no_auto_exe'             => \$opt_no_auto_exe,
-           'property_cfg_filename=s' => \$property_config_filename,
-           'svn_password=s'          => \$opt_svn_password,
-           'svn_username=s'          => \$opt_svn_username,
-           'tag_location=s'          => \$opt_import_tag_location,
-           'verbose+'                => \$opt_verbose,
-           'wc=s'                    => \$opt_existing_wc_dir,
-           'glob_ignores=s'          => \$opt_glob_ignores)
-  or &usage;
-&usage("$0: too few arguments") if @ARGV < 2;
-
-$repos_base_url      = shift;
-$repos_load_rel_path = shift;
-
-# Check that the repository base URL and the import directories do not
-# contain any ..'s.
-if ($repos_base_url =~ /\.{2}/)
-  {
-    die "$0: repos base URL $repos_base_url cannot contain ..'s.\n";
-  }
-if ($repos_load_rel_path =~ /\.{2}/)
-  {
-    die "$0: repos import relative directory path $repos_load_rel_path ",
-        "cannot contain ..'s.\n";
-  }
-
-# If there are no directories listed on the command line, then the
-# directories are read from standard input.  In this case, the
-# -no_user_input command line option must be specified.
-if (!@ARGV and !$opt_no_user_input)
-  {
-    &usage("$0: must use -no_user_input if no dirs listed on command line.");
-  }
-
-# The tag option cannot be used when directories are read from
-# standard input because tags may collide and no user input can be
-# taken to verify that the input is ok.
-if (!@ARGV and $opt_import_tag_location)
-  {
-    &usage("$0: cannot use -tag_location when dirs are read from stdin.");
-  }
-
-# If the tag directory is set, then the import directory cannot be '.'.
-if (defined $opt_import_tag_location and $repos_load_rel_path eq '.')
-  {
-    &usage("$0: cannot set import_dir to '.' and use -t command line option.");
-  }
-
-# Set the svn command line options that are used anytime svn connects
-# to the repository.
-my @svn_use_repos_cmd_opts;
-&set_svn_use_repos_cmd_opts($opt_svn_username, $opt_svn_password);
-
-# Check that the tag directories do not contain any ..'s.  Also, the
-# import and tag directories cannot be absolute.
-if (defined $opt_import_tag_location and $opt_import_tag_location =~ /\.{2}/)
-  {
-    die "$0: repos tag relative directory path $opt_import_tag_location ",
-        "cannot contain ..'s.\n";
-  }
-if ($repos_load_rel_path =~ m|^/|)
-  {
-    die "$0: repos import relative directory path $repos_load_rel_path ",
-        "cannot start with /.\n";
-  }
-if (defined $opt_import_tag_location and $opt_import_tag_location =~ m|^/|)
-  {
-    die "$0: repos tagrelative directory path $opt_import_tag_location ",
-        "cannot start with /.\n";
-  }
-
-if (defined $opt_existing_wc_dir)
-  {
-    unless (-e $opt_existing_wc_dir)
-      {
-        die "$0: working copy '$opt_existing_wc_dir' does not exist.\n";
-      }
-
-    unless (-d _)
-      {
-        die "$0: working copy '$opt_existing_wc_dir' is not a directory.\n";
-      }
-
-    unless (-d "$opt_existing_wc_dir/.svn")
-      {
-        die "$0: working copy '$opt_existing_wc_dir' does not have .svn ",
-            "directory.\n";
-      }
-
-    $opt_existing_wc_dir = Cwd::abs_path($opt_existing_wc_dir)
-  }
-
-# If no glob_ignores specified, try to deduce from config file,
-# or use the default below.
-my $ignores_str =
-    '*.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store';
-
-if ( defined $opt_glob_ignores)
-  {
-    $ignores_str = $opt_glob_ignores;
-  }
-elsif ( -f "$ENV{HOME}/.subversion/config" )
-  {
-    open my $conf, "$ENV{HOME}/.subversion/config";
-    while (<$conf>)
-      {
-        if ( /^global-ignores\s*=\s*(.*?)\s*$/ )
-          {
-	    $ignores_str = $1;
-            last;
-          }
-      }
-  }
-
-my @glob_ignores = map
-                     {
-                       s/\./\\\./g; s/\*/\.\*/g; "^$_\$";
-                     } split(/\s+/, $ignores_str);
-unshift @glob_ignores, '\.svn$';
-
-# Convert the string URL into a URI object.
-$repos_base_url    =~ s|/*$||;
-my $repos_base_uri = URI->new($repos_base_url);
-
-# Check that $repos_load_rel_path is not a directory here implying
-# that a command line option was forgotten.
-if ($repos_load_rel_path ne '.' and -d $repos_load_rel_path)
-  {
-    die "$0: import_dir '$repos_load_rel_path' is a directory.\n";
-  }
-
-# The remaining command line arguments should be directories.  Check
-# that they all exist and that there are no duplicates.
-if (@ARGV)
-  {
-    my %dirs;
-    foreach my $dir (@ARGV)
-      {
-        unless (-e $dir)
-          {
-            die "$0: directory '$dir' does not exist.\n";
-          }
-
-        unless (-d _)
-          {
-            die "$0: directory '$dir' is not a directory.\n";
-          }
-
-        if ($dirs{$dir})
-          {
-            die "$0: directory '$dir' is listed more than once on command ",
-                "line.\n";
-          }
-        $dirs{$dir} = 1;
-      }
-  }
-
-# Create the tag locations and print them for the user to review.
-# Check that there are no duplicate tags.
-my %load_tags;
-if (@ARGV and defined $opt_import_tag_location)
-  {
-    my %seen_tags;
-
-    foreach my $load_dir (@ARGV)
-      {
-        my $load_tag = &get_tag_dir($load_dir);
-
-        print "Directory $load_dir will be tagged as $load_tag\n";
-
-        if ($seen_tags{$load_tag})
-          {
-            die "$0: duplicate tag generated.\n";
-          }
-        $seen_tags{$load_tag} = 1;
-
-        $load_tags{$load_dir} = $load_tag;
-      }
-
-    exit 0 unless &get_answer("Please examine identified tags.  Are they " .
-                              "acceptable? (Y/n) ", 'ny', 1);
-    print "\n";
-  }
-
-# Load the property configuration filename, if one was specified, into
-# an array of hashes, where each hash contains a regular expression
-# and a property to apply to the file if the regular expression
-# matches.
-my @property_settings;
-if (defined $property_config_filename and length $property_config_filename)
-  {
-    open(CFG, $property_config_filename)
-      or die "$0: cannot open '$property_config_filename' for reading: $!\n";
-
-    my $ok = 1;
-
-    while (my $line = <CFG>)
-      {
-        next if $line =~ /^\s*$/;
-        next if $line =~ /^\s*#/;
-
-        # Split the input line into words taking into account that
-        # single or double quotes may define a single word with
-        # whitespace in it.  The format for the file is
-        # regex control property_name property_value
-        my @line = &split_line($line);
-        next if @line == 0;
-
-        unless (@line == 2 or @line == 4)
-          {
-            warn "$0: line $. of '$property_config_filename' has to have 2 ",
-                 "or 4 columns.\n";
-            $ok = 0;
-            next;
-          }
-        my ($regex, $control, $property_name, $property_value) = @line;
-
-        unless ($control eq 'break' or $control eq 'cont')
-          {
-            warn "$0: line $. of '$property_config_filename' has illegal ",
-                 "value for column 3 '$control', must be 'break' or 'cont'.\n";
-            $ok = 0;
-            next;
-          }
-
-        # Compile the regular expression.
-        my $re;
-        eval { $re = qr/$regex/i };
-        if ($@)
-          {
-            warn "$0: line $. of '$property_config_filename' regex '$regex' ",
-                 "does not compile:\n$@\n";
-            $ok = 0;
-            next;
-          }
-
-        push(@property_settings, {name    => $property_name,
-                                  value   => $property_value,
-                                  control => $control,
-                                  re      => $re});
-      }
-    close(CFG)
-      or warn "$0: error in closing '$property_config_filename' for ",
-              "reading: $!\n";
-
-    exit 1 unless $ok;
-  }
-
-# Check that the svn base URL works by running svn log on it.  Only
-# get the HEAD revision log message; there's no need to waste
-# bandwidth seeing all of the log messages.
-print "Checking that the base URL is a Subversion repository.\n";
-read_from_process($svn, 'log', '-r', 'HEAD',
-                  @svn_use_repos_cmd_opts, $repos_base_uri);
-print "\n";
-
-my $orig_cwd = cwd;
-
-# The first step is to determine the root of the svn repository.  Do
-# this with the svn log command.  Take the svn_url hostname and port
-# as the initial url and append to it successive portions of the final
-# path until svn log succeeds.
-print "Finding the root URL of the Subversion repository.\n";
-my $repos_root_uri;
-my $repos_root_uri_path;
-my $repos_base_path_segment;
-{
-  my $r = $repos_base_uri->clone;
-  my @path_segments            = grep { length($_) } $r->path_segments;
-  my @repos_base_path_segments = @path_segments;
-  unshift(@path_segments, '');
-  $r->path('');
-  my @r_path_segments;
-
-  while (@path_segments)
-    {
-      $repos_root_uri_path = shift @path_segments;
-      push(@r_path_segments, $repos_root_uri_path);
-      $r->path_segments(@r_path_segments);
-      if (safe_read_from_pipe($svn, 'log', '-r', 'HEAD',
-                              @svn_use_repos_cmd_opts, $r) == 0)
-        {
-          $repos_root_uri = $r;
-          last;
-        }
-      shift @repos_base_path_segments;
-    }
-  $repos_base_path_segment = join('/', @repos_base_path_segments);
-}
-
-if ($repos_root_uri)
-  {
-    print "Determined that the svn root URL is $repos_root_uri.\n\n";
-  }
-else
-  {
-    die "$0: cannot determine root svn URL.\n";
-  }
-
-# Create a temporary directory for svn to work in.
-my $temp_dir = tempdir( "svn_load_dirs_XXXXXXXXXX", TMPDIR => 1 );
-
-# Put in a signal handler to clean up any temporary directories.
-sub catch_signal {
-  my $signal = shift;
-  warn "$0: caught signal $signal.  Quitting now.\n";
-  exit 1;
-}
-
-$SIG{HUP}  = \&catch_signal;
-$SIG{INT}  = \&catch_signal;
-$SIG{TERM} = \&catch_signal;
-$SIG{PIPE} = \&catch_signal;
-
-# Create an object that when DESTROY'ed will delete the temporary
-# directory.  The CLEANUP flag to tempdir should do this, but they
-# call rmtree with 1 as the last argument which takes extra security
-# measures that do not clean up the .svn directories.
-my $temp_dir_cleanup = Temp::Delete->new;
-
-# Determine the native end of line style for this system.  Do this the
-# most portable way, by writing a file with a single \n in non-binary
-# mode and then reading the file in binary mode.
-my $native_eol = &determine_native_eol;
-
-# Check if all the directories exist to load the directories into the
-# repository.  If not, ask if they should be created.  For tags, do
-# not create the tag directory itself, that is done on the svn cp.
-{
-  print "Finding if any directories need to be created in repository.\n";
-
-  my @dirs_to_create;
-  my @urls_to_create;
-  my %seen_dir;
-  my @load_tags_without_last_segment;
-
-  # Assume that the last portion of the tag directory contains the
-  # version number and remove it from the directories to create,
-  # because the tag directory will be created by svn cp.
-  foreach my $load_tag (sort values %load_tags)
-    {
-      # Skip this tag if there is only one segment in its name.
-      my $index = rindex($load_tag, '/');
-      next if $index == -1;
-
-      # Trim off the last segment and record the result.
-      push(@load_tags_without_last_segment, substr($load_tag, 0, $index));
-    }
-  
-  foreach my $dir ($repos_load_rel_path, @load_tags_without_last_segment)
-    {
-      next unless length $dir;
-      my $d = '';
-      foreach my $segment (split('/', $dir))
-        {
-          $d = length $d ? "$d/$segment" : $segment;
-          my $url = "$repos_base_url/$d";
-          unless ($seen_dir{$d})
-            {
-              $seen_dir{$d} = 1;
-              if (safe_read_from_pipe($svn, 'log', '-r', 'HEAD',
-                                      @svn_use_repos_cmd_opts, $url) != 0)
-                {
-                  push(@dirs_to_create, $d);
-                  push(@urls_to_create, $url);
-                }
-            }
-        }
-    }
-
-  if (@dirs_to_create)
-    {
-      print "The following directories do not exist and need to exist:\n";
-      foreach my $dir (@dirs_to_create)
-        {
-          print "  $dir\n";
-        }
-      exit 0 unless &get_answer("You must add them now to load the " .
-                                "directories.  Continue (Y/n)? ", 'ny', 1);
-
-      my $message = "Create directories to load project into.\n\n";
-
-      foreach my $dir (@dirs_to_create)
-        {
-          if (length $repos_base_path_segment)
-            {
-              $message .= "* $repos_base_path_segment/$dir: New directory.\n";
-            }
-          else
-            {
-              $message .= "* $dir: New directory.\n";
-            }
-        }
-      $message = wrap('', '  ', $message);
-
-      read_from_process($svn, 'mkdir', @svn_use_repos_cmd_opts,
-                        '-m', $message, @urls_to_create);
-    }
-  else
-    {
-      print "No directories need to be created to prepare repository.\n";
-    }
-}
-
-# Either checkout a new working copy from the repository or use an
-# existing working copy.
-if (defined $opt_existing_wc_dir)
-  {
-    # Update an already existing working copy.
-    print "Not checking out anything; using existing working directory at\n";
-    print "$opt_existing_wc_dir\n";
-
-    chdir($opt_existing_wc_dir)
-      or die "$0: cannot chdir '$opt_existing_wc_dir': $!\n";
-
-    read_from_process($svn, 'update', @svn_use_repos_cmd_opts);
-  }
-else
-  {
-    # Check out the svn repository starting at the svn URL into a
-    # fixed directory name.
-    my $checkout_dir_name = 'my_import_wc';
-
-    # Check out only the directory being imported to, otherwise the
-    # checkout of the entire base URL can be very huge, if it contains
-    # a large number of tags.
-    my $checkout_url;
-    if ($repos_load_rel_path eq '.')
-      {
-        $checkout_url = $repos_base_url;
-      }
-    else
-      {
-        $checkout_url = "$repos_base_url/$repos_load_rel_path";
-      }
-
-    print "Checking out $checkout_url into $temp_dir/$checkout_dir_name\n";
-
-    chdir($temp_dir)
-      or die "$0: cannot chdir '$temp_dir': $!\n";
-
-    read_from_process($svn, 'checkout',
-                      @svn_use_repos_cmd_opts,
-                      $checkout_url, $checkout_dir_name);
-
-    chdir($checkout_dir_name)
-      or die "$0: cannot chdir '$checkout_dir_name': $!\n";
-  }
-
-# At this point, the current working directory is the top level
-# directory of the working copy.  Record the absolute path to this
-# location because the script will chdir back here later on.
-my $wc_import_dir_cwd = cwd;
-
-# Set up the names for the path to the import and tag directories.
-my $repos_load_abs_path;
-if ($repos_load_rel_path eq '.')
-  {
-    $repos_load_abs_path = length($repos_base_path_segment) ?
-                           $repos_base_path_segment : "/";
-  }
-else
-  {
-    $repos_load_abs_path = length($repos_base_path_segment) ?
-                           "$repos_base_path_segment/$repos_load_rel_path" :
-                           $repos_load_rel_path;
-  }
-
-# Now go through each source directory and copy each file from the
-# source directory to the target directory.  For new target files, add
-# them to svn.  For files that no longer exist, delete them.
-my $print_rename_message = 1;
-my @load_dirs            = @ARGV;
-while (defined (my $load_dir = &get_next_load_dir))
-  {
-    my $load_tag = $load_tags{$load_dir};
-
-    if (defined $load_tag)
-      {
-        print "\nLoading $load_dir and will save in tag $load_tag.\n";
-      }
-    else
-      {
-        print "\nLoading $load_dir.\n";
-      }
-
-    # The first hash is keyed by the old name in a rename and the
-    # second by the new name.  The last variable contains a list of
-    # old and new filenames in a rename.
-    my %rename_from_files;
-    my %rename_to_files;
-    my @renamed_filenames;
-
-    unless ($opt_no_user_input)
-      {
-        my $repeat_loop;
-        do
-          {
-            $repeat_loop = 0;
-
-            my %add_files;
-            my %del_files;
-
-            # Get the list of files and directories in the repository
-            # working copy.  This hash is called %del_files because
-            # each file or directory will be deleted from the hash
-            # using the list of files and directories in the source
-            # directory, leaving the files and directories that need
-            # to be deleted.
-            %del_files = &recursive_ls_and_hash($wc_import_dir_cwd);
-
-            # This anonymous subroutine finds all the files and
-            # directories in the directory to load.  It notes the file
-            # type and for each file found, it deletes it from
-            # %del_files.
-            my $wanted = sub
-              {
-                s#^\./##;
-                return if $_ eq '.';
-
-                my $source_path = $_;
-                my $dest_path   = "$wc_import_dir_cwd/$_";
-
-                my ($source_type) = &file_info($source_path);
-                my ($dest_type)   = &file_info($dest_path);
-
-                # Fail if the destination type exists but is of a
-                # different type of file than the source type.
-                if ($dest_type ne '0' and $source_type ne $dest_type)
-                  {
-                    die "$0: does not handle changing source and destination ",
-                        "type for '$source_path'.\n";
-                  }
-
-                if ($source_type ne 'd' and
-                    $source_type ne 'f' and
-                    $source_type ne 'l')
-                  {
-                    warn "$0: skipping loading file '$source_path' of type ",
-                         "'$source_type'.\n";
-                    unless ($opt_no_user_input)
-                      {
-                        print STDERR "Press return to continue: ";
-                        <STDIN>;
-                      }
-                    return;
-                  }
-
-                unless (defined delete $del_files{$source_path})
-                  {
-                    $add_files{$source_path}{type} = $source_type;
-                  }
-              };
-
-            # Now change into the directory containing the files to
-            # load.  First change to the original directory where this
-            # script was run so that if the specified directory is a
-            # relative directory path, then the script can change into
-            # it.
-            chdir($orig_cwd)
-              or die "$0: cannot chdir '$orig_cwd': $!\n";
-            chdir($load_dir)
-              or die "$0: cannot chdir '$load_dir': $!\n";
-
-            find({no_chdir   => 1,
-                  preprocess => sub { sort { $b cmp $a }
-                                      grep { $_ !~ /^[._]svn$/ } @_ },
-                  wanted     => $wanted
-                 }, '.');
-
-            # At this point %add_files contains the list of new files
-            # and directories to be created in the working copy tree
-            # and %del_files contains the files and directories that
-            # need to be deleted.  Because there may be renames that
-            # have taken place, give the user the opportunity to
-            # rename any deleted files and directories to ones being
-            # added.
-            my @add_files = sort keys %add_files;
-            my @del_files = sort keys %del_files;
-
-            # Because the source code management system may keep the
-            # original renamed file or directory in the working copy
-            # until a commit, remove them from the list of deleted
-            # files or directories.
-            &filter_renamed_files(\@del_files, \%rename_from_files);
-
-            # Now change into the working copy directory in case any
-            # renames need to be performed.
-            chdir($wc_import_dir_cwd)
-              or die "$0: cannot chdir '$wc_import_dir_cwd': $!\n";
-
-            # Only do renames if there are both added and deleted
-            # files and directories.
-            if (@add_files and @del_files)
-              {
-                my $max = @add_files > @del_files ? @add_files : @del_files;
-
-                # Print the files that have been added and deleted.
-                # Find the deleted file with the longest name and use
-                # that for the width of the filename column.  Add one
-                # to the filename width to let the directory /
-                # character be appended to a directory name.
-                my $line_number_width = 4;
-                my $filename_width    = 0;
-                foreach my $f (@del_files)
-                  {
-                    my $l = length($f);
-                    $filename_width = $l if $l > $filename_width;
-                  }
-                ++$filename_width;
-                my $printf_format = "%${line_number_width}d";
-
-                if ($print_rename_message)
-                  {
-                    $print_rename_message = 0;
-                    print "\n",
-                      "The following table lists files and directories that\n",
-                      "exist in either the Subversion repository or the\n",
-                      "directory to be imported but not both.  You now have\n",
-                      "the opportunity to match them up as renames instead\n",
-                      "of deletes and adds.  This is a Good Thing as it'll\n",
-                      "make the repository take less space.\n\n",
-                      "The left column lists files and directories that\n",
-                      "exist in the Subversion repository and do not exist\n",
-                      "in the directory being imported.  The right column\n",
-                      "lists files and directories that exist in the\n",
-                      "directory being imported.  Match up a deleted item\n",
-                      "from the left column with an added item from the\n",
-                      "right column.  Note the line numbers on the left\n",
-                      "which you type into this script to have a rename\n",
-                      "performed.\n";
-                  }
-
-                # Sort the added and deleted files and directories by
-                # the lowercase versions of their basenames instead of
-                # their complete path, which makes finding files that
-                # were moved into different directories easier to
-                # match up.
-                @add_files = map { $_->[0] }
-                             sort { $a->[1] cmp $b->[1] }
-                             map { [$_->[0], lc($_->[1])] }
-                             map { [$_, m#([^/]+)$#] }
-                             @add_files;
-                @del_files = map { $_->[0] }
-                             sort { $a->[1] cmp $b->[1] }
-                             map { [$_->[0], lc($_->[1])] }
-                             map { [$_, m#([^/]+)$#] }
-                             @del_files;
-
-              RELIST:
-
-                for (my $i=0; $i<$max; ++$i)
-                  {
-                    my $add_filename = '';
-                    my $del_filename = '';
-                    if ($i < @add_files)
-                      {
-                        $add_filename = $add_files[$i];
-                        if ($add_files{$add_filename}{type} eq 'd')
-                          {
-                            $add_filename .= '/';
-                          }
-                      }
-                    if ($i < @del_files)
-                      {
-                        $del_filename = $del_files[$i];
-                        if ($del_files{$del_filename}{type} eq 'd')
-                          {
-                            $del_filename .= '/';
-                          }
-                      }
-
-                    if ($i % 22 == 0)
-                      {
-                        print
-                          "\n",
-                          " " x $line_number_width,
-                          " ",
-                          "Deleted", " " x ($filename_width-length("Deleted")),
-                          " ",
-                          "Added\n";
-                      }
-
-                    printf $printf_format, $i;
-                    print  " ", $del_filename,
-                           "_" x ($filename_width - length($del_filename)),
-                           " ", $add_filename, "\n";
-
-                    if (($i+1) % 22 == 0)
-                      {
-                        unless (&get_answer("Continue printing (Y/n)? ",
-                                            'ny', 1))
-                          {
-                            last;
-                          }
-                      }
-                  }
-
-                # Get the feedback from the user.
-                my $line;
-                my $add_filename;
-                my $add_index;
-                my $del_filename;
-                my $del_index;
-                my $got_line = 0;
-                do {
-                  print "Enter two indexes for each column to rename, ",
-                        "(R)elist, or (F)inish: ";
-                  $line = <STDIN>;
-                  $line = '' unless defined $line;
-                  if ($line =~ /^R$/i )
-                    {
-                      goto RELIST;
-                    }
-                  
-                  if ($line =~ /^F$/i)
-                    {
-                      $got_line = 1;
-                    }
-                  elsif ($line =~ /^(\d+)\s+(\d+)$/)
-                    {
-                      print "\n";
-
-                      $del_index = $1;
-                      $add_index = $2;
-                      if ($del_index >= @del_files)
-                        {
-                          print "Delete index $del_index is larger than ",
-                                "maximum index of ", scalar @del_files - 1,
-                                ".\n";
-                          $del_index = undef;
-                        }
-                      if ($add_index > @add_files)
-                        {
-                          print "Add index $add_index is larger than maximum ",
-                                "index of ", scalar @add_files - 1, ".\n";
-                          $add_index = undef;
-                        }
-                      $got_line = defined $del_index && defined $add_index;
-
-                      # Check that the file or directory to be renamed
-                      # has the same file type.
-                      if ($got_line)
-                        {
-                          $add_filename = $add_files[$add_index];
-                          $del_filename = $del_files[$del_index];
-                          if ($add_files{$add_filename}{type} ne
-                              $del_files{$del_filename}{type})
-                            {
-                              print "File types for $del_filename and ",
-                                    "$add_filename differ.\n";
-                              $got_line = undef;
-                            }
-                        }
-                    }
-                } until ($got_line);
-
-                if ($line !~ /^F$/i)
-                  {
-                    print "Renaming $del_filename to $add_filename.\n";
-
-                    $repeat_loop = 1;
-
-                    # Because subversion cannot rename the same file
-                    # or directory twice, which includes doing a
-                    # rename of a file in a directory that was
-                    # previously renamed, a commit has to be
-                    # performed.  Check if the file or directory being
-                    # renamed now would cause such a problem and
-                    # commit if so.
-                    my $do_commit_now = 0;
-                    foreach my $rename_to_filename (keys %rename_to_files)
-                      {
-                        if (contained_in($del_filename,
-                                         $rename_to_filename,
-                                         $rename_to_files{$rename_to_filename}{type}))
-                          {
-                            $do_commit_now = 1;
-                            last;
-                          }
-                      }
-
-                    if ($do_commit_now)
-                      {
-                        print "Now committing previously run renames.\n";
-                        &commit_renames($load_dir,
-                                        \@renamed_filenames,
-                                        \%rename_from_files,
-                                        \%rename_to_files);
-                      }
-
-                    push(@renamed_filenames, $del_filename, $add_filename);
-                    {
-                      my $d = $del_files{$del_filename};
-                      $rename_from_files{$del_filename} = $d;
-                      $rename_to_files{$add_filename}   = $d;
-                    }
-
-                    # Check that any required directories to do the
-                    # rename exist.
-                    my @add_segments = split('/', $add_filename);
-                    pop(@add_segments);
-                    my $add_dir = '';
-                    my @add_dirs;
-                    foreach my $segment (@add_segments)
-                      {
-                        $add_dir = length($add_dir) ? "$add_dir/$segment" :
-                                                      $segment;
-                        unless (-d $add_dir)
-                          {
-                            push(@add_dirs, $add_dir);
-                          }
-                      }
-
-                    if (@add_dirs)
-                      {
-                        read_from_process($svn, 'mkdir', @add_dirs);
-                      }
-
-                    read_from_process($svn, 'mv',
-                                      $del_filename, $add_filename);
-                  }
-              }
-          } while ($repeat_loop);
-      }
-
-    # If there are any renames that have not been committed, then do
-    # that now.
-    if (@renamed_filenames)
-      {
-        &commit_renames($load_dir,
-                        \@renamed_filenames,
-                        \%rename_from_files,
-                        \%rename_to_files);
-      }
-
-    # At this point all renames have been performed.  Now get the
-    # final list of files and directories in the working copy
-    # directory.  The %add_files hash will contain the list of files
-    # and directories to add to the working copy and %del_files starts
-    # with all the files already in the working copy and gets files
-    # removed that are in the imported directory, which results in a
-    # list of files that should be deleted.  %upd_files holds the list
-    # of files that have been updated.
-    my %add_files;
-    my %del_files = &recursive_ls_and_hash($wc_import_dir_cwd);
-    my %upd_files;
-
-    # This anonymous subroutine copies files from the source directory
-    # to the working copy directory.
-    my $wanted = sub
-      {
-        s#^\./##;
-        return if $_ eq '.';
-
-        my $source_path = $_;
-        my $dest_path   = "$wc_import_dir_cwd/$_";
-
-        my ($source_type, $source_is_exe) = &file_info($source_path);
-        my ($dest_type)                   = &file_info($dest_path);
-
-        return if ($source_type ne 'd' and
-                   $source_type ne 'f' and
-                   $source_type ne 'l');
-
-        # Fail if the destination type exists but is of a different
-        # type of file than the source type.
-        if ($dest_type ne '0' and $source_type ne $dest_type)
-          {
-            die "$0: does not handle changing source and destination type ",
-                "for '$source_path'.\n";
-          }
-
-        # Determine if the file is being added or is an update to an
-        # already existing file using the file's digest.
-        my $del_info = delete $del_files{$source_path};
-        if (defined $del_info)
-          {
-            if (defined (my $del_digest = $del_info->{digest}))
-              {
-                my $new_digest = &digest_hash_file($source_path);
-                if ($new_digest ne $del_digest)
-                  {
-                    print "U   $source_path\n";
-                    $upd_files{$source_path} = $del_info;
-                  }
-              }
-          }
-        else
-          {
-            print "A   $source_path\n";
-            $add_files{$source_path}{type} = $source_type;
-
-            # Create an array reference to hold the list of properties
-            # to apply to this object.
-            unless (defined $add_files{$source_path}{properties})
-              {
-                $add_files{$source_path}{properties} = [];
-              }
-
-            # Go through the list of properties for a match on this
-            # file or directory and if there is a match, then apply
-            # the property to it.
-            foreach my $property (@property_settings)
-              {
-                my $re = $property->{re};
-                if ($source_path =~ $re)
-                  {
-                    my $property_name  = $property->{name};
-                    my $property_value = $property->{value};
-
-                    # The property value may not be set in the
-                    # configuration file, since the user may just want
-                    # to set the control flag.
-                    if (defined $property_name and defined $property_value)
-                      {
-                        # Ignore properties that do not apply to
-                        # directories.
-                        if ($source_type eq 'd')
-                          {
-                            if ($property_name eq 'svn:eol-style' or
-                                $property_name eq 'svn:executable' or
-                                $property_name eq 'svn:keywords' or
-                                $property_name eq 'svn:mime-type')
-                              {
-                                next;
-                              }
-                          }
-
-                        # Ignore properties that do not apply to
-                        # files.
-                        if ($source_type eq 'f')
-                          {
-                            if ($property_name eq 'svn:externals' or
-                                $property_name eq 'svn:ignore')
-                              {
-                                next;
-                              }
-                          }
-
-                        print "Adding to '$source_path' property ",
-                              "'$property_name' with value ",
-                              "'$property_value'.\n";
-
-                        push(@{$add_files{$source_path}{properties}},
-                             $property);
-                      }
-
-                    last if $property->{control} eq 'break';
-                  }
-              }
-          }
-
-        # Add svn:executable to files that have their executable bit
-        # set.
-        if ($source_is_exe and !$opt_no_auto_exe)
-          {
-            print "Adding to '$source_path' property 'svn:executable' with ",
-                  "value '*'.\n";
-            my $property = {name => 'svn:executable', value => '*'};
-            push (@{$add_files{$source_path}{properties}},
-                  $property);
-          }
-
-        # Now make sure the file or directory in the source directory
-        # exists in the repository.
-        if ($source_type eq 'd')
-          {
-            if ($dest_type eq '0')
-              {
-                mkdir($dest_path)
-                  or die "$0: cannot mkdir '$dest_path': $!\n";
-              }
-          }
-        elsif
-          ($source_type eq 'l') {
-            my $link_target = readlink($source_path)
-              or die "$0: cannot readlink '$source_path': $!\n";
-            if ($dest_type eq 'l')
-              {
-                my $old_target = readlink($dest_path)
-                  or die "$0: cannot readlink '$dest_path': $!\n";
-                return if ($old_target eq $link_target);
-                unlink($dest_path)
-                  or die "$0: unlink '$dest_path' failed: $!\n";
-              }
-            symlink($link_target, $dest_path)
-              or die "$0: cannot symlink '$dest_path' to '$link_target': $!\n";
-          }
-        elsif
-          ($source_type eq 'f') {
-            # Only copy the file if the digests do not match.
-            if ($add_files{$source_path} or $upd_files{$source_path})
-              {
-                copy($source_path, $dest_path)
-                  or die "$0: copy '$source_path' to '$dest_path': $!\n";
-              }
-          }
-        else
-          {
-            die "$0: does not handle copying files of type '$source_type'.\n";
-          }
-      };
-
-    # Now change into the directory containing the files to load.
-    # First change to the original directory where this script was run
-    # so that if the specified directory is a relative directory path,
-    # then the script can change into it.
-    chdir($orig_cwd)
-      or die "$0: cannot chdir '$orig_cwd': $!\n";
-    chdir($load_dir)
-      or die "$0: cannot chdir '$load_dir': $!\n";
-
-    find({no_chdir   => 1,
-          preprocess => sub { sort { $b cmp $a }
-                              grep { $_ !~ /^[._]svn$/ } @_ },
-          wanted     => $wanted
-         }, '.');
-
-    # The files and directories that are in %del_files are the files
-    # and directories that need to be deleted.  Because svn will
-    # return an error if a file or directory is deleted in a directory
-    # that subsequently is deleted, first find all directories and
-    # remove from the list any files and directories inside those
-    # directories from this list.  Work through the list repeatedly
-    # working from short to long names so that directories containing
-    # other files and directories will be deleted first.
-    my $repeat_loop;
-    do
-      {
-        $repeat_loop = 0;
-        my @del_files = sort {length($a) <=> length($b) || $a cmp $b}
-                        keys %del_files;
-        &filter_renamed_files(\@del_files, \%rename_from_files);
-        foreach my $file (@del_files)
-          {
-            if ($del_files{$file}{type} eq 'd')
-              {
-                my $dir        = "$file/";
-                my $dir_length = length($dir);
-                foreach my $f (@del_files)
-                  {
-                    next if $file eq $f;
-                    if (length($f) >= $dir_length and
-                        substr($f, 0, $dir_length) eq $dir)
-                      {
-                        print "d   $f\n";
-                        delete $del_files{$f};
-                        $repeat_loop = 1;
-                      }
-                  }
-
-                # If there were any deletions of files and/or
-                # directories inside a directory that will be deleted,
-                # then restart the entire loop again, because one or
-                # more keys have been deleted from %del_files.
-                # Equally important is not to stop this loop if no
-                # deletions have been done, otherwise later
-                # directories that may contain files and directories
-                # to be deleted will not be deleted.
-                last if $repeat_loop;
-              }
-          }
-      } while ($repeat_loop);
-
-    # What is left are files that are not in any directories to be
-    # deleted and directories to be deleted.  To delete the files,
-    # deeper files and directories must be deleted first.  Because we
-    # have a hash keyed by remaining files and directories to be
-    # deleted, instead of trying to figure out which directories and
-    # files are contained in other directories, just reverse sort by
-    # the path length and then alphabetically.
-    my @del_files = sort {length($b) <=> length($a) || $a cmp $b }
-                    keys %del_files;
-    &filter_renamed_files(\@del_files, \%rename_from_files);
-    foreach my $file (@del_files)
-      {
-        print "D   $file\n";
-      }
-
-    # Now change back to the trunk directory and run the svn commands.
-    chdir($wc_import_dir_cwd)
-      or die "$0: cannot chdir '$wc_import_dir_cwd': $!\n";
-
-    # If any of the added files have the svn:eol-style property set,
-    # then pass -b to diff, otherwise diff may fail because the end of
-    # lines have changed and the source file and file in the
-    # repository will not be identical.
-    my @diff_ignore_space_changes;
-
-    if (keys %add_files)
-      {
-        my @add_files = sort {length($a) <=> length($b) || $a cmp $b}
-                        keys %add_files;
-        my $target_filename = &make_targets_file(@add_files);
-        read_from_process($svn, 'add', '-N', '--targets', $target_filename);
-        unlink($target_filename);
-
-        # Add properties on the added files.
-        foreach my $add_file (@add_files)
-          {
-            foreach my $property (@{$add_files{$add_file}{properties}})
-              {
-                my $property_name  = $property->{name};
-                my $property_value = $property->{value};
-
-                if ($property_name eq 'svn:eol-style')
-                  {
-                    @diff_ignore_space_changes = ('-b');
-                  }
-                
-                # Write the value to a temporary file in case it's multi-line
-                my ($handle, $tmpfile) = tempfile(DIR => $temp_dir);
-                print $handle $property_value;
-                close($handle);
-
-                read_from_process($svn,
-                                  'propset',
-                                  $property_name,
-                                  '--file',
-                                  $tmpfile,
-                                  $add_file);
-              }
-          }
-      }
-    if (@del_files)
-      {
-        my $target_filename = &make_targets_file(@del_files);
-        read_from_process($svn, 'rm', '--targets', $target_filename);
-        unlink($target_filename);
-      }
-
-    # Go through the list of updated files and check the svn:eol-style
-    # property.  If it is set to native, then convert all CR, CRLF and
-    # LF's in the file to the native end of line characters.  Also,
-    # modify diff's command line so that it will ignore the change in
-    # end of line style.
-    if (keys %upd_files)
-      {
-        my @upd_files = sort {length($a) <=> length($b) || $a cmp $b}
-                        keys %upd_files;
-        foreach my $upd_file (@upd_files)
-          {
-            # Always append @BASE to a filename in case they contain a
-            # @ character, in which case the Subversion command line
-            # client will attempt to parse the characters after the @
-            # as a revision and most likely fail, or if the characters
-            # after the @ are a valid revision, then it'll possibly
-            # get the incorrect information.  So always append @BASE
-            # and any preceding @'s will be treated normally and the
-            # correct information will be retrieved.
-            my @command = ($svn,
-                           'propget',
-                           'svn:eol-style',
-                           "$upd_file\@BASE");
-            my @lines = read_from_process(@command);
-            next unless @lines;
-            if (@lines > 1)
-              {
-                warn "$0: '@command' returned more than one line of output: ",
-                  "'@lines'.\n";
-                next;
-              }
-
-            my $eol_style = $lines[0];
-            if ($eol_style eq 'native')
-              {
-                @diff_ignore_space_changes = ('-b');
-                if (&convert_file_to_native_eol($upd_file))
-                  {
-                    print "Native eol-style conversion modified $upd_file.\n";
-                  }
-              }
-          }
-      }
-
-    my $message = wrap('', '', "Load $load_dir into $repos_load_abs_path.\n");
-    read_from_process($svn, 'commit',
-                      @svn_use_repos_cmd_opts,
-                      '-m', $message);
-
-    # If an update is not run now after a commit, then some file and
-    # directory paths will have an older revisions associated with
-    # them and any future commits will fail because they are out of
-    # date.
-    read_from_process($svn, 'update', @svn_use_repos_cmd_opts);
-
-    # Now remove any files and directories to be deleted in the
-    # repository.
-    if (@del_files)
-      {
-        rmtree(\@del_files, 1, 0);
-      }
-
-    # Now make the tag by doing a copy in the svn repository itself.
-    if (defined $load_tag)
-      {
-        my $repos_tag_abs_path = length($repos_base_path_segment) ?
-                                 "$repos_base_path_segment/$load_tag" :
-                                 $load_tag;
-
-        my $from_url = $repos_load_rel_path eq '.' ?
-                       $repos_load_rel_path :
-                       "$repos_base_url/$repos_load_rel_path";
-        my $to_url   = "$repos_base_url/$load_tag";
-
-        $message     = wrap("",
-                            "",
-                            "Tag $repos_load_abs_path as " .
-                            "$repos_tag_abs_path.\n");
-        read_from_process($svn, 'cp', @svn_use_repos_cmd_opts,
-                          '-m', $message, $from_url, $to_url);
-
-        # Now check out the tag and run a recursive diff between the
-        # original source directory and the tag for a consistency
-        # check.
-        my $checkout_dir_name = "my_tag_wc_named_$load_tag";
-        print "Checking out $to_url into $temp_dir/$checkout_dir_name\n";
-
-        chdir($temp_dir)
-          or die "$0: cannot chdir '$temp_dir': $!\n";
-
-        read_from_process($svn, 'checkout',
-                          @svn_use_repos_cmd_opts,
-                          $to_url, $checkout_dir_name);
-
-        chdir($checkout_dir_name)
-          or die "$0: cannot chdir '$checkout_dir_name': $!\n";
-
-        chdir($orig_cwd)
-          or die "$0: cannot chdir '$orig_cwd': $!\n";
-        read_from_process('diff', '-u', @diff_ignore_space_changes,
-                          '-x', '.svn',
-                          '-r', $load_dir, "$temp_dir/$checkout_dir_name");
-      }
-  }
-
-exit 0;
-
-sub usage
-{
-  warn "@_\n" if @_;
-  die "usage: $0 [options] svn_url svn_import_dir [dir_v1 [dir_v2 [..]]]\n",
-      "  svn_url        is the file:// or http:// URL of the svn repository\n",
-      "  svn_import_dir is the path relative to svn_url where to load dirs\n",
-      "  dir_v1 ..      list dirs to import otherwise read from stdin\n",
-      "options are\n",
-      "  -no_user_input don't ask yes/no questions and assume yes answer\n",
-      "  -no_auto_exe   don't set svn:executable for executable files\n",
-      "  -p filename    table listing properties to apply to matching files\n",
-      "  -svn_username  username to perform commits as\n",
-      "  -svn_password  password to supply to svn commit\n",
-      "  -t tag_dir     create a tag copy in tag_dir, relative to svn_url\n",
-      "  -v             increase program verbosity, multiple -v's allowed\n",
-      "  -wc path       use the already checked-out working copy at path\n",
-      "                 instead of checkout out a fresh working copy\n",
-      "  -glob_ignores  List of filename patterns to ignore (as in svn's\n",
-      "                 global-ignores config option)\n";
-}
-
-# Get the next directory to load, either from the command line or from
-# standard input.
-my $get_next_load_dir_init = 0;
-my @get_next_load_dirs;
-sub get_next_load_dir
-{
-  if (@ARGV)
-    {
-      unless ($get_next_load_dir_init)
-        {
-          $get_next_load_dir_init = 1;
-          @get_next_load_dirs     = @ARGV;
-        }
-      return shift @get_next_load_dirs;
-    }
-
-  if ($opt_verbose)
-    {
-      print "Waiting for next directory to import on standard input:\n";
-    }
-  my $line = <STDIN>;
-
-  print "\n" if $opt_verbose;
-
-  chomp $line;
-  if ($line =~ m|(\S+)\s+(\S+)|)
-    {
-      $line = $1;
-      set_svn_use_repos_cmd_opts($2, $opt_svn_password);
-    }
-  $line;
-}
-
-# This constant stores the commonly used string to indicate that a
-# subroutine has been passed an incorrect number of arguments.
-use vars qw($INCORRECT_NUMBER_OF_ARGS);
-$INCORRECT_NUMBER_OF_ARGS = "passed incorrect number of arguments.\n";
-
-# Creates a temporary file in the temporary directory and stores the
-# arguments in it for use by the svn --targets command line option.
-# If any part of the file creation failed, exit the program, as
-# there's no workaround.  Use a unique number as a counter to the
-# files.
-my $make_targets_file_counter;
-sub make_targets_file
-{
-  unless (@_)
-    {
-      confess "$0: make_targets_file $INCORRECT_NUMBER_OF_ARGS";
-    }
-
-  $make_targets_file_counter = 1 unless defined $make_targets_file_counter;
-
-  my $filename = sprintf "%s/targets.%05d",
-                 $temp_dir,
-                 $make_targets_file_counter;
-  ++$make_targets_file_counter;
-
-  open(TARGETS, ">$filename")
-    or die "$0: cannot open '$filename' for writing: $!\n";
-
-  foreach my $file (@_)
-    {
-      print TARGETS "$file\n";
-    }
-
-  close(TARGETS)
-    or die "$0: error in closing '$filename' for writing: $!\n";
-
-  $filename;
-}
-
-# Set the svn command line options that are used anytime svn connects
-# to the repository.
-sub set_svn_use_repos_cmd_opts
-{
-  unless (@_ == 2)
-    {
-      confess "$0: set_svn_use_repos_cmd_opts $INCORRECT_NUMBER_OF_ARGS";
-    }
-
-  my $username = shift;
-  my $password = shift;
-
-  @svn_use_repos_cmd_opts = ('--non-interactive');
-  if (defined $username and length $username)
-    {
-      push(@svn_use_repos_cmd_opts, '--username', $username);
-    }
-  if (defined $password)
-    {
-      push(@svn_use_repos_cmd_opts, '--password', $password);
-    }
-}
-
-sub get_tag_dir
-{
-  unless (@_ == 1)
-    {
-      confess "$0: get_tag_dir $INCORRECT_NUMBER_OF_ARGS";
-    }
-
-  my $load_dir = shift;
-
-  # Take the tag relative directory, search for pairs of
-  # REGEX_SEP_CHAR's and use the regular expression inside the pair to
-  # put in the tag directory name.
-  my $tag_location = $opt_import_tag_location;
-  my $load_tag     = '';
-  while ((my $i = index($tag_location, $REGEX_SEP_CHAR)) >= 0)
-    {
-      $load_tag .= substr($tag_location, 0, $i, '');
-      substr($tag_location, 0, 1, '');
-      my $j = index($tag_location, $REGEX_SEP_CHAR);
-      if ($j < 0)
-        {
-          die "$0: -t value '$opt_import_tag_location' does not have ",
-              "matching $REGEX_SEP_CHAR.\n";
-        }
-      my $regex = substr($tag_location, 0, $j, '');
-      $regex = "($regex)" unless ($regex =~ /\(.+\)/);
-      substr($tag_location, 0, 1, '');
-      my @results = $load_dir =~ m/$regex/;
-      $load_tag .= join('', @results);
-    }
-  $load_tag .= $tag_location;
-
-  $load_tag;
-}
-
-# Return a two element array.  The first element is a single character
-# that represents the type of object the path points to.  The second
-# is a boolean (1 for true, '' for false) if the path points to a file
-# and if the file is executable.
-sub file_info
-{
-  lstat(shift) or return ('0', '');
-  -b _ and return ('b', '');
-  -c _ and return ('c', '');
-  -d _ and return ('d', '');
-  -f _ and return ('f', -x _);
-  -l _ and return ('l', '');
-  -p _ and return ('p', '');
-  -S _ and return ('S', '');
-  return '?';
-}
-
-# Start a child process safely without using /bin/sh.
-sub safe_read_from_pipe
-{
-  unless (@_)
-    {
-      croak "$0: safe_read_from_pipe $INCORRECT_NUMBER_OF_ARGS";
-    }
-
-  my $openfork_available = "MSWin32" ne $OSNAME;
-  if ($openfork_available)
-    {
-      print "Running @_\n";
-      my $pid = open(SAFE_READ, "-|");
-      unless (defined $pid)
-        {
-          die "$0: cannot fork: $!\n";
-        }
-      unless ($pid)
-        {
-          # child
-          open(STDERR, ">&STDOUT")
-            or die "$0: cannot dup STDOUT: $!\n";
-          exec(@_)
-            or die "$0: cannot exec '@_': $!\n";
-        }
-    }
-  else
-    {
-      # Redirect the comment into a temp file and use that to work around
-      # Windoze's (non-)handling of multi-line commands.
-      my @commandline = ();
-      my $command;
-      my $comment;
-        
-      while ($command = shift)
-        {
-          if ("-m" eq $command)
-            {
-              my $comment = shift;
-              my ($handle, $tmpfile) = tempfile(DIR => $temp_dir);
-              print $handle $comment;
-              close($handle);
-                
-              push(@commandline, "--file");
-              push(@commandline, $tmpfile);
-            }
-          else
-            {
-              # Munge the command to protect it from the command line
-              $command =~ s/\"/\\\"/g;
-              if ($command =~ m"\s") { $command = "\"$command\""; }
-              if ($command eq "") { $command = "\"\""; }
-              if ($command =~ m"\n")
-                {
-                  warn "$0: carriage return detected in command - may not work\n";
-                }
-              push(@commandline, $command);
-            }
-        }
-        
-      print "Running @commandline\n";
-      if ( $comment ) { print $comment; }
-        
-      # Now do the pipe.
-      open(SAFE_READ, "@commandline |")
-        or die "$0: cannot pipe to command: $!\n";
-    }
-    
-  # parent
-  my @output;
-  while (<SAFE_READ>)
-    {
-      chomp;
-      push(@output, $_);
-    }
-  close(SAFE_READ);
-  my $result = $?;
-  my $exit   = $result >> 8;
-  my $signal = $result & 127;
-  my $cd     = $result & 128 ? "with core dump" : "";
-  if ($signal or $cd)
-    {
-      warn "$0: pipe from '@_' failed $cd: exit=$exit signal=$signal\n";
-    }
-  if (wantarray)
-    {
-      return ($result, @output);
-    }
-  else
-    {
-      return $result;
-    }
-}
-
-# Use safe_read_from_pipe to start a child process safely and exit the
-# script if the child failed for whatever reason.
-sub read_from_process
-{
-  unless (@_)
-    {
-      croak "$0: read_from_process $INCORRECT_NUMBER_OF_ARGS";
-    }
-  my ($status, @output) = &safe_read_from_pipe(@_);
-  if ($status)
-    {
-      print STDERR "$0: @_ failed with this output:\n", join("\n", @output),
-                   "\n";
-      unless ($opt_no_user_input)
-        {
-          print STDERR
-            "Press return to quit and clean up svn working directory: ";
-          <STDIN>;
-        }
-      exit 1;
-    }
-  else
-    {
-      return @output;
-    }
-}
-
-# Get a list of all the files and directories in the specified
-# directory, the type of file and a digest hash of file types.
-sub recursive_ls_and_hash
-{
-  unless (@_ == 1)
-    {
-      croak "$0: recursive_ls_and_hash $INCORRECT_NUMBER_OF_ARGS";
-    }
-
-  # This is the directory to change into.
-  my $dir = shift;
-
-  # Get the current directory so that the script can change into the
-  # current working directory after changing into the specified
-  # directory.
-  my $return_cwd = cwd;
-
-  chdir($dir)
-    or die "$0: cannot chdir '$dir': $!\n";
-
-  my %files;
-
-  my $wanted = sub
-    {
-      s#^\./##;
-      return if $_ eq '.';
-      my ($file_type) = &file_info($_);
-      my $file_digest;
-      if ($file_type eq 'f' or ($file_type eq 'l' and stat($_) and -f _))
-        {
-          $file_digest = &digest_hash_file($_);
-        }
-      $files{$_} = {type   => $file_type,
-                    digest => $file_digest};
-    };
-  find({no_chdir   => 1,
-        preprocess => sub
-	  {
-            grep
-              {
-                my $ok=1;
-                foreach my $x (@glob_ignores)
-                  {
-                    if ( $_ =~ /$x/ ) {$ok=0;last;}
-                  }
-                $ok
-              } @_
-          },
-        wanted     => $wanted
-       }, '.');
-
-  chdir($return_cwd)
-    or die "$0: cannot chdir '$return_cwd': $!\n";
-
-  %files;
-}
-
-# Given a list of files and directories which have been renamed but
-# not commtited, commit them with a proper log message.
-sub commit_renames
-{
-  unless (@_ == 4)
-    {
-      croak "$0: commit_renames $INCORRECT_NUMBER_OF_ARGS";
-    }
-
-  my $load_dir          = shift;
-  my $renamed_filenames = shift;
-  my $rename_from_files = shift;
-  my $rename_to_files   = shift;
-
-  my $number_renames    = @$renamed_filenames/2;
-
-  my $message = "To prepare to load $load_dir into $repos_load_abs_path, " .
-                "perform $number_renames rename" .
-                ($number_renames > 1 ? "s" : "") . ".\n";
-
-  # Text::Wrap::wrap appears to replace multiple consecutive \n's with
-  # one \n, so wrap the text and then append the second \n.
-  $message  = wrap("", "", $message) . "\n";
-  while (@$renamed_filenames)
-    {
-      my $from  = "$repos_load_abs_path/" . shift @$renamed_filenames;
-      my $to    = "$repos_load_abs_path/" . shift @$renamed_filenames;
-      $message .= wrap("", "  ", "* $to: Renamed from $from.\n");
-    }
-
-  # Change to the top of the working copy so that any
-  # directories will also be updated.
-  my $cwd = cwd;
-  chdir($wc_import_dir_cwd)
-    or die "$0: cannot chdir '$wc_import_dir_cwd': $!\n";
-  read_from_process($svn, 'commit', @svn_use_repos_cmd_opts, '-m', $message);
-  read_from_process($svn, 'update', @svn_use_repos_cmd_opts);
-  chdir($cwd)
-    or die "$0: cannot chdir '$cwd': $!\n";
-
-  # Some versions of subversion have a bug where renamed files
-  # or directories are not deleted after a commit, so do that
-  # here.
-  my @del_files = sort {length($b) <=> length($a) || $a cmp $b }
-                  keys %$rename_from_files;
-  rmtree(\@del_files, 1, 0);
-
-  # Empty the list of old and new renamed names.
-  undef %$rename_from_files;
-  undef %$rename_to_files;
-}
-
-# Take a one file or directory and see if its name is equal to a
-# second or is contained in the second if the second file's file type
-# is a directory.
-sub contained_in
-{
-  unless (@_ == 3)
-    {
-      croak "$0: contain_in $INCORRECT_NUMBER_OF_ARGS";
-    }
-
-  my $contained      = shift;
-  my $container      = shift;
-  my $container_type = shift;
-
-  if ($container eq $contained)
-    {
-      return 1;
-    }
-
-  if ($container_type eq 'd')
-    {
-      my $dirname        = "$container/";
-      my $dirname_length = length($dirname);
-
-      if ($dirname_length <= length($contained) and
-          $dirname eq substr($contained, 0, $dirname_length))
-        {
-          return 1;
-        }
-    }
-
-  return 0;
-}
-
-# Take an array reference containing a list of files and directories
-# and take a hash reference and remove from the array reference any
-# files and directories and the files the directory contains listed in
-# the hash.
-sub filter_renamed_files
-{
-  unless (@_ == 2)
-    {
-      croak "$0: filter_renamed_files $INCORRECT_NUMBER_OF_ARGS";
-    }
-
-  my $array_ref = shift;
-  my $hash_ref  = shift;
-
-  foreach my $remove_filename (keys %$hash_ref)
-    {
-      my $remove_file_type = $hash_ref->{$remove_filename}{type};
-      for (my $i=0; $i<@$array_ref;)
-        {
-          if (contained_in($array_ref->[$i],
-                           $remove_filename,
-                           $remove_file_type))
-            {
-              splice(@$array_ref, $i, 1);
-              next;
-            }
-          ++$i;
-        }
-    }
-}
-
-# Get a digest hash of the specified filename.
-sub digest_hash_file
-{
-  unless (@_ == 1)
-    {
-      croak "$0: digest_hash_file $INCORRECT_NUMBER_OF_ARGS";
-    }
-
-  my $filename = shift;
-
-  my $ctx = Digest::MD5->new;
-  if (open(READ, $filename))
-    {
-      binmode READ;
-      $ctx->addfile(*READ);
-      close(READ);
-    }
-  else
-    {
-      die "$0: cannot open '$filename' for reading: $!\n";
-    }
-  $ctx->digest;
-}
-
-# Read standard input until a line contains the required input or an
-# empty line to signify the default answer.
-sub get_answer
-{
-  unless (@_ == 3)
-    {
-      croak "$0: get_answer $INCORRECT_NUMBER_OF_ARGS";
-    }
-
-  my $message = shift;
-  my $answers = shift;
-  my $def_ans = shift;
-
-  return $def_ans if $opt_no_user_input;
-
-  my $char;
-  do
-    {
-      print $message;
-      $char = '';
-      my $line = <STDIN>;
-      if (defined $line and length $line)
-        {
-          $char = substr($line, 0, 1);
-          $char = '' if $char eq "\n";
-        }
-    } until $char eq '' or $answers =~ /$char/ig;
-
-  return $def_ans if $char eq '';
-  return pos($answers) - 1;
-}
-
-# Determine the native end of line on this system by writing a \n in
-# non-binary mode to an empty file and reading the same file back in
-# binary mode.
-sub determine_native_eol
-{
-  my $filename = "$temp_dir/svn_load_dirs_eol_test.$$";
-  if (-e $filename)
-    {
-      unlink($filename)
-        or die "$0: cannot unlink '$filename': $!\n";
-    }
-
-  # Write the \n in non-binary mode.
-  open(NL_TEST, ">$filename")
-    or die "$0: cannot open '$filename' for writing: $!\n";
-  print NL_TEST "\n";
-  close(NL_TEST)
-    or die "$0: error in closing '$filename' for writing: $!\n";
-
-  # Read the \n in binary mode.
-  open(NL_TEST, $filename)
-    or die "$0: cannot open '$filename' for reading: $!\n";
-  binmode NL_TEST;
-  local $/;
-  undef $/;
-  my $eol = <NL_TEST>;
-  close(NL_TEST)
-    or die "$0: cannot close '$filename' for reading: $!\n";
-  unlink($filename)
-    or die "$0: cannot unlink '$filename': $!\n";
-
-  my $eol_length = length($eol);
-  unless ($eol_length)
-    {
-      die "$0: native eol length on this system is 0.\n";
-    }
-
-  print "Native EOL on this system is ";
-  for (my $i=0; $i<$eol_length; ++$i)
-    {
-      printf "\\%03o", ord(substr($eol, $i, 1));
-    }
-  print ".\n\n";
-
-  $eol;
-}
-
-# Take a filename, open the file and replace all CR, CRLF and LF's
-# with the native end of line style for this system.
-sub convert_file_to_native_eol
-{
-  unless (@_ == 1)
-    {
-      croak "$0: convert_file_to_native_eol $INCORRECT_NUMBER_OF_ARGS";
-    }
-
-  my $filename = shift;
-  open(FILE, $filename)
-    or die "$0: cannot open '$filename' for reading: $!\n";
-  binmode FILE;
-  local $/;
-  undef $/;
-  my $in = <FILE>;
-  close(FILE)
-    or die "$0: error in closing '$filename' for reading: $!\n";
-  my $out = '';
-
-  # Go through the file and transform it byte by byte.
-  my $i = 0;
-  while ($i < length($in))
-    {
-      my $cc = substr($in, $i, 2);
-      if ($cc eq "\015\012")
-        {
-          $out .= $native_eol;
-          $i += 2;
-          next;
-        }
-
-      my $c = substr($cc, 0, 1);
-      if ($c eq "\012" or $c eq "\015")
-        {
-          $out .= $native_eol;
-        }
-      else
-        {
-          $out .= $c;
-        }
-      ++$i;
-    }
-
-  return 0 if $in eq $out;
-
-  my $tmp_filename = ".svn/tmp/svn_load_dirs.$$";
-  open(FILE, ">$tmp_filename")
-    or die "$0: cannot open '$tmp_filename' for writing: $!\n";
-  binmode FILE;
-  print FILE $out;
-  close(FILE)
-    or die "$0: cannot close '$tmp_filename' for writing: $!\n";
-  rename($tmp_filename, $filename)
-    or die "$0: cannot rename '$tmp_filename' to '$filename': $!\n";
-
-  return 1;
-}
-
-# Split the input line into words taking into account that single or
-# double quotes may define a single word with whitespace in it.
-sub split_line
-{
-  unless (@_ == 1)
-    {
-      croak "$0: split_line $INCORRECT_NUMBER_OF_ARGS";
-    }
-
-  my $line = shift;
-
-  # Strip leading whitespace.  Do not strip trailing whitespace which
-  # may be part of quoted text that was never closed.
-  $line =~ s/^\s+//;
-
-  my $line_length  = length $line;
-  my @words        = ();
-  my $current_word = '';
-  my $in_quote     = '';
-  my $in_protect   = '';
-  my $in_space     = '';
-  my $i            = 0;
-
-  while ($i < $line_length)
-    {
-      my $c = substr($line, $i, 1);
-      ++$i;
-
-      if ($in_protect)
-        {
-          if ($c eq $in_quote)
-            {
-              $current_word .= $c;
-            }
-          elsif ($c eq '"' or $c eq "'")
-            {
-              $current_word .= $c;
-            }
-          else
-            {
-              $current_word .= "$in_protect$c";
-            }
-          $in_protect = '';
-        }
-      elsif ($c eq '\\')
-        {
-          $in_protect = $c;
-        }
-      elsif ($in_quote)
-        {
-          if ($c eq $in_quote)
-            {
-              $in_quote = '';
-            }
-          else
-            {
-              $current_word .= $c;
-            }
-        }
-      elsif ($c eq '"' or $c eq "'")
-        {
-          $in_quote = $c;
-        }
-      elsif ($c =~ m/^\s$/)
-        {
-          unless ($in_space)
-            {
-              push(@words, $current_word);
-              $current_word = '';
-            }
-        }
-      else
-        {
-          $current_word .= $c;
-        }
-
-      $in_space = $c =~ m/^\s$/;
-    }
-
-  # Handle any leftovers.
-  $current_word .= $in_protect if $in_protect;
-  push(@words, $current_word) if length $current_word;
-
-  @words;
-}
-
-# This package exists just to delete the temporary directory.
-package Temp::Delete;
-
-sub new
-{
-  bless {}, shift;
-}
-
-sub DESTROY
-{
-  print "Cleaning up $temp_dir\n";
-  File::Path::rmtree([$temp_dir], 0, 0);
-}
diff --git a/thirdparty/svnmerge/COPYING b/thirdparty/svnmerge/COPYING
deleted file mode 100644
index d511905..0000000
--- a/thirdparty/svnmerge/COPYING
+++ /dev/null
@@ -1,339 +0,0 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/thirdparty/svnmerge/svnmerge.py b/thirdparty/svnmerge/svnmerge.py
deleted file mode 100755
index b1cd9da..0000000
--- a/thirdparty/svnmerge/svnmerge.py
+++ /dev/null
@@ -1,2170 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-# Copyright (c) 2005, Giovanni Bajo
-# Copyright (c) 2004-2005, Awarix, Inc.
-# All rights reserved.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-#
-# Author: Archie Cobbs <archie at awarix dot com>
-# Rewritten in Python by: Giovanni Bajo <rasky at develer dot com>
-#
-# Acknowledgments:
-#   John Belmonte <john at neggie dot net> - metadata and usability
-#     improvements
-#   Blair Zajac <blair at orcaware dot com> - random improvements
-#   Raman Gupta <rocketraman at fastmail dot fm> - bidirectional and transitive
-#     merging support
-#
-# $HeadURL$
-# $LastChangedDate$
-# $LastChangedBy$
-# $LastChangedRevision$
-#
-# Requisites:
-# svnmerge.py has been tested with all SVN major versions since 1.1 (both
-# client and server). It is unknown if it works with previous versions.
-#
-# Differences from svnmerge.sh:
-# - More portable: tested as working in FreeBSD and OS/2.
-# - Add double-verbose mode, which shows every svn command executed (-v -v).
-# - "svnmerge avail" now only shows commits in source, not also commits in
-#   other parts of the repository.
-# - Add "svnmerge block" to flag some revisions as blocked, so that
-#   they will not show up anymore in the available list.  Added also
-#   the complementary "svnmerge unblock".
-# - "svnmerge avail" has grown two new options:
-#   -B to display a list of the blocked revisions
-#   -A to display both the blocked and the available revisions.
-# - Improved generated commit message to make it machine parsable even when
-#   merging commits which are themselves merges.
-# - Add --force option to skip working copy check
-# - Add --record-only option to "svnmerge merge" to avoid performing
-#   an actual merge, yet record that a merge happened.
-#
-# TODO:
-#  - Add "svnmerge avail -R": show logs in reverse order
-#
-# Information for Hackers:
-#
-# Identifiers for branches:
-#  A branch is identified in three ways within this source:
-#  - as a working copy (variable name usually includes 'dir')
-#  - as a fully qualified URL
-#  - as a path identifier (an opaque string indicating a particular path
-#    in a particular repository; variable name includes 'pathid')
-#  A "target" is generally user-specified, and may be a working copy or
-#  a URL.
-
-import sys, os, getopt, re, types, tempfile, time, popen2, locale
-from bisect import bisect
-from xml.dom import pulldom
-
-NAME = "svnmerge"
-if not hasattr(sys, "version_info") or sys.version_info < (2, 0):
-    error("requires Python 2.0 or newer")
-
-# Set up the separator used to separate individual log messages from
-# each revision merged into the target location.  Also, create a
-# regular expression that will find this same separator in already
-# committed log messages, so that the separator used for this run of
-# svnmerge.py will have one more LOG_SEPARATOR appended to the longest
-# separator found in all the commits.
-LOG_SEPARATOR = 8 * '.'
-LOG_SEPARATOR_RE = re.compile('^((%s)+)' % re.escape(LOG_SEPARATOR),
-                              re.MULTILINE)
-
-# Each line of the embedded log messages will be prefixed by LOG_LINE_PREFIX.
-LOG_LINE_PREFIX = 2 * ' '
-
-# Set python to the default locale as per environment settings, same as svn
-# TODO we should really parse config and if log-encoding is specified, set
-# the locale to match that encoding
-locale.setlocale(locale.LC_ALL, '')
-
-# We want the svn output (such as svn info) to be non-localized
-# Using LC_MESSAGES should not affect localized output of svn log, for example
-if os.environ.has_key("LC_ALL"):
-    del os.environ["LC_ALL"]
-os.environ["LC_MESSAGES"] = "C"
-
-###############################################################################
-# Support for older Python versions
-###############################################################################
-
-# True/False constants are Python 2.2+
-try:
-    True, False
-except NameError:
-    True, False = 1, 0
-
-def lstrip(s, ch):
-    """Replacement for str.lstrip (support for arbitrary chars to strip was
-    added in Python 2.2.2)."""
-    i = 0
-    try:
-        while s[i] == ch:
-            i = i+1
-        return s[i:]
-    except IndexError:
-        return ""
-
-def rstrip(s, ch):
-    """Replacement for str.rstrip (support for arbitrary chars to strip was
-    added in Python 2.2.2)."""
-    try:
-        if s[-1] != ch:
-            return s
-        i = -2
-        while s[i] == ch:
-            i = i-1
-        return s[:i+1]
-    except IndexError:
-        return ""
-
-def strip(s, ch):
-    """Replacement for str.strip (support for arbitrary chars to strip was
-    added in Python 2.2.2)."""
-    return lstrip(rstrip(s, ch), ch)
-
-def rsplit(s, sep, maxsplits=0):
-    """Like str.rsplit, which is Python 2.4+ only."""
-    L = s.split(sep)
-    if not 0 < maxsplits <= len(L):
-        return L
-    return [sep.join(L[0:-maxsplits])] + L[-maxsplits:]
-
-###############################################################################
-
-def kwextract(s):
-    """Extract info from a svn keyword string."""
-    try:
-        return strip(s, "$").strip().split(": ")[1]
-    except IndexError:
-        return "<unknown>"
-
-__revision__ = kwextract('$Rev$')
-__date__ = kwextract('$Date$')
-
-# Additional options, not (yet?) mapped to command line flags
-default_opts = {
-    "svn": "svn",
-    "prop": NAME + "-integrated",
-    "block-prop": NAME + "-blocked",
-    "commit-verbose": True,
-}
-logs = {}
-
-def console_width():
-    """Get the width of the console screen (if any)."""
-    try:
-        return int(os.environ["COLUMNS"])
-    except (KeyError, ValueError):
-        pass
-
-    try:
-        # Call the Windows API (requires ctypes library)
-        from ctypes import windll, create_string_buffer
-        h = windll.kernel32.GetStdHandle(-11)
-        csbi = create_string_buffer(22)
-        res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
-        if res:
-            import struct
-            (bufx, bufy,
-             curx, cury, wattr,
-             left, top, right, bottom,
-             maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw)
-            return right - left + 1
-    except ImportError:
-        pass
-
-    # Parse the output of stty -a
-    out = os.popen("stty -a").read()
-    m = re.search(r"columns (\d+);", out)
-    if m:
-        return int(m.group(1))
-
-    # sensible default
-    return 80
-
-def error(s):
-    """Subroutine to output an error and bail."""
-    print >> sys.stderr, "%s: %s" % (NAME, s)
-    sys.exit(1)
-
-def report(s):
-    """Subroutine to output progress message, unless in quiet mode."""
-    if opts["verbose"]:
-        print "%s: %s" % (NAME, s)
-
-def prefix_lines(prefix, lines):
-    """Given a string representing one or more lines of text, insert the
-    specified prefix at the beginning of each line, and return the result.
-    The input must be terminated by a newline."""
-    assert lines[-1] == "\n"
-    return prefix + lines[:-1].replace("\n", "\n"+prefix) + "\n"
-
-def recode_stdout_to_file(s):
-    if locale.getdefaultlocale()[1] is None or not hasattr(sys.stdout, "encoding") \
-            or sys.stdout.encoding is None:
-        return s
-    u = s.decode(sys.stdout.encoding)
-    return u.encode(locale.getdefaultlocale()[1])
-
-class LaunchError(Exception):
-    """Signal a failure in execution of an external command. Parameters are the
-    exit code of the process, the original command line, and the output of the
-    command."""
-
-try:
-    """Launch a sub-process. Return its output (both stdout and stderr),
-    optionally split by lines (if split_lines is True). Raise a LaunchError
-    exception if the exit code of the process is non-zero (failure).
-
-    This function has two implementations, one based on subprocess (preferred),
-    and one based on popen (for compatibility).
-    """
-    import subprocess
-    import shlex
-
-    def launch(cmd, split_lines=True):
-        # Requiring python 2.4 or higher, on some platforms we get
-        # much faster performance from the subprocess module (where python
-        # doesn't try to close an exhorbitant number of file descriptors)
-        stdout = ""
-        stderr = ""
-        try:
-            if os.name == 'nt':
-                p = subprocess.Popen(cmd, stdout=subprocess.PIPE, \
-                                     close_fds=False, stderr=subprocess.PIPE)
-            else:
-                # Use shlex to break up the parameters intelligently,
-                # respecting quotes. shlex can't handle unicode.
-                args = shlex.split(cmd.encode('ascii'))
-                p = subprocess.Popen(args, stdout=subprocess.PIPE, \
-                                     close_fds=False, stderr=subprocess.PIPE)
-            stdoutAndErr = p.communicate()
-            stdout = stdoutAndErr[0]
-            stderr = stdoutAndErr[1]
-        except OSError, inst:
-            # Using 1 as failure code; should get actual number somehow? For
-            # examples see svnmerge_test.py's TestCase_launch.test_failure and
-            # TestCase_launch.test_failurecode.
-            raise LaunchError(1, cmd, stdout + " " + stderr + ": " + str(inst))
-
-        if p.returncode == 0:
-            if split_lines:
-                # Setting keepends=True for compatibility with previous logic
-                # (where file.readlines() preserves newlines)
-                return stdout.splitlines(True)
-            else:
-                return stdout
-        else:
-            raise LaunchError(p.returncode, cmd, stdout + stderr)
-except ImportError:
-    # support versions of python before 2.4 (slower on some systems)
-    def launch(cmd, split_lines=True):
-        if os.name not in ['nt', 'os2']:
-            p = popen2.Popen4(cmd)
-            p.tochild.close()
-            if split_lines:
-                out = p.fromchild.readlines()
-            else:
-                out = p.fromchild.read()
-            ret = p.wait()
-            if ret == 0:
-                ret = None
-            else:
-                ret >>= 8
-        else:
-            i,k = os.popen4(cmd)
-            i.close()
-            if split_lines:
-                out = k.readlines()
-            else:
-                out = k.read()
-            ret = k.close()
-
-        if ret is None:
-            return out
-        raise LaunchError(ret, cmd, out)
-
-def launchsvn(s, show=False, pretend=False, **kwargs):
-    """Launch SVN and grab its output."""
-    username = opts.get("username", None)
-    password = opts.get("password", None)
-    if username:
-        username = " --username=" + username
-    else:
-        username = ""
-    if password:
-        password = " --password=" + password
-    else:
-        password = ""
-    cmd = opts["svn"] + " --non-interactive" + username + password + " " + s
-    if show or opts["verbose"] >= 2:
-        print cmd
-    if pretend:
-        return None
-    return launch(cmd, **kwargs)
-
-def svn_command(s):
-    """Do (or pretend to do) an SVN command."""
-    out = launchsvn(s, show=opts["show-changes"] or opts["dry-run"],
-                    pretend=opts["dry-run"],
-                    split_lines=False)
-    if not opts["dry-run"]:
-        print out
-
-def check_dir_clean(dir):
-    """Check the current status of dir for local mods."""
-    if opts["force"]:
-        report('skipping status check because of --force')
-        return
-    report('checking status of "%s"' % dir)
-
-    # Checking with -q does not show unversioned files or external
-    # directories.  Though it displays a debug message for external
-    # directories, after a blank line.  So, practically, the first line
-    # matters: if it's non-empty there is a modification.
-    out = launchsvn("status -q %s" % dir)
-    if out and out[0].strip():
-        error('"%s" has local modifications; it must be clean' % dir)
-
-class RevisionLog:
-    """
-    A log of the revisions which affected a given URL between two
-    revisions.
-    """
-
-    def __init__(self, url, begin, end, find_propchanges=False):
-        """
-        Create a new RevisionLog object, which stores, in self.revs, a list
-        of the revisions which affected the specified URL between begin and
-        end. If find_propchanges is True, self.propchange_revs will contain a
-        list of the revisions which changed properties directly on the
-        specified URL. URL must be the URL for a directory in the repository.
-        """
-        self.url = url
-
-        # Setup the log options (--quiet, so we don't show log messages)
-        log_opts = '--xml --quiet -r%s:%s "%s"' % (begin, end, url)
-        if find_propchanges:
-            # The --verbose flag lets us grab merge tracking information
-            # by looking at propchanges
-            log_opts = "--verbose " + log_opts
-
-        # Read the log to look for revision numbers and merge-tracking info
-        self.revs = []
-        self.propchange_revs = []
-        repos_pathid = target_to_pathid(url)
-        for chg in SvnLogParser(launchsvn("log %s" % log_opts,
-                                          split_lines=False)):
-            self.revs.append(chg.revision())
-            for p in chg.paths():
-                if p.action() == 'M' and p.pathid() == repos_pathid:
-                    self.propchange_revs.append(chg.revision())
-
-        # Save the range of the log
-        self.begin = int(begin)
-        if end == "HEAD":
-            # If end is not provided, we do not know which is the latest
-            # revision in the repository. So we set 'end' to the latest
-            # known revision.
-            self.end = self.revs[-1]
-        else:
-            self.end = int(end)
-
-        self._merges = None
-        self._blocks = None
-
-    def merge_metadata(self):
-        """
-        Return a VersionedProperty object, with a cached view of the merge
-        metadata in the range of this log.
-        """
-
-        # Load merge metadata if necessary
-        if not self._merges:
-            self._merges = VersionedProperty(self.url, opts["prop"])
-            self._merges.load(self)
-
-        return self._merges
-
-    def block_metadata(self):
-        if not self._blocks:
-            self._blocks = VersionedProperty(self.url, opts["block-prop"])
-            self._blocks.load(self)
-
-        return self._blocks
-
-
-class VersionedProperty:
-    """
-    A read-only, cached view of a versioned property.
-
-    self.revs contains a list of the revisions in which the property changes.
-    self.values stores the new values at each corresponding revision. If the
-    value of the property is unknown, it is set to None.
-
-    Initially, we set self.revs to [0] and self.values to [None]. This
-    indicates that, as of revision zero, we know nothing about the value of
-    the property.
-
-    Later, if you run self.load(log), we cache the value of this property over
-    the entire range of the log by noting each revision in which the property
-    was changed. At the end of the range of the log, we invalidate our cache
-    by adding the value "None" to our cache for any revisions which fall out
-    of the range of our log.
-
-    Once self.revs and self.values are filled, we can find the value of the
-    property at any arbitrary revision using a binary search on self.revs.
-    Once we find the last revision during which the property was changed,
-    we can lookup the associated value in self.values. (If the associated
-    value is None, the associated value was not cached and we have to do
-    a full propget.)
-
-    An example: We know that the 'svnmerge' property was added in r10, and
-    changed in r21. We gathered log info up until r40.
-
-    revs = [0, 10, 21, 40]
-    values = [None, "val1", "val2", None]
-
-    What these values say:
-    - From r0 to r9, we know nothing about the property.
-    - In r10, the property was set to "val1". This property stayed the same
-      until r21, when it was changed to "val2".
-    - We don't know what happened after r40.
-    """
-
-    def __init__(self, url, name):
-        """View the history of a versioned property at URL with name"""
-        self.url = url
-        self.name = name
-
-        # We know nothing about the value of the property. Setup revs
-        # and values to indicate as such.
-        self.revs = [0]
-        self.values = [None]
-
-        # We don't have any revisions cached
-        self._initial_value = None
-        self._changed_revs = []
-        self._changed_values = []
-
-    def load(self, log):
-        """
-        Load the history of property changes from the specified
-        RevisionLog object.
-        """
-
-        # Get the property value before the range of the log
-        if log.begin > 1:
-            self.revs.append(log.begin-1)
-            try:
-                self._initial_value = self.raw_get(log.begin-1)
-            except LaunchError:
-                # The specified URL might not exist before the
-                # range of the log. If so, we can safely assume
-                # that the property was empty at that time.
-                self._initial_value = { }
-            self.values.append(self._initial_value)
-        else:
-            self._initial_value = { }
-            self.values[0] = self._initial_value
-
-        # Cache the property values in the log range
-        old_value = self._initial_value
-        for rev in log.propchange_revs:
-            new_value = self.raw_get(rev)
-            if new_value != old_value:
-                self._changed_revs.append(rev)
-                self._changed_values.append(new_value)
-                self.revs.append(rev)
-                self.values.append(new_value)
-                old_value = new_value
-
-        # Indicate that we know nothing about the value of the property
-        # after the range of the log.
-        if log.revs:
-            self.revs.append(log.end+1)
-            self.values.append(None)
-
-    def raw_get(self, rev=None):
-        """
-        Get the property at revision REV. If rev is not specified, get
-        the property at revision HEAD.
-        """
-        return get_revlist_prop(self.url, self.name, rev)
-
-    def get(self, rev=None):
-        """
-        Get the property at revision REV. If rev is not specified, get
-        the property at revision HEAD.
-        """
-
-        if rev is not None:
-
-            # Find the index using a binary search
-            i = bisect(self.revs, rev) - 1
-
-            # Return the value of the property, if it was cached
-            if self.values[i] is not None:
-                return self.values[i]
-
-        # Get the current value of the property
-        return self.raw_get(rev)
-
-    def changed_revs(self, key=None):
-        """
-        Get a list of the revisions in which the specified dictionary
-        key was changed in this property. If key is not specified,
-        return a list of revisions in which any key was changed.
-        """
-        if key is None:
-            return self._changed_revs
-        else:
-            changed_revs = []
-            old_val = self._initial_value
-            for rev, val in zip(self._changed_revs, self._changed_values):
-                if val.get(key) != old_val.get(key):
-                    changed_revs.append(rev)
-                    old_val = val
-            return changed_revs
-
-    def initialized_revs(self):
-        """
-        Get a list of the revisions in which keys were added or
-        removed in this property.
-        """
-        initialized_revs = []
-        old_len = len(self._initial_value)
-        for rev, val in zip(self._changed_revs, self._changed_values):
-            if len(val) != old_len:
-                initialized_revs.append(rev)
-                old_len = len(val)
-        return initialized_revs
-
-class RevisionSet:
-    """
-    A set of revisions, held in dictionary form for easy manipulation. If we
-    were to rewrite this script for Python 2.3+, we would subclass this from
-    set (or UserSet).  As this class does not include branch
-    information, it's assumed that one instance will be used per
-    branch.
-    """
-    def __init__(self, parm):
-        """Constructs a RevisionSet from a string in property form, or from
-        a dictionary whose keys are the revisions. Raises ValueError if the
-        input string is invalid."""
-
-        self._revs = {}
-
-        revision_range_split_re = re.compile('[-:]')
-
-        if isinstance(parm, types.DictType):
-            self._revs = parm.copy()
-        elif isinstance(parm, types.ListType):
-            for R in parm:
-                self._revs[int(R)] = 1
-        else:
-            parm = parm.strip()
-            if parm:
-                for R in parm.split(","):
-                    rev_or_revs = re.split(revision_range_split_re, R)
-                    if len(rev_or_revs) == 1:
-                        self._revs[int(rev_or_revs[0])] = 1
-                    elif len(rev_or_revs) == 2:
-                        for rev in range(int(rev_or_revs[0]),
-                                         int(rev_or_revs[1])+1):
-                            self._revs[rev] = 1
-                    else:
-                        raise ValueError, 'Ill formatted revision range: ' + R
-
-    def sorted(self):
-        revnums = self._revs.keys()
-        revnums.sort()
-        return revnums
-
-    def normalized(self):
-        """Returns a normalized version of the revision set, which is an
-        ordered list of couples (start,end), with the minimum number of
-        intervals."""
-        revnums = self.sorted()
-        revnums.reverse()
-        ret = []
-        while revnums:
-            s = e = revnums.pop()
-            while revnums and revnums[-1] in (e, e+1):
-                e = revnums.pop()
-            ret.append((s, e))
-        return ret
-
-    def __str__(self):
-        """Convert the revision set to a string, using its normalized form."""
-        L = []
-        for s,e in self.normalized():
-            if s == e:
-                L.append(str(s))
-            else:
-                L.append(str(s) + "-" + str(e))
-        return ",".join(L)
-
-    def __contains__(self, rev):
-        return self._revs.has_key(rev)
-
-    def __sub__(self, rs):
-        """Compute subtraction as in sets."""
-        revs = {}
-        for r in self._revs.keys():
-            if r not in rs:
-                revs[r] = 1
-        return RevisionSet(revs)
-
-    def __and__(self, rs):
-        """Compute intersections as in sets."""
-        revs = {}
-        for r in self._revs.keys():
-            if r in rs:
-                revs[r] = 1
-        return RevisionSet(revs)
-
-    def __nonzero__(self):
-        return len(self._revs) != 0
-
-    def __len__(self):
-        """Return the number of revisions in the set."""
-        return len(self._revs)
-
-    def __iter__(self):
-        return iter(self.sorted())
-
-    def __or__(self, rs):
-        """Compute set union."""
-        revs = self._revs.copy()
-        revs.update(rs._revs)
-        return RevisionSet(revs)
-
-def merge_props_to_revision_set(merge_props, pathid):
-    """A converter which returns a RevisionSet instance containing the
-    revisions from PATH as known to BRANCH_PROPS.  BRANCH_PROPS is a
-    dictionary of pathid -> revision set branch integration information
-    (as returned by get_merge_props())."""
-    if not merge_props.has_key(pathid):
-        error('no integration info available for path "%s"' % pathid)
-    return RevisionSet(merge_props[pathid])
-
-def dict_from_revlist_prop(propvalue):
-    """Given a property value as a string containing per-source revision
-    lists, return a dictionary whose key is a source path identifier
-    and whose value is the revisions for that source."""
-    prop = {}
-
-    # Multiple sources are separated by any whitespace.
-    for L in propvalue.split():
-        # We use rsplit to play safe and allow colons in pathids.
-        source, revs = rsplit(L.strip(), ":", 1)
-        prop[source] = revs
-    return prop
-
-def get_revlist_prop(url_or_dir, propname, rev=None):
-    """Given a repository URL or working copy path and a property
-    name, extract the values of the property which store per-source
-    revision lists and return a dictionary whose key is a source path
-    identifier, and whose value is the revisions for that source."""
-
-    # Note that propget does not return an error if the property does
-    # not exist, it simply does not output anything. So we do not need
-    # to check for LaunchError here.
-    args = '--strict "%s" "%s"' % (propname, url_or_dir)
-    if rev:
-        args = '-r %s %s' % (rev, args)
-    out = launchsvn('propget %s' % args, split_lines=False)
-
-    return dict_from_revlist_prop(out)
-
-def get_merge_props(dir):
-    """Extract the merged revisions."""
-    return get_revlist_prop(dir, opts["prop"])
-
-def get_block_props(dir):
-    """Extract the blocked revisions."""
-    return get_revlist_prop(dir, opts["block-prop"])
-
-def get_blocked_revs(dir, source_pathid):
-    p = get_block_props(dir)
-    if p.has_key(source_pathid):
-        return RevisionSet(p[source_pathid])
-    return RevisionSet("")
-
-def format_merge_props(props, sep=" "):
-    """Formats the hash PROPS as a string suitable for use as a
-    Subversion property value."""
-    assert sep in ["\t", "\n", " "]   # must be a whitespace
-    props = props.items()
-    props.sort()
-    L = []
-    for h, r in props:
-        L.append(h + ":" + r)
-    return sep.join(L)
-
-def _run_propset(dir, prop, value):
-    """Set the property 'prop' of directory 'dir' to value 'value'. We go
-    through a temporary file to not run into command line length limits."""
-    try:
-        fd, fname = tempfile.mkstemp()
-        f = os.fdopen(fd, "wb")
-    except AttributeError:
-        # Fallback for Python <= 2.3 which does not have mkstemp (mktemp
-        # suffers from race conditions. Not that we care...)
-        fname = tempfile.mktemp()
-        f = open(fname, "wb")
-
-    try:
-        f.write(value)
-        f.close()
-        report("property data written to temp file: %s" % value)
-        svn_command('propset "%s" -F "%s" "%s"' % (prop, fname, dir))
-    finally:
-        os.remove(fname)
-
-def set_props(dir, name, props):
-    props = format_merge_props(props)
-    if props:
-        _run_propset(dir, name, props)
-    else:
-        svn_command('propdel "%s" "%s"' % (name, dir))
-
-def set_merge_props(dir, props):
-    set_props(dir, opts["prop"], props)
-
-def set_block_props(dir, props):
-    set_props(dir, opts["block-prop"], props)
-
-def set_blocked_revs(dir, source_pathid, revs):
-    props = get_block_props(dir)
-    if revs:
-        props[source_pathid] = str(revs)
-    elif props.has_key(source_pathid):
-        del props[source_pathid]
-    set_block_props(dir, props)
-
-def is_url(url):
-    """Check if url is a valid url."""
-    return re.search(r"^[a-zA-Z][-+\.\w]*://[^\s]+$", url) is not None
-
-def is_wc(dir):
-    """Check if a directory is a working copy."""
-    return os.path.isdir(os.path.join(dir, ".svn")) or \
-           os.path.isdir(os.path.join(dir, "_svn"))
-
-_cache_svninfo = {}
-def get_svninfo(target):
-    """Extract the subversion information for a target (through 'svn info').
-    This function uses an internal cache to let clients query information
-    many times."""
-    if _cache_svninfo.has_key(target):
-        return _cache_svninfo[target]
-    info = {}
-    for L in launchsvn('info "%s"' % target):
-        L = L.strip()
-        if not L:
-            continue
-        key, value = L.split(": ", 1)
-        info[key] = value.strip()
-    _cache_svninfo[target] = info
-    return info
-
-def target_to_url(target):
-    """Convert working copy path or repos URL to a repos URL."""
-    if is_wc(target):
-        info = get_svninfo(target)
-        return info["URL"]
-    return target
-
-_cache_reporoot = {}
-def get_repo_root(target):
-    """Compute the root repos URL given a working-copy path, or a URL."""
-    # Try using "svn info WCDIR". This works only on SVN clients >= 1.3
-    if not is_url(target):
-        try:
-            info = get_svninfo(target)
-            root = info["Repository Root"]
-            _cache_reporoot[root] = None
-            return root
-        except KeyError:
-            pass
-        url = target_to_url(target)
-        assert url[-1] != '/'
-    else:
-        url = target
-
-    # Go through the cache of the repository roots. This avoids extra
-    # server round-trips if we are asking the root of different URLs
-    # in the same repository (the cache in get_svninfo() cannot detect
-    # that of course and would issue a remote command).
-    assert is_url(url)
-    for r in _cache_reporoot:
-        if url.startswith(r):
-            return r
-
-    # Try using "svn info URL". This works only on SVN clients >= 1.2
-    try:
-        info = get_svninfo(url)
-        root = info["Repository Root"]
-        _cache_reporoot[root] = None
-        return root
-    except LaunchError:
-        pass
-
-    # Constrained to older svn clients, we are stuck with this ugly
-    # trial-and-error implementation. It could be made faster with a
-    # binary search.
-    while url:
-        temp = os.path.dirname(url)
-        try:
-            launchsvn('proplist "%s"' % temp)
-        except LaunchError:
-            _cache_reporoot[url] = None
-            return url
-        url = temp
-
-    assert False, "svn repos root not found"
-
-def target_to_pathid(target):
-    """Convert a target (either a working copy path or an URL) into a
-    path identifier."""
-    root = get_repo_root(target)
-    url = target_to_url(target)
-    assert root[-1] != "/"
-    assert url[:len(root)] == root, "url=%r, root=%r" % (url, root)
-    return url[len(root):]
-
-class SvnLogParser:
-    """
-    Parse the "svn log", going through the XML output and using pulldom (which
-    would even allow streaming the command output).
-    """
-    def __init__(self, xml):
-        self._events = pulldom.parseString(xml)
-    def __getitem__(self, idx):
-        for event, node in self._events:
-            if event == pulldom.START_ELEMENT and node.tagName == "logentry":
-                self._events.expandNode(node)
-                return self.SvnLogRevision(node)
-        raise IndexError, "Could not find 'logentry' tag in xml"
-
-    class SvnLogRevision:
-        def __init__(self, xmlnode):
-            self.n = xmlnode
-        def revision(self):
-            return int(self.n.getAttribute("revision"))
-        def author(self):
-            return self.n.getElementsByTagName("author")[0].firstChild.data
-        def paths(self):
-            return [self.SvnLogPath(n)
-                    for n in  self.n.getElementsByTagName("path")]
-
-        class SvnLogPath:
-            def __init__(self, xmlnode):
-                self.n = xmlnode
-            def action(self):
-                return self.n.getAttribute("action")
-            def pathid(self):
-                return self.n.firstChild.data
-            def copyfrom_rev(self):
-                try: return self.n.getAttribute("copyfrom-rev")
-                except KeyError: return None
-            def copyfrom_pathid(self):
-                try: return self.n.getAttribute("copyfrom-path")
-                except KeyError: return None
-
-def get_copyfrom(target):
-    """Get copyfrom info for a given target (it represents the directory from
-    where it was branched). NOTE: repos root has no copyfrom info. In this case
-    None is returned.
-
-    Returns the:
-        - source file or directory from which the copy was made
-        - revision from which that source was copied
-        - revision in which the copy was committed
-    """
-    repos_path = target_to_pathid(target)
-    for chg in SvnLogParser(launchsvn('log -v --xml --stop-on-copy "%s"'
-                                      % target, split_lines=False)):
-        for p in chg.paths():
-            if p.action() == 'A' and p.pathid() == repos_path:
-                # These values will be None if the corresponding elements are
-                # not found in the log.
-                return p.copyfrom_pathid(), p.copyfrom_rev(), chg.revision()
-    return None,None,None
-
-def get_latest_rev(url):
-    """Get the latest revision of the repository of which URL is part."""
-    try:
-        return get_svninfo(url)["Revision"]
-    except LaunchError:
-        # Alternative method for latest revision checking (for svn < 1.2)
-        report('checking latest revision of "%s"' % url)
-        L = launchsvn('proplist --revprop -r HEAD "%s"' % opts["source-url"])[0]
-        rev = re.search("revision (\d+)", L).group(1)
-        report('latest revision of "%s" is %s' % (url, rev))
-        return rev
-
-def get_created_rev(url):
-    """Lookup the revision at which the path identified by the
-    provided URL was first created."""
-    oldest_rev = -1
-    report('determining oldest revision for URL "%s"' % url)
-    ### TODO: Refactor this to use a modified RevisionLog class.
-    lines = None
-    cmd = "log -r1:HEAD --stop-on-copy -q " + url
-    try:
-        lines = launchsvn(cmd + " --limit=1")
-    except LaunchError:
-        # Assume that --limit isn't supported by the installed 'svn'.
-        lines = launchsvn(cmd)
-    if lines and len(lines) > 1:
-        i = lines[1].find(" ")
-        if i != -1:
-            oldest_rev = int(lines[1][1:i])
-    if oldest_rev == -1:
-        error('unable to determine oldest revision for URL "%s"' % url)
-    return oldest_rev
-
-def get_commit_log(url, revnum):
-    """Return the log message for a specific integer revision
-    number."""
-    out = launchsvn("log --incremental -r%d %s" % (revnum, url))
-    return recode_stdout_to_file("".join(out[1:]))
-
-def construct_merged_log_message(url, revnums):
-    """Return a commit log message containing all the commit messages
-    in the specified revisions at the given URL.  The separator used
-    in this log message is determined by searching for the longest
-    svnmerge separator existing in the commit log messages and
-    extending it by one more separator.  This results in a new commit
-    log message that is clearer in describing merges that contain
-    other merges. Trailing newlines are removed from the embedded
-    log messages."""
-    messages = ['']
-    longest_sep = ''
-    for r in revnums.sorted():
-        message = get_commit_log(url, r)
-        if message:
-            message = re.sub(r'(\r\n|\r|\n)', "\n", message)
-            message = rstrip(message, "\n") + "\n"
-            messages.append(prefix_lines(LOG_LINE_PREFIX, message))
-            for match in LOG_SEPARATOR_RE.findall(message):
-                sep = match[1]
-                if len(sep) > len(longest_sep):
-                    longest_sep = sep
-
-    longest_sep += LOG_SEPARATOR + "\n"
-    messages.append('')
-    return longest_sep.join(messages)
-
-def get_default_source(branch_target, branch_props):
-    """Return the default source for branch_target (given its branch_props).
-    Error out if there is ambiguity."""
-    if not branch_props:
-        error("no integration info available")
-
-    props = branch_props.copy()
-    pathid = target_to_pathid(branch_target)
-
-    # To make bidirectional merges easier, find the target's
-    # repository local path so it can be removed from the list of
-    # possible integration sources.
-    if props.has_key(pathid):
-        del props[pathid]
-
-    if len(props) > 1:
-        err_msg = "multiple sources found. "
-        err_msg += "Explicit source argument (-S/--source) required.\n"
-        err_msg += "The merge sources available are:"
-        for prop in props:
-          err_msg += "\n  " + prop
-        error(err_msg)
-
-    return props.keys()[0]
-
-def check_old_prop_version(branch_target, branch_props):
-    """Check if branch_props (of branch_target) are svnmerge properties in
-    old format, and emit an error if so."""
-
-    # Previous svnmerge versions allowed trailing /'s in the repository
-    # local path.  Newer versions of svnmerge will trim trailing /'s
-    # appearing in the command line, so if there are any properties with
-    # trailing /'s, they will not be properly matched later on, so require
-    # the user to change them now.
-    fixed = {}
-    changed = False
-    for source, revs in branch_props.items():
-        src = rstrip(source, "/")
-        fixed[src] = revs
-        if src != source:
-            changed = True
-
-    if changed:
-        err_msg = "old property values detected; an upgrade is required.\n\n"
-        err_msg += "Please execute and commit these changes to upgrade:\n\n"
-        err_msg += 'svn propset "%s" "%s" "%s"' % \
-                   (opts["prop"], format_merge_props(fixed), branch_target)
-        error(err_msg)
-
-def should_find_reflected(branch_dir):
-    should_find_reflected = opts["bidirectional"]
-
-    # If the source has integration info for the target, set find_reflected
-    # even if --bidirectional wasn't specified
-    if not should_find_reflected:
-        source_props = get_merge_props(opts["source-url"])
-        should_find_reflected = source_props.has_key(target_to_pathid(branch_dir))
-
-    return should_find_reflected
-
-def analyze_revs(target_pathid, url, begin=1, end=None,
-                 find_reflected=False):
-    """For the source of the merges in the source URL being merged into
-    target_pathid, analyze the revisions in the interval begin-end (which
-    defaults to 1-HEAD), to find out which revisions are changes in
-    the url, which are changes elsewhere (so-called 'phantom'
-    revisions), optionally which are reflected changes (to avoid
-    conflicts that can occur when doing bidirectional merging between
-    branches), and which revisions initialize merge tracking against other
-    branches.  Return a tuple of four RevisionSet's:
-        (real_revs, phantom_revs, reflected_revs, initialized_revs).
-
-    NOTE: To maximize speed, if "end" is not provided, the function is
-    not able to find phantom revisions following the last real
-    revision in the URL.
-    """
-
-    begin = str(begin)
-    if end is None:
-        end = "HEAD"
-    else:
-        end = str(end)
-        if long(begin) > long(end):
-            return RevisionSet(""), RevisionSet(""), \
-                   RevisionSet(""), RevisionSet("")
-
-    logs[url] = RevisionLog(url, begin, end, find_reflected)
-    revs = RevisionSet(logs[url].revs)
-
-    if end == "HEAD":
-        # If end is not provided, we do not know which is the latest revision
-        # in the repository. So return the phantom revision set only up to
-        # the latest known revision.
-        end = str(list(revs)[-1])
-
-    phantom_revs = RevisionSet("%s-%s" % (begin, end)) - revs
-
-    if find_reflected:
-        reflected_revs = logs[url].merge_metadata().changed_revs(target_pathid)
-        reflected_revs += logs[url].block_metadata().changed_revs(target_pathid)
-    else:
-        reflected_revs = []
-
-    initialized_revs = RevisionSet(logs[url].merge_metadata().initialized_revs())
-    reflected_revs = RevisionSet(reflected_revs)
-
-    return revs, phantom_revs, reflected_revs, initialized_revs
-
-def analyze_source_revs(branch_target, source_url, **kwargs):
-    """For the given branch and source, extract the real and phantom
-    source revisions."""
-    branch_url = target_to_url(branch_target)
-    branch_pathid = target_to_pathid(branch_target)
-
-    # Extract the latest repository revision from the URL of the branch
-    # directory (which is already cached at this point).
-    end_rev = get_latest_rev(source_url)
-
-    # Calculate the base of analysis. If there is a "1-XX" interval in the
-    # merged_revs, we do not need to check those.
-    base = 1
-    r = opts["merged-revs"].normalized()
-    if r and r[0][0] == 1:
-        base = r[0][1] + 1
-
-    # See if the user filtered the revision set. If so, we are not
-    # interested in something outside that range.
-    if opts["revision"]:
-        revs = RevisionSet(opts["revision"]).sorted()
-        if base < revs[0]:
-            base = revs[0]
-        if end_rev > revs[-1]:
-            end_rev = revs[-1]
-
-    return analyze_revs(branch_pathid, source_url, base, end_rev, **kwargs)
-
-def minimal_merge_intervals(revs, phantom_revs):
-    """Produce the smallest number of intervals suitable for merging. revs
-    is the RevisionSet which we want to merge, and phantom_revs are phantom
-    revisions which can be used to concatenate intervals, thus minimizing the
-    number of operations."""
-    revnums = revs.normalized()
-    ret = []
-
-    cur = revnums.pop()
-    while revnums:
-        next = revnums.pop()
-        assert next[1] < cur[0]      # otherwise it is not ordered
-        assert cur[0] - next[1] > 1  # otherwise it is not normalized
-        for i in range(next[1]+1, cur[0]):
-            if i not in phantom_revs:
-                ret.append(cur)
-                cur = next
-                break
-        else:
-            cur = (next[0], cur[1])
-
-    ret.append(cur)
-    ret.reverse()
-    return ret
-
-def display_revisions(revs, display_style, revisions_msg, source_url):
-    """Show REVS as dictated by DISPLAY_STYLE, either numerically, in
-    log format, or as diffs.  When displaying revisions numerically,
-    prefix output with REVISIONS_MSG when in verbose mode.  Otherwise,
-    request logs or diffs using SOURCE_URL."""
-    if display_style == "revisions":
-        if revs:
-            report(revisions_msg)
-            print revs
-    elif display_style == "logs":
-        for start,end in revs.normalized():
-            svn_command('log --incremental -v -r %d:%d %s' % \
-                        (start, end, source_url))
-    elif display_style in ("diffs", "summarize"):
-        if display_style == 'summarize':
-            summarize = '--summarize '
-        else:
-            summarize = ''
-
-        for start, end in revs.normalized():
-            print
-            if start == end:
-                print "%s: changes in revision %d follow" % (NAME, start)
-            else:
-                print "%s: changes in revisions %d-%d follow" % (NAME,
-                                                                 start, end)
-            print
-
-            # Note: the starting revision number to 'svn diff' is
-            # NOT inclusive so we have to subtract one from ${START}.
-            svn_command("diff -r %d:%d %s %s" % (start - 1, end, summarize,
-                                                 source_url))
-    else:
-        assert False, "unhandled display style: %s" % display_style
-
-def action_init(target_dir, target_props):
-    """Initialize for merges."""
-    # Check that directory is ready for being modified
-    check_dir_clean(target_dir)
-
-    # If the user hasn't specified the revisions to use, see if the
-    # "source" is a copy from the current tree and if so, we can use
-    # the version data obtained from it.
-    revision_range = opts["revision"]
-    if not revision_range:
-        # Determining a default endpoint for the revision range that "init"
-        # will use, since none was provided by the user.
-        cf_source, cf_rev, copy_committed_in_rev = \
-                                            get_copyfrom(opts["source-url"])
-        target_path = target_to_pathid(target_dir)
-
-        if target_path == cf_source:
-            # If source was originally copyied from target, and we are merging
-            # changes from source to target (the copy target is the merge
-            # source, and the copy source is the merge target), then we want to
-            # mark as integrated up to the rev in which the copy was committed
-            # which created the merge source:
-            report('the source "%s" is a branch of "%s"' %
-                   (opts["source-url"], target_dir))
-            revision_range = "1-" + str(copy_committed_in_rev)
-        else:
-            # If the copy source is the merge source, and
-            # the copy target is the merge target, then we want to
-            # mark as integrated up to the specific rev of the merge
-            # target from which the merge source was copied. Longer
-            # discussion here:
-            # http://subversion.tigris.org/issues/show_bug.cgi?id=2810
-            target_url = target_to_url(target_dir)
-            source_path = target_to_pathid(opts["source-url"])
-            cf_source_path, cf_rev, copy_committed_in_rev = get_copyfrom(target_url)
-            if source_path == cf_source_path:
-                report('the merge source "%s" is the copy source of "%s"' %
-                       (opts["source-url"], target_dir))
-                revision_range = "1-" + cf_rev
-
-    # When neither the merge source nor target is a copy of the other, and
-    # the user did not specify a revision range, then choose a default which is
-    # the current revision; saying, in effect, "everything has been merged, so
-    # mark as integrated up to the latest rev on source url).
-    revs = revision_range or "1-" + get_latest_rev(opts["source-url"])
-    revs = RevisionSet(revs)
-
-    report('marking "%s" as already containing revisions "%s" of "%s"' %
-           (target_dir, revs, opts["source-url"]))
-
-    revs = str(revs)
-    # If the local svnmerge-integrated property already has an entry
-    # for the source-pathid, simply error out.
-    if not opts["force"] and target_props.has_key(opts["source-pathid"]):
-        error('Repository-relative path %s has already been initialized at %s\n'
-              'Use --force to re-initialize'
-              % (opts["source-pathid"], target_dir))
-    target_props[opts["source-pathid"]] = revs
-
-    # Set property
-    set_merge_props(target_dir, target_props)
-
-    # Write out commit message if desired
-    if opts["commit-file"]:
-        f = open(opts["commit-file"], "w")
-        print >>f, 'Initialized merge tracking via "%s" with revisions "%s" from ' \
-            % (NAME, revs)
-        print >>f, '%s' % opts["source-url"]
-        f.close()
-        report('wrote commit message to "%s"' % opts["commit-file"])
-
-def action_avail(branch_dir, branch_props):
-    """Show commits available for merges."""
-    source_revs, phantom_revs, reflected_revs, initialized_revs = \
-               analyze_source_revs(branch_dir, opts["source-url"],
-                                   find_reflected=
-                                       should_find_reflected(branch_dir))
-    report('skipping phantom revisions: %s' % phantom_revs)
-    if reflected_revs:
-        report('skipping reflected revisions: %s' % reflected_revs)
-        report('skipping initialized revisions: %s' % initialized_revs)
-
-    blocked_revs = get_blocked_revs(branch_dir, opts["source-pathid"])
-    avail_revs = source_revs - opts["merged-revs"] - blocked_revs - \
-                 reflected_revs - initialized_revs
-
-    # Compose the set of revisions to show
-    revs = RevisionSet("")
-    report_msg = "revisions available to be merged are:"
-    if "avail" in opts["avail-showwhat"]:
-        revs |= avail_revs
-    if "blocked" in opts["avail-showwhat"]:
-        revs |= blocked_revs
-        report_msg = "revisions blocked are:"
-
-    # Limit to revisions specified by -r (if any)
-    if opts["revision"]:
-        revs = revs & RevisionSet(opts["revision"])
-
-    display_revisions(revs, opts["avail-display"],
-                      report_msg,
-                      opts["source-url"])
-
-def action_integrated(branch_dir, branch_props):
-    """Show change sets already merged.  This set of revisions is
-    calculated from taking svnmerge-integrated property from the
-    branch, and subtracting any revision older than the branch
-    creation revision."""
-    # Extract the integration info for the branch_dir
-    branch_props = get_merge_props(branch_dir)
-    check_old_prop_version(branch_dir, branch_props)
-    revs = merge_props_to_revision_set(branch_props, opts["source-pathid"])
-
-    # Lookup the oldest revision on the branch path.
-    oldest_src_rev = get_created_rev(opts["source-url"])
-
-    # Subtract any revisions which pre-date the branch.
-    report("subtracting revisions which pre-date the source URL (%d)" %
-           oldest_src_rev)
-    revs = revs - RevisionSet(range(1, oldest_src_rev))
-
-    # Limit to revisions specified by -r (if any)
-    if opts["revision"]:
-        revs = revs & RevisionSet(opts["revision"])
-
-    display_revisions(revs, opts["integrated-display"],
-                      "revisions already integrated are:", opts["source-url"])
-
-def action_merge(branch_dir, branch_props):
-    """Record merge meta data, and do the actual merge (if not
-    requested otherwise via --record-only)."""
-    # Check branch directory is ready for being modified
-    check_dir_clean(branch_dir)
-
-    source_revs, phantom_revs, reflected_revs, initialized_revs = \
-               analyze_source_revs(branch_dir, opts["source-url"],
-                                   find_reflected=
-                                       should_find_reflected(branch_dir))
-
-    if opts["revision"]:
-        revs = RevisionSet(opts["revision"])
-    else:
-        revs = source_revs
-
-    blocked_revs = get_blocked_revs(branch_dir, opts["source-pathid"])
-    merged_revs = opts["merged-revs"]
-
-    # Show what we're doing
-    if opts["verbose"]:  # just to avoid useless calculations
-        if merged_revs & revs:
-            report('"%s" already contains revisions %s' % (branch_dir,
-                                                           merged_revs & revs))
-        if phantom_revs:
-            report('memorizing phantom revision(s): %s' % phantom_revs)
-        if reflected_revs:
-            report('memorizing reflected revision(s): %s' % reflected_revs)
-        if blocked_revs & revs:
-            report('skipping blocked revisions(s): %s' % (blocked_revs & revs))
-        if initialized_revs:
-            report('skipping initialized revision(s): %s' % initialized_revs)
-
-    # Compute final merge set.
-    revs = revs - merged_revs - blocked_revs - reflected_revs - \
-           phantom_revs - initialized_revs
-    if not revs:
-        report('no revisions to merge, exiting')
-        return
-
-    # When manually marking revisions as merged, we only update the
-    # integration meta data, and don't perform an actual merge.
-    record_only = opts["record-only"]
-
-    if record_only:
-        report('recording merge of revision(s) %s from "%s"' %
-               (revs, opts["source-url"]))
-    else:
-        report('merging in revision(s) %s from "%s"' %
-               (revs, opts["source-url"]))
-
-    # Do the merge(s). Note: the starting revision number to 'svn merge'
-    # is NOT inclusive so we have to subtract one from start.
-    # We try to keep the number of merge operations as low as possible,
-    # because it is faster and reduces the number of conflicts.
-    old_block_props = get_block_props(branch_dir)
-    merge_metadata = logs[opts["source-url"]].merge_metadata()
-    block_metadata = logs[opts["source-url"]].block_metadata()
-    for start,end in minimal_merge_intervals(revs, phantom_revs):
-        if not record_only:
-            # Preset merge/blocked properties to the source value at
-            # the start rev to avoid spurious property conflicts
-            set_merge_props(branch_dir, merge_metadata.get(start - 1))
-            set_block_props(branch_dir, block_metadata.get(start - 1))
-            # Do the merge
-            svn_command("merge --force -r %d:%d %s %s" % \
-                        (start - 1, end, opts["source-url"], branch_dir))
-            # TODO: to support graph merging, add logic to merge the property
-            # meta-data manually
-
-    # Update the set of merged revisions.
-    merged_revs = merged_revs | revs | reflected_revs | phantom_revs | initialized_revs
-    branch_props[opts["source-pathid"]] = str(merged_revs)
-    set_merge_props(branch_dir, branch_props)
-    # Reset the blocked revs
-    set_block_props(branch_dir, old_block_props)
-
-    # Write out commit message if desired
-    if opts["commit-file"]:
-        f = open(opts["commit-file"], "w")
-        if record_only:
-            print >>f, 'Recorded merge of revisions %s via %s from ' % \
-                  (revs, NAME)
-        else:
-            print >>f, 'Merged revisions %s via %s from ' % \
-                  (revs, NAME)
-        print >>f, '%s' % opts["source-url"]
-        if opts["commit-verbose"]:
-            print >>f
-            print >>f, construct_merged_log_message(opts["source-url"], revs),
-
-        f.close()
-        report('wrote commit message to "%s"' % opts["commit-file"])
-
-def action_block(branch_dir, branch_props):
-    """Block revisions."""
-    # Check branch directory is ready for being modified
-    check_dir_clean(branch_dir)
-
-    source_revs, phantom_revs, reflected_revs, initialized_revs = \
-               analyze_source_revs(branch_dir, opts["source-url"])
-    revs_to_block = source_revs - opts["merged-revs"]
-
-    # Limit to revisions specified by -r (if any)
-    if opts["revision"]:
-        revs_to_block = RevisionSet(opts["revision"]) & revs_to_block
-
-    if not revs_to_block:
-        error('no available revisions to block')
-
-    # Change blocked information
-    blocked_revs = get_blocked_revs(branch_dir, opts["source-pathid"])
-    blocked_revs = blocked_revs | revs_to_block
-    set_blocked_revs(branch_dir, opts["source-pathid"], blocked_revs)
-
-    # Write out commit message if desired
-    if opts["commit-file"]:
-        f = open(opts["commit-file"], "w")
-        print >>f, 'Blocked revisions %s via %s' % (revs_to_block, NAME)
-        if opts["commit-verbose"]:
-            print >>f
-            print >>f, construct_merged_log_message(opts["source-url"],
-                                                    revs_to_block),
-
-        f.close()
-        report('wrote commit message to "%s"' % opts["commit-file"])
-
-def action_unblock(branch_dir, branch_props):
-    """Unblock revisions."""
-    # Check branch directory is ready for being modified
-    check_dir_clean(branch_dir)
-
-    blocked_revs = get_blocked_revs(branch_dir, opts["source-pathid"])
-    revs_to_unblock = blocked_revs
-
-    # Limit to revisions specified by -r (if any)
-    if opts["revision"]:
-        revs_to_unblock = revs_to_unblock & RevisionSet(opts["revision"])
-
-    if not revs_to_unblock:
-        error('no available revisions to unblock')
-
-    # Change blocked information
-    blocked_revs = blocked_revs - revs_to_unblock
-    set_blocked_revs(branch_dir, opts["source-pathid"], blocked_revs)
-
-    # Write out commit message if desired
-    if opts["commit-file"]:
-        f = open(opts["commit-file"], "w")
-        print >>f, 'Unblocked revisions %s via %s' % (revs_to_unblock, NAME)
-        if opts["commit-verbose"]:
-            print >>f
-            print >>f, construct_merged_log_message(opts["source-url"],
-                                                    revs_to_unblock),
-        f.close()
-        report('wrote commit message to "%s"' % opts["commit-file"])
-
-def action_rollback(branch_dir, branch_props):
-    """Rollback previously integrated revisions."""
-
-    # Make sure the revision arguments are present
-    if not opts["revision"]:
-        error("The '-r' option is mandatory for rollback")
-
-    # Check branch directory is ready for being modified
-    check_dir_clean(branch_dir)
-
-    # Extract the integration info for the branch_dir
-    branch_props = get_merge_props(branch_dir)
-    check_old_prop_version(branch_dir, branch_props)
-    # Get the list of all revisions already merged into this source-pathid.
-    merged_revs = merge_props_to_revision_set(branch_props,
-                                              opts["source-pathid"])
-
-    # At which revision was the src created?
-    oldest_src_rev = get_created_rev(opts["source-url"])
-    src_pre_exist_range = RevisionSet("1-%d" % oldest_src_rev)
-
-    # Limit to revisions specified by -r (if any)
-    revs = merged_revs & RevisionSet(opts["revision"])
-
-    # make sure there's some revision to rollback
-    if not revs:
-        report("Nothing to rollback in revision range r%s" % opts["revision"])
-        return
-
-    # If even one specified revision lies outside the lifetime of the
-    # merge source, error out.
-    if revs & src_pre_exist_range:
-        err_str  = "Specified revision range falls out of the rollback range.\n"
-        err_str += "%s was created at r%d" % (opts["source-pathid"],
-                                              oldest_src_rev)
-        error(err_str)
-
-    record_only = opts["record-only"]
-
-    if record_only:
-        report('recording rollback of revision(s) %s from "%s"' %
-               (revs, opts["source-url"]))
-    else:
-        report('rollback of revision(s) %s from "%s"' %
-               (revs, opts["source-url"]))
-
-    # Do the reverse merge(s). Note: the starting revision number
-    # to 'svn merge' is NOT inclusive so we have to subtract one from start.
-    # We try to keep the number of merge operations as low as possible,
-    # because it is faster and reduces the number of conflicts.
-    rollback_intervals = minimal_merge_intervals(revs, [])
-    # rollback in the reverse order of merge
-    rollback_intervals.reverse()
-    for start, end in rollback_intervals:
-        if not record_only:
-            # Do the merge
-            svn_command("merge --force -r %d:%d %s %s" % \
-                        (end, start - 1, opts["source-url"], branch_dir))
-
-    # Write out commit message if desired
-    # calculate the phantom revs first
-    if opts["commit-file"]:
-        f = open(opts["commit-file"], "w")
-        if record_only:
-            print >>f, 'Recorded rollback of revisions %s via %s from ' % \
-                  (revs , NAME)
-        else:
-            print >>f, 'Rolled back revisions %s via %s from ' % \
-                  (revs , NAME)
-        print >>f, '%s' % opts["source-url"]
-
-        f.close()
-        report('wrote commit message to "%s"' % opts["commit-file"])
-
-    # Update the set of merged revisions.
-    merged_revs = merged_revs - revs
-    branch_props[opts["source-pathid"]] = str(merged_revs)
-    set_merge_props(branch_dir, branch_props)
-
-def action_uninit(branch_dir, branch_props):
-    """Uninit SOURCE URL."""
-    # Check branch directory is ready for being modified
-    check_dir_clean(branch_dir)
-
-    # If the source-pathid does not have an entry in the svnmerge-integrated
-    # property, simply error out.
-    if not branch_props.has_key(opts["source-pathid"]):
-        error('Repository-relative path "%s" does not contain merge '
-              'tracking information for "%s"' \
-                % (opts["source-pathid"], branch_dir))
-
-    del branch_props[opts["source-pathid"]]
-
-    # Set merge property with the selected source deleted
-    set_merge_props(branch_dir, branch_props)
-
-    # Set blocked revisions for the selected source to None
-    set_blocked_revs(branch_dir, opts["source-pathid"], None)
-
-    # Write out commit message if desired
-    if opts["commit-file"]:
-        f = open(opts["commit-file"], "w")
-        print >>f, 'Removed merge tracking for "%s" for ' % NAME
-        print >>f, '%s' % opts["source-url"]
-        f.close()
-        report('wrote commit message to "%s"' % opts["commit-file"])
-
-###############################################################################
-# Command line parsing -- options and commands management
-###############################################################################
-
-class OptBase:
-    def __init__(self, *args, **kwargs):
-        self.help = kwargs["help"]
-        del kwargs["help"]
-        self.lflags = []
-        self.sflags = []
-        for a in args:
-            if a.startswith("--"):   self.lflags.append(a)
-            elif a.startswith("-"):  self.sflags.append(a)
-            else:
-                raise TypeError, "invalid flag name: %s" % a
-        if kwargs.has_key("dest"):
-            self.dest = kwargs["dest"]
-            del kwargs["dest"]
-        else:
-            if not self.lflags:
-                raise TypeError, "cannot deduce dest name without long options"
-            self.dest = self.lflags[0][2:]
-        if kwargs:
-            raise TypeError, "invalid keyword arguments: %r" % kwargs.keys()
-    def repr_flags(self):
-        f = self.sflags + self.lflags
-        r = f[0]
-        for fl in f[1:]:
-            r += " [%s]" % fl
-        return r
-
-class Option(OptBase):
-    def __init__(self, *args, **kwargs):
-        self.default = kwargs.setdefault("default", 0)
-        del kwargs["default"]
-        self.value = kwargs.setdefault("value", None)
-        del kwargs["value"]
-        OptBase.__init__(self, *args, **kwargs)
-    def apply(self, state, value):
-        assert value == ""
-        if self.value is not None:
-            state[self.dest] = self.value
-        else:
-            state[self.dest] += 1
-
-class OptionArg(OptBase):
-    def __init__(self, *args, **kwargs):
-        self.default = kwargs["default"]
-        del kwargs["default"]
-        self.metavar = kwargs.setdefault("metavar", None)
-        del kwargs["metavar"]
-        OptBase.__init__(self, *args, **kwargs)
-
-        if self.metavar is None:
-            if self.dest is not None:
-                self.metavar = self.dest.upper()
-            else:
-                self.metavar = "arg"
-        if self.default:
-            self.help += " (default: %s)" % self.default
-    def apply(self, state, value):
-        assert value is not None
-        state[self.dest] = value
-    def repr_flags(self):
-        r = OptBase.repr_flags(self)
-        return r + " " + self.metavar
-
-class CommandOpts:
-    class Cmd:
-        def __init__(self, *args):
-            self.name, self.func, self.usage, self.help, self.opts = args
-        def short_help(self):
-            return self.help.split(".")[0]
-        def __str__(self):
-            return self.name
-        def __call__(self, *args, **kwargs):
-            return self.func(*args, **kwargs)
-
-    def __init__(self, global_opts, common_opts, command_table, version=None):
-        self.progname = NAME
-        self.version = version.replace("%prog", self.progname)
-        self.cwidth = console_width() - 2
-        self.ctable = command_table.copy()
-        self.gopts = global_opts[:]
-        self.copts = common_opts[:]
-        self._add_builtins()
-        for k in self.ctable.keys():
-            cmd = self.Cmd(k, *self.ctable[k])
-            opts = []
-            for o in cmd.opts:
-                if isinstance(o, types.StringType) or \
-                   isinstance(o, types.UnicodeType):
-                    o = self._find_common(o)
-                opts.append(o)
-            cmd.opts = opts
-            self.ctable[k] = cmd
-
-    def _add_builtins(self):
-        self.gopts.append(
-            Option("-h", "--help", help="show help for this command and exit"))
-        if self.version is not None:
-            self.gopts.append(
-                Option("-V", "--version", help="show version info and exit"))
-        self.ctable["help"] = (self._cmd_help,
-            "help [COMMAND]",
-            "Display help for a specific command. If COMMAND is omitted, "
-            "display brief command description.",
-            [])
-
-    def _cmd_help(self, cmd=None, *args):
-        if args:
-            self.error("wrong number of arguments", "help")
-        if cmd is not None:
-            cmd = self._command(cmd)
-            self.print_command_help(cmd)
-        else:
-            self.print_command_list()
-
-    def _paragraph(self, text, width=78):
-        chunks = re.split("\s+", text.strip())
-        chunks.reverse()
-        lines = []
-        while chunks:
-            L = chunks.pop()
-            while chunks and len(L) + len(chunks[-1]) + 1 <= width:
-                L += " " + chunks.pop()
-            lines.append(L)
-        return lines
-
-    def _paragraphs(self, text, *args, **kwargs):
-        pars = text.split("\n\n")
-        lines = self._paragraph(pars[0], *args, **kwargs)
-        for p in pars[1:]:
-            lines.append("")
-            lines.extend(self._paragraph(p, *args, **kwargs))
-        return lines
-
-    def _print_wrapped(self, text, indent=0):
-        text = self._paragraphs(text, self.cwidth - indent)
-        print text.pop(0)
-        for t in text:
-            print " " * indent + t
-
-    def _find_common(self, fl):
-        for o in self.copts:
-            if fl in o.lflags+o.sflags:
-                return o
-        assert False, fl
-
-    def _compute_flags(self, opts, check_conflicts=True):
-        back = {}
-        sfl = ""
-        lfl = []
-        for o in opts:
-            sapp = lapp = ""
-            if isinstance(o, OptionArg):
-                sapp, lapp = ":", "="
-            for s in o.sflags:
-                if check_conflicts and back.has_key(s):
-                    raise RuntimeError, "option conflict: %s" % s
-                back[s] = o
-                sfl += s[1:] + sapp
-            for l in o.lflags:
-                if check_conflicts and back.has_key(l):
-                    raise RuntimeError, "option conflict: %s" % l
-                back[l] = o
-                lfl.append(l[2:] + lapp)
-        return sfl, lfl, back
-
-    def _extract_command(self, args):
-        """
-        Try to extract the command name from the argument list. This is
-        non-trivial because we want to allow command-specific options even
-        before the command itself.
-        """
-        opts = self.gopts[:]
-        for cmd in self.ctable.values():
-            opts.extend(cmd.opts)
-        sfl, lfl, _ = self._compute_flags(opts, check_conflicts=False)
-
-        lopts,largs = getopt.getopt(args, sfl, lfl)
-        if not largs:
-            return None
-        return self._command(largs[0])
-
-    def _fancy_getopt(self, args, opts, state=None):
-        if state is None:
-            state= {}
-        for o in opts:
-            if not state.has_key(o.dest):
-                state[o.dest] = o.default
-
-        sfl, lfl, back = self._compute_flags(opts)
-        try:
-            lopts,args = getopt.gnu_getopt(args, sfl, lfl)
-        except AttributeError:
-            # Before Python 2.3, there was no gnu_getopt support.
-            # So we can't parse intermixed positional arguments
-            # and options.
-            lopts,args = getopt.getopt(args, sfl, lfl)
-
-        for o,v in lopts:
-            back[o].apply(state, v)
-        return state, args
-
-    def _command(self, cmd):
-        if not self.ctable.has_key(cmd):
-            self.error("unknown command: '%s'" % cmd)
-        return self.ctable[cmd]
-
-    def parse(self, args):
-        if not args:
-            self.print_small_help()
-            sys.exit(0)
-
-        cmd = None
-        try:
-            cmd = self._extract_command(args)
-            opts = self.gopts[:]
-            if cmd:
-                opts.extend(cmd.opts)
-                args.remove(cmd.name)
-            state, args = self._fancy_getopt(args, opts)
-        except getopt.GetoptError, e:
-            self.error(e, cmd)
-
-        # Handle builtins
-        if self.version is not None and state["version"]:
-            self.print_version()
-            sys.exit(0)
-        if state["help"]: # special case for --help
-            if cmd:
-                self.print_command_help(cmd)
-                sys.exit(0)
-            cmd = self.ctable["help"]
-        else:
-            if cmd is None:
-                self.error("command argument required")
-        if str(cmd) == "help":
-            cmd(*args)
-            sys.exit(0)
-        return cmd, args, state
-
-    def error(self, s, cmd=None):
-        print >>sys.stderr, "%s: %s" % (self.progname, s)
-        if cmd is not None:
-            self.print_command_help(cmd)
-        else:
-            self.print_small_help()
-        sys.exit(1)
-    def print_small_help(self):
-        print "Type '%s help' for usage" % self.progname
-    def print_usage_line(self):
-        print "usage: %s <subcommand> [options...] [args...]\n" % self.progname
-    def print_command_list(self):
-        print "Available commands (use '%s help COMMAND' for more details):\n" \
-              % self.progname
-        cmds = self.ctable.keys()
-        cmds.sort()
-        indent = max(map(len, cmds))
-        for c in cmds:
-            h = self.ctable[c].short_help()
-            print "  %-*s   " % (indent, c),
-            self._print_wrapped(h, indent+6)
-    def print_command_help(self, cmd):
-        cmd = self.ctable[str(cmd)]
-        print 'usage: %s %s\n' % (self.progname, cmd.usage)
-        self._print_wrapped(cmd.help)
-        def print_opts(opts, self=self):
-            if not opts: return
-            flags = [o.repr_flags() for o in opts]
-            indent = max(map(len, flags))
-            for f,o in zip(flags, opts):
-                print "  %-*s :" % (indent, f),
-                self._print_wrapped(o.help, indent+5)
-        print '\nCommand options:'
-        print_opts(cmd.opts)
-        print '\nGlobal options:'
-        print_opts(self.gopts)
-
-    def print_version(self):
-        print self.version
-
-###############################################################################
-# Options and Commands description
-###############################################################################
-
-global_opts = [
-    Option("-F", "--force",
-           help="force operation even if the working copy is not clean, or "
-                "there are pending updates"),
-    Option("-n", "--dry-run",
-           help="don't actually change anything, just pretend; "
-                "implies --show-changes"),
-    Option("-s", "--show-changes",
-           help="show subversion commands that make changes"),
-    Option("-v", "--verbose",
-           help="verbose mode: output more information about progress"),
-    OptionArg("-u", "--username",
-              default=None,
-              help="invoke subversion commands with the supplied username"),
-    OptionArg("-p", "--password",
-              default=None,
-              help="invoke subversion commands with the supplied password"),
-]
-
-common_opts = [
-    Option("-b", "--bidirectional",
-           value=True,
-           default=False,
-           help="remove reflected and initialized revisions from merge candidates.  "
-                "Not required but may be specified to speed things up slightly"),
-    OptionArg("-f", "--commit-file", metavar="FILE",
-              default="svnmerge-commit-message.txt",
-              help="set the name of the file where the suggested log message "
-                   "is written to"),
-    Option("-M", "--record-only",
-           value=True,
-           default=False,
-           help="do not perform an actual merge of the changes, yet record "
-                "that a merge happened"),
-    OptionArg("-r", "--revision",
-              metavar="REVLIST",
-              default="",
-              help="specify a revision list, consisting of revision numbers "
-                   'and ranges separated by commas, e.g., "534,537-539,540"'),
-    OptionArg("-S", "--source", "--head",
-              default=None,
-              help="specify a merge source for this branch.  It can be either "
-                   "a path, a full URL, or an unambiguous substring of one "
-                   "of the paths for which merge tracking was already "
-                   "initialized.  Needed only to disambiguate in case of "
-                   "multiple merge sources"),
-]
-
-command_table = {
-    "init": (action_init,
-    "init [OPTION...] [SOURCE]",
-    """Initialize merge tracking from SOURCE on the current working
-    directory.
-
-    If SOURCE is specified, all the revisions in SOURCE are marked as already
-    merged; if this is not correct, you can use --revision to specify the
-    exact list of already-merged revisions.
-
-    If SOURCE is omitted, then it is computed from the "svn cp" history of the
-    current working directory (searching back for the branch point); in this
-    case, %s assumes that no revision has been integrated yet since
-    the branch point (unless you teach it with --revision).""" % NAME,
-    [
-        "-f", "-r", # import common opts
-    ]),
-
-    "avail": (action_avail,
-    "avail [OPTION...] [PATH]",
-    """Show unmerged revisions available for PATH as a revision list.
-    If --revision is given, the revisions shown will be limited to those
-    also specified in the option.
-
-    When svnmerge is used to bidirectionally merge changes between a
-    branch and its source, it is necessary to not merge the same changes
-    forth and back: e.g., if you committed a merge of a certain
-    revision of the branch into the source, you do not want that commit
-    to appear as available to merged into the branch (as the code
-    originated in the branch itself!).  svnmerge will automatically
-    exclude these so-called "reflected" revisions.""",
-    [
-        Option("-A", "--all",
-               dest="avail-showwhat",
-               value=["blocked", "avail"],
-               default=["avail"],
-               help="show both available and blocked revisions (aka ignore "
-                    "blocked revisions)"),
-        "-b",
-        Option("-B", "--blocked",
-               dest="avail-showwhat",
-               value=["blocked"],
-               help="show the blocked revision list (see '%s block')" % NAME),
-        Option("-d", "--diff",
-               dest="avail-display",
-               value="diffs",
-               default="revisions",
-               help="show corresponding diff instead of revision list"),
-        Option("--summarize",
-               dest="avail-display",
-               value="summarize",
-               help="show summarized diff instead of revision list"),
-        Option("-l", "--log",
-               dest="avail-display",
-               value="logs",
-               help="show corresponding log history instead of revision list"),
-        "-r",
-        "-S",
-    ]),
-
-    "integrated": (action_integrated,
-    "integrated [OPTION...] [PATH]",
-    """Show merged revisions available for PATH as a revision list.
-    If --revision is given, the revisions shown will be limited to
-    those also specified in the option.""",
-    [
-        Option("-d", "--diff",
-               dest="integrated-display",
-               value="diffs",
-               default="revisions",
-               help="show corresponding diff instead of revision list"),
-        Option("-l", "--log",
-               dest="integrated-display",
-               value="logs",
-               help="show corresponding log history instead of revision list"),
-        "-r",
-        "-S",
-    ]),
-
-    "rollback": (action_rollback,
-    "rollback [OPTION...] [PATH]",
-    """Rollback previously merged in revisions from PATH.  The
-    --revision option is mandatory, and specifies which revisions
-    will be rolled back.  Only the previously integrated merges
-    will be rolled back.
-
-    When manually rolling back changes, --record-only can be used to
-    instruct %s that a manual rollback of a certain revision
-    already happened, so that it can record it and offer that
-    revision for merge henceforth.""" % (NAME),
-    [
-        "-f", "-r", "-S", "-M", # import common opts
-    ]),
-
-    "merge": (action_merge,
-    "merge [OPTION...] [PATH]",
-    """Merge in revisions into PATH from its source. If --revision is omitted,
-    all the available revisions will be merged. In any case, already merged-in
-    revisions will NOT be merged again.
-
-    When svnmerge is used to bidirectionally merge changes between a
-    branch and its source, it is necessary to not merge the same changes
-    forth and back: e.g., if you committed a merge of a certain
-    revision of the branch into the source, you do not want that commit
-    to appear as available to merged into the branch (as the code
-    originated in the branch itself!).  svnmerge will automatically
-    exclude these so-called "reflected" revisions.
-
-    When manually merging changes across branches, --record-only can
-    be used to instruct %s that a manual merge of a certain revision
-    already happened, so that it can record it and not offer that
-    revision for merge anymore.  Conversely, when there are revisions
-    which should not be merged, use '%s block'.""" % (NAME, NAME),
-    [
-        "-b", "-f", "-r", "-S", "-M", # import common opts
-    ]),
-
-    "block": (action_block,
-    "block [OPTION...] [PATH]",
-    """Block revisions within PATH so that they disappear from the available
-    list. This is useful to hide revisions which will not be integrated.
-    If --revision is omitted, it defaults to all the available revisions.
-
-    Do not use this option to hide revisions that were manually merged
-    into the branch.  Instead, use '%s merge --record-only', which
-    records that a merge happened (as opposed to a merge which should
-    not happen).""" % NAME,
-    [
-        "-f", "-r", "-S", # import common opts
-    ]),
-
-    "unblock": (action_unblock,
-    "unblock [OPTION...] [PATH]",
-    """Revert the effect of '%s block'. If --revision is omitted, all the
-    blocked revisions are unblocked""" % NAME,
-    [
-        "-f", "-r", "-S", # import common opts
-    ]),
-
-    "uninit": (action_uninit,
-    "uninit [OPTION...] [PATH]",
-    """Remove merge tracking information from PATH. It cleans any kind of merge
-    tracking information (including the list of blocked revisions). If there
-    are multiple sources, use --source to indicate which source you want to
-    forget about.""",
-    [
-        "-f", "-S", # import common opts
-    ]),
-}
-
-
-def main(args):
-    global opts
-
-    # Initialize default options
-    opts = default_opts.copy()
-    logs.clear()
-
-    optsparser = CommandOpts(global_opts, common_opts, command_table,
-                             version="%%prog r%s\n  modified: %s\n\n"
-                                     "Copyright (C) 2004,2005 Awarix Inc.\n"
-                                     "Copyright (C) 2005, Giovanni Bajo"
-                                     % (__revision__, __date__))
-
-    cmd, args, state = optsparser.parse(args)
-    opts.update(state)
-
-    source = opts.get("source", None)
-    branch_dir = "."
-
-    if str(cmd) == "init":
-        if len(args) == 1:
-            source = args[0]
-        elif len(args) > 1:
-            optsparser.error("wrong number of parameters", cmd)
-    elif str(cmd) in command_table.keys():
-        if len(args) == 1:
-            branch_dir = args[0]
-        elif len(args) > 1:
-            optsparser.error("wrong number of parameters", cmd)
-    else:
-        assert False, "command not handled: %s" % cmd
-
-    # Validate branch_dir
-    if not is_wc(branch_dir):
-        error('"%s" is not a subversion working directory' % branch_dir)
-
-    # Extract the integration info for the branch_dir
-    branch_props = get_merge_props(branch_dir)
-    check_old_prop_version(branch_dir, branch_props)
-
-    # Calculate source_url and source_path
-    report("calculate source path for the branch")
-    if not source:
-        if str(cmd) == "init":
-            cf_source, cf_rev, copy_committed_in_rev = get_copyfrom(branch_dir)
-            if not cf_source:
-                error('no copyfrom info available. '
-                      'Explicit source argument (-S/--source) required.')
-            opts["source-pathid"] = cf_source
-            if not opts["revision"]:
-                opts["revision"] = "1-" + cf_rev
-        else:
-            opts["source-pathid"] = get_default_source(branch_dir, branch_props)
-
-        # (assumes pathid is a repository-relative-path)
-        assert opts["source-pathid"][0] == '/'
-        opts["source-url"] = get_repo_root(branch_dir) + opts["source-pathid"]
-    else:
-        # The source was given as a command line argument and is stored in
-        # SOURCE.  Ensure that the specified source does not end in a /,
-        # otherwise it's easy to have the same source path listed more
-        # than once in the integrated version properties, with and without
-        # trailing /'s.
-        source = rstrip(source, "/")
-        if not is_wc(source) and not is_url(source):
-            # Check if it is a substring of a pathid recorded
-            # within the branch properties.
-            found = []
-            for pathid in branch_props.keys():
-                if pathid.find(source) > 0:
-                    found.append(pathid)
-            if len(found) == 1:
-                # (assumes pathid is a repository-relative-path)
-                source = get_repo_root(branch_dir) + found[0]
-            else:
-                error('"%s" is neither a valid URL, nor an unambiguous '
-                      'substring of a repository path, nor a working directory'
-                      % source)
-
-        source_pathid = target_to_pathid(source)
-        if str(cmd) == "init" and \
-               source_pathid == target_to_pathid("."):
-            error("cannot init integration source path '%s'\n"
-                  "Its repository-relative path must differ from the "
-                  "repository-relative path of the current directory."
-                  % source_pathid)
-        opts["source-pathid"] = source_pathid
-        opts["source-url"] = target_to_url(source)
-
-    # Sanity check source_url
-    assert is_url(opts["source-url"])
-    # SVN does not support non-normalized URL (and we should not
-    # have created them)
-    assert opts["source-url"].find("/..") < 0
-
-    report('source is "%s"' % opts["source-url"])
-
-    # Get previously merged revisions (except when command is init)
-    if str(cmd) != "init":
-        opts["merged-revs"] = merge_props_to_revision_set(branch_props,
-                                                          opts["source-pathid"])
-
-    # Perform the action
-    cmd(branch_dir, branch_props)
-
-
-if __name__ == "__main__":
-    try:
-        main(sys.argv[1:])
-    except LaunchError, (ret, cmd, out):
-        err_msg = "command execution failed (exit code: %d)\n" % ret
-        err_msg += cmd + "\n"
-        err_msg += "".join(out)
-        error(err_msg)
-    except KeyboardInterrupt:
-        # Avoid traceback on CTRL+C
-        print "aborted by user"
-        sys.exit(1)
