diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index a1010aa..d170bc7c 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -68,19 +68,31 @@
 
 def CheckChangeOnCommit(input_api, output_api):
   results = []
+  if not input_api.json:
+    results.append(output_api.PresubmitNotifyResult(
+        'You don\'t have json nor simplejson installed.\n'
+        '  This is a warning that you will need to upgrade your python '
+        'installation.\n'
+        '  This is no big deal but you\'ll eventually need to '
+        'upgrade.\n'
+        '  How? Easy! You can do it right now and shut me off! Just:\n'
+        '    del depot_tools\\python.bat\n'
+        '    gclient\n'
+        '  Thanks for your patience.'))
   results.extend(_CommonChecks(input_api, output_api))
   # TODO(thestig) temporarily disabled, doesn't work in third_party/
   #results.extend(input_api.canned_checks.CheckSvnModifiedDirectories(
   #    input_api, output_api, sources))
   # Make sure the tree is 'open'.
-  # TODO(maruel): Run it in a separate thread to parallelize checks?
-  results.extend(CheckTreeIsOpen(
+  results.extend(input_api.canned_checks.CheckTreeIsOpen(
       input_api,
       output_api,
-      'http://chromium-status.appspot.com/status',
-      '0',
-      'http://chromium-status.appspot.com/current?format=raw'))
-  results.extend(CheckTryJobExecution(input_api, output_api))
+      'http://chromium-status.appspot.com/current?format=raw',
+      '.*closed.*'))
+  results.extend(input_api.canned_checks.CheckRietveldTryJobExecution(input_api,
+      output_api, 'http://codereview.chromium.org', ('win', 'linux', 'mac'),
+      'tryserver@chromium.org'))
+
   # These builders are just too slow.
   IGNORED_BUILDERS = [
     'Chromium XP',
@@ -89,119 +101,14 @@
     'Chromium Linux',
     'Chromium Linux x64',
   ]
-  results.extend(CheckPendingBuilds(
+  results.extend(input_api.canned_checks.CheckBuildbotPendingBuilds(
       input_api,
       output_api,
-      'http://build.chromium.org/buildbot/waterfall/json/builders',
+      'http://build.chromium.org/buildbot/waterfall/json/builders?filter=1',
       6,
       IGNORED_BUILDERS))
   return results
 
 
-def CheckTryJobExecution(input_api, output_api):
-  outputs = []
-  if not input_api.change.issue or not input_api.change.patchset:
-    return outputs
-  url = "http://codereview.chromium.org/%d/get_build_results/%d" % (
-            input_api.change.issue, input_api.change.patchset)
-  PLATFORMS = ('win', 'linux', 'mac')
-  try:
-    connection = input_api.urllib2.urlopen(url)
-    # platform|status|url
-    values = [item.split('|', 2) for item in connection.read().splitlines()]
-    connection.close()
-    if not values:
-      # It returned an empty list. Probably a private review.
-      return outputs
-    # Reformat as an dict of platform: [status, url]
-    values = dict([[v[0], [v[1], v[2]]] for v in values])
-    for platform in PLATFORMS:
-      values.setdefault(platform, ['not started', ''])
-    message = None
-    non_success = [k.upper() for k,v in values.iteritems() if v[0] != 'success']
-    if 'failure' in [v[0] for v in values.itervalues()]:
-      message = 'Try job failures on %s!\n' % ', '.join(non_success)
-    elif non_success:
-      message = ('Unfinished (or not even started) try jobs on '
-                 '%s.\n') % ', '.join(non_success)
-    if message:
-      message += (
-          'Is try server wrong or broken? Please notify maruel@chromium.org. '
-          'Thanks.\n')
-      outputs.append(output_api.PresubmitPromptWarning(message=message))
-  except input_api.urllib2.HTTPError, e:
-    if e.code == 404:
-      # Fallback to no try job.
-      # TODO(maruel): Change to a PresubmitPromptWarning once the try server is
-      # stable enough and it seems to work fine.
-      outputs.append(output_api.PresubmitNotifyResult(
-          'You should try the patch first.'))
-    else:
-      # Another HTTP error happened, warn the user.
-      # TODO(maruel): Change to a PresubmitPromptWarning once it deemed to work
-      # fine.
-      outputs.append(output_api.PresubmitNotifyResult(
-          'Got %s while looking for try job status.' % str(e)))
-  return outputs
-
-
-def CheckTreeIsOpen(input_api, output_api, url, closed, url_text):
-  """Similar to the one in presubmit_canned_checks except it shows an helpful
-  status text instead.
-  """
-  assert(input_api.is_committing)
-  try:
-    connection = input_api.urllib2.urlopen(url)
-    status = connection.read()
-    connection.close()
-    if input_api.re.match(closed, status):
-      long_text = status + '\n' + url
-      try:
-        connection = input_api.urllib2.urlopen(url_text)
-        long_text = connection.read().strip()
-        connection.close()
-      except IOError:
-        pass
-      return [output_api.PresubmitError("The tree is closed.",
-                                        long_text=long_text)]
-  except IOError:
-    pass
-  return []
-
-
-def CheckPendingBuilds(input_api, output_api, url, max_pendings, ignored):
-  try:
-    connection = input_api.urllib2.urlopen(url)
-    raw_data = connection.read()
-    connection.close()
-    try:
-      import simplejson
-      data = simplejson.loads(raw_data)
-    except ImportError:
-      # TODO(maruel): use json parser.
-      # simplejson is much safer. But we should be just fine enough with that:
-      patched_data = raw_data.replace('null', 'None')
-      patched_data = patched_data.replace('false', 'False')
-      patched_data = patched_data.replace('true', 'True')
-      data = eval(patched_data)
-    out = []
-    for (builder_name, builder)  in data.iteritems():
-      if builder_name in ignored:
-        continue
-      pending_builds_len = len(builder.get('pending_builds', []))
-      if pending_builds_len > max_pendings:
-        out.append('%s has %d build(s) pending' %
-                   (builder_name, pending_builds_len))
-    if out:
-      return [output_api.PresubmitPromptWarning(
-          'Build(s) pending. It is suggested to wait that no more than %d '
-              'builds are pending.' % max_pendings,
-          long_text='\n'.join(out))]
-  except IOError:
-    # Silently pass.
-    pass
-  return []
-
-
 def GetPreferredTrySlaves():
   return ['win', 'linux', 'mac']
