diff --git a/tools/bionicbb/README.md b/tools/bionicbb/README.md
index 4d3291f..a285984 100644
--- a/tools/bionicbb/README.md
+++ b/tools/bionicbb/README.md
@@ -8,6 +8,7 @@
 ------------
 
  * Python 2.7
+ * [Advanced Python Scheduler](https://apscheduler.readthedocs.org/en/latest/)
  * [Flask](http://flask.pocoo.org/)
  * [Google API Client Library](https://developers.google.com/api-client-library/python/start/installation)
  * [jenkinsapi](https://pypi.python.org/pypi/jenkinsapi)
diff --git a/tools/bionicbb/build_listener.py b/tools/bionicbb/bionicbb.py
similarity index 90%
rename from tools/bionicbb/build_listener.py
rename to tools/bionicbb/bionicbb.py
index fa55d37..20d6460 100644
--- a/tools/bionicbb/build_listener.py
+++ b/tools/bionicbb/bionicbb.py
@@ -16,11 +16,15 @@
 #
 import json
 import logging
+import os
+
+from apscheduler.schedulers.background import BackgroundScheduler
+from flask import Flask, request
 import requests
 
 import gerrit
+import tasks
 
-from flask import Flask, request
 app = Flask(__name__)
 
 
@@ -115,4 +119,12 @@
 
 
 if __name__ == "__main__":
+    logging.basicConfig(level=logging.INFO)
+
+    # Prevent the job from being rescheduled by the reloader.
+    if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
+        scheduler = BackgroundScheduler()
+        scheduler.start()
+        scheduler.add_job(tasks.get_and_process_jobs, 'interval', minutes=5)
+
     app.run(host='0.0.0.0', debug=True)
diff --git a/tools/bionicbb/gmail.py b/tools/bionicbb/gmail.py
new file mode 100644
index 0000000..f088ad6
--- /dev/null
+++ b/tools/bionicbb/gmail.py
@@ -0,0 +1,71 @@
+#
+# Copyright (C) 2015 The Android Open Source Project
+#
+# 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.
+#
+import base64
+import httplib2
+
+import config
+
+
+def get_body(msg):
+    if 'attachmentId' in msg['payload']['body']:
+        raise NotImplementedError('Handling of messages contained in '
+                                  'attachments not yet implemented.')
+    b64_body = msg['payload']['body']['data']
+    return base64.urlsafe_b64decode(b64_body.encode('ASCII'))
+
+
+def build_service():
+    from apiclient.discovery import build
+    from oauth2client.client import flow_from_clientsecrets
+    from oauth2client.file import Storage
+    from oauth2client.tools import run
+
+    OAUTH_SCOPE = 'https://www.googleapis.com/auth/gmail.modify'
+    STORAGE = Storage('oauth.storage')
+
+    # Start the OAuth flow to retrieve credentials
+    flow = flow_from_clientsecrets(config.client_secret_file,
+                                   scope=OAUTH_SCOPE)
+    http = httplib2.Http()
+
+    # Try to retrieve credentials from storage or run the flow to generate them
+    credentials = STORAGE.get()
+    if credentials is None or credentials.invalid:
+        credentials = run(flow, STORAGE, http=http)
+
+    http = credentials.authorize(http)
+    return build('gmail', 'v1', http=http)
+
+
+def get_gerrit_label(labels):
+    for label in labels:
+        if label['name'] == 'gerrit':
+            return label['id']
+    return None
+
+
+def get_all_messages(service, label):
+    msgs = []
+    response = service.users().messages().list(
+        userId='me', labelIds=label).execute()
+    if 'messages' in response:
+        msgs.extend(response['messages'])
+    while 'nextPageToken' in response:
+        page_token = response['nextPageToken']
+        response = service.users().messages().list(
+            userId='me', pageToken=page_token).execute()
+        msgs.extend(response['messages'])
+    return msgs
diff --git a/tools/bionicbb/gmail_listener.py b/tools/bionicbb/gmail_listener.py
deleted file mode 100644
index 134258a..0000000
--- a/tools/bionicbb/gmail_listener.py
+++ /dev/null
@@ -1,354 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (C) 2015 The Android Open Source Project
-#
-# 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.
-#
-import base64
-import httplib
-import httplib2
-import jenkinsapi
-import json
-import logging
-import os
-import re
-import requests
-import socket
-import sys
-import time
-
-import apiclient.errors
-
-import config
-import gerrit
-
-
-class GmailError(RuntimeError):
-    def __init__(self, message):
-        super(GmailError, self).__init__(message)
-
-
-def get_gerrit_label(labels):
-    for label in labels:
-        if label['name'] == 'gerrit':
-            return label['id']
-    return None
-
-
-def get_headers(msg):
-    headers = {}
-    for hdr in msg['payload']['headers']:
-        headers[hdr['name']] = hdr['value']
-    return headers
-
-
-def is_untrusted_committer(change_id, patch_set):
-    # TODO(danalbert): Needs to be based on the account that made the comment.
-    commit = gerrit.get_commit(change_id, patch_set)
-    committer = commit['committer']['email']
-    return not committer.endswith('@google.com')
-
-
-def contains_cleanspec(change_id, patch_set):
-    files = gerrit.get_files_for_revision(change_id, patch_set)
-    return 'CleanSpec.mk' in [os.path.basename(f) for f in files]
-
-
-def contains_bionicbb(change_id, patch_set):
-    files = gerrit.get_files_for_revision(change_id, patch_set)
-    return any('tools/bionicbb' in f for f in files)
-
-
-def should_skip_build(info):
-    if info['MessageType'] not in ('newchange', 'newpatchset', 'comment'):
-        raise ValueError('should_skip_build() is only valid for new '
-                         'changes, patch sets, and commits.')
-
-    change_id = info['Change-Id']
-    patch_set = info['PatchSet']
-
-    checks = [
-        is_untrusted_committer,
-        contains_cleanspec,
-        contains_bionicbb,
-    ]
-    for check in checks:
-        if check(change_id, patch_set):
-            return True
-    return False
-
-
-def build_service():
-    from apiclient.discovery import build
-    from oauth2client.client import flow_from_clientsecrets
-    from oauth2client.file import Storage
-    from oauth2client.tools import run
-
-    OAUTH_SCOPE = 'https://www.googleapis.com/auth/gmail.modify'
-    STORAGE = Storage('oauth.storage')
-
-    # Start the OAuth flow to retrieve credentials
-    flow = flow_from_clientsecrets(config.client_secret_file,
-                                   scope=OAUTH_SCOPE)
-    http = httplib2.Http()
-
-    # Try to retrieve credentials from storage or run the flow to generate them
-    credentials = STORAGE.get()
-    if credentials is None or credentials.invalid:
-        credentials = run(flow, STORAGE, http=http)
-
-    http = credentials.authorize(http)
-    return build('gmail', 'v1', http=http)
-
-
-def get_all_messages(service, label):
-    msgs = []
-    response = service.users().messages().list(
-        userId='me', labelIds=label).execute()
-    if 'messages' in response:
-        msgs.extend(response['messages'])
-    while 'nextPageToken' in response:
-        page_token = response['nextPageToken']
-        response = service.users().messages().list(
-            userId='me', pageToken=page_token).execute()
-        msgs.extend(response['messages'])
-    return msgs
-
-
-def get_body(msg):
-    if 'attachmentId' in msg['payload']['body']:
-        raise NotImplementedError('Handling of messages contained in '
-                                  'attachments not yet implemented.')
-    b64_body = msg['payload']['body']['data']
-    return base64.urlsafe_b64decode(b64_body.encode('ASCII'))
-
-
-def get_gerrit_info(body):
-    info = {}
-    gerrit_pattern = r'^Gerrit-(\S+): (.+)$'
-    for match in re.finditer(gerrit_pattern, body, flags=re.MULTILINE):
-        info[match.group(1)] = match.group(2).strip()
-    return info
-
-
-def clean_project(dry_run):
-    username = config.jenkins_credentials['username']
-    password = config.jenkins_credentials['password']
-    jenkins_url = config.jenkins_url
-    jenkins = jenkinsapi.api.Jenkins(jenkins_url, username, password)
-
-    build = 'clean-bionic-presubmit'
-    if build in jenkins:
-        if not dry_run:
-            job = jenkins[build].invoke()
-            url = job.get_build().baseurl
-        else:
-            url = 'DRY_RUN_URL'
-        logging.info('Cleaning: %s %s', build, url)
-    else:
-        logging.error('Failed to clean: could not find project %s', build)
-    return True
-
-
-def build_project(gerrit_info, dry_run, lunch_target=None):
-    project_to_jenkins_map = {
-        'platform/bionic': 'bionic-presubmit',
-        'platform/build': 'bionic-presubmit',
-        'platform/external/jemalloc': 'bionic-presubmit',
-        'platform/external/libcxx': 'bionic-presubmit',
-        'platform/external/libcxxabi': 'bionic-presubmit',
-        'platform/external/compiler-rt': 'bionic-presubmit',
-    }
-
-    username = config.jenkins_credentials['username']
-    password = config.jenkins_credentials['password']
-    jenkins_url = config.jenkins_url
-    jenkins = jenkinsapi.api.Jenkins(jenkins_url, username, password)
-
-    project = gerrit_info['Project']
-    change_id = gerrit_info['Change-Id']
-    if project in project_to_jenkins_map:
-        build = project_to_jenkins_map[project]
-    else:
-        build = 'bionic-presubmit'
-
-    if build in jenkins:
-        project_path = '/'.join(project.split('/')[1:])
-        if not project_path:
-            raise RuntimeError('bogus project: {}'.format(project))
-        if project_path.startswith('platform/'):
-            raise RuntimeError('Bad project mapping: {} => {}'.format(
-                project, project_path))
-        ref = gerrit.ref_for_change(change_id)
-        params = {
-            'REF': ref,
-            'CHANGE_ID': change_id,
-            'PROJECT': project_path
-        }
-        if lunch_target is not None:
-            params['LUNCH_TARGET'] = lunch_target
-        if not dry_run:
-            _ = jenkins[build].invoke(build_params=params)
-            # https://issues.jenkins-ci.org/browse/JENKINS-27256
-            # url = job.get_build().baseurl
-            url = 'URL UNAVAILABLE'
-        else:
-            url = 'DRY_RUN_URL'
-        logging.info('Building: %s => %s %s %s', project, build, url,
-                     change_id)
-    else:
-        logging.error('Unknown build: %s => %s %s', project, build, change_id)
-    return True
-
-
-def handle_change(gerrit_info, _, dry_run):
-    if should_skip_build(gerrit_info):
-        return True
-    return build_project(gerrit_info, dry_run)
-handle_newchange = handle_change
-handle_newpatchset = handle_change
-
-
-def drop_rejection(gerrit_info, dry_run):
-    request_data = {
-        'changeid': gerrit_info['Change-Id'],
-        'patchset': gerrit_info['PatchSet']
-    }
-    url = '{}/{}'.format(config.build_listener_url, 'drop-rejection')
-    headers = {'Content-Type': 'application/json;charset=UTF-8'}
-    if not dry_run:
-        try:
-            requests.post(url, headers=headers, data=json.dumps(request_data))
-        except requests.exceptions.ConnectionError as ex:
-            logging.error('Failed to drop rejection: %s', ex)
-            return False
-    logging.info('Dropped rejection: %s', gerrit_info['Change-Id'])
-    return True
-
-
-def handle_comment(gerrit_info, body, dry_run):
-    if 'Verified+1' in body:
-        drop_rejection(gerrit_info, dry_run)
-
-    if should_skip_build(gerrit_info):
-        return True
-
-    command_map = {
-        'clean': lambda: clean_project(dry_run),
-        'retry': lambda: build_project(gerrit_info, dry_run),
-
-        'arm': lambda: build_project(gerrit_info, dry_run,
-                                     lunch_target='aosp_arm-eng'),
-        'aarch64': lambda: build_project(gerrit_info, dry_run,
-                                         lunch_target='aosp_arm64-eng'),
-        'mips': lambda: build_project(gerrit_info, dry_run,
-                                      lunch_target='aosp_mips-eng'),
-        'mips64': lambda: build_project(gerrit_info, dry_run,
-                                        lunch_target='aosp_mips64-eng'),
-        'x86': lambda: build_project(gerrit_info, dry_run,
-                                     lunch_target='aosp_x86-eng'),
-        'x86_64': lambda: build_project(gerrit_info, dry_run,
-                                        lunch_target='aosp_x86_64-eng'),
-    }
-
-    def handle_unknown_command():
-        pass    # TODO(danalbert): should complain to the commenter.
-
-    commands = [match.group(1).strip() for match in
-                re.finditer(r'^bionicbb:\s*(.+)$', body, flags=re.MULTILINE)]
-
-    for command in commands:
-        if command in command_map:
-            command_map[command]()
-        else:
-            handle_unknown_command()
-
-    return True
-
-
-def skip_handler(gerrit_info, _, __):
-    logging.info('Skipping %s: %s', gerrit_info['MessageType'],
-                 gerrit_info['Change-Id'])
-    return True
-
-
-handle_abandon = skip_handler
-handle_merge_failed = skip_handler
-handle_merged = skip_handler
-handle_restore = skip_handler
-handle_revert = skip_handler
-
-
-def process_message(msg, dry_run):
-    try:
-        body = get_body(msg)
-        gerrit_info = get_gerrit_info(body)
-        if not gerrit_info:
-            logging.fatal('No Gerrit info found: %s', msg.subject)
-        msg_type = gerrit_info['MessageType']
-        handler = 'handle_{}'.format(
-            gerrit_info['MessageType'].replace('-', '_'))
-        if handler in globals():
-            return globals()[handler](gerrit_info, body, dry_run)
-        else:
-            logging.warning('MessageType %s unhandled.', msg_type)
-        return False
-    except NotImplementedError as ex:
-        logging.error("%s", ex)
-        return False
-    except gerrit.GerritError as ex:
-        change_id = gerrit_info['Change-Id']
-        logging.error('Gerrit error (%d): %s %s', ex.code, change_id, ex.url)
-        return ex.code == 404
-
-
-def main(argc, argv):
-    dry_run = False
-    if argc == 2 and argv[1] == '--dry-run':
-        dry_run = True
-    elif argc > 2:
-        sys.exit('usage: python {} [--dry-run]'.format(argv[0]))
-
-    gmail_service = build_service()
-    msg_service = gmail_service.users().messages()
-
-    while True:
-        try:
-            labels = gmail_service.users().labels().list(userId='me').execute()
-            if not labels['labels']:
-                raise GmailError('Could not retrieve Gmail labels')
-            label_id = get_gerrit_label(labels['labels'])
-            if not label_id:
-                raise GmailError('Could not find gerrit label')
-
-            for msg in get_all_messages(gmail_service, label_id):
-                msg = msg_service.get(userId='me', id=msg['id']).execute()
-                if process_message(msg, dry_run) and not dry_run:
-                    msg_service.trash(userId='me', id=msg['id']).execute()
-            time.sleep(60 * 5)
-        except GmailError as ex:
-            logging.error('Gmail error: %s', ex)
-            time.sleep(60 * 5)
-        except apiclient.errors.HttpError as ex:
-            logging.error('API Client HTTP error: %s', ex)
-            time.sleep(60 * 5)
-        except httplib.BadStatusLine:
-            pass
-        except httplib2.ServerNotFoundError:
-            pass
-        except socket.error:
-            pass
-
-
-if __name__ == '__main__':
-    main(len(sys.argv), sys.argv)
diff --git a/tools/bionicbb/presubmit.py b/tools/bionicbb/presubmit.py
new file mode 100644
index 0000000..cc6f3cc
--- /dev/null
+++ b/tools/bionicbb/presubmit.py
@@ -0,0 +1,203 @@
+#
+# Copyright (C) 2015 The Android Open Source Project
+#
+# 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.
+#
+from __future__ import absolute_import
+
+import json
+import logging
+import os.path
+import re
+import requests
+
+import jenkinsapi
+
+import gerrit
+
+import config
+
+
+def is_untrusted_committer(change_id, patch_set):
+    # TODO(danalbert): Needs to be based on the account that made the comment.
+    commit = gerrit.get_commit(change_id, patch_set)
+    committer = commit['committer']['email']
+    return not committer.endswith('@google.com')
+
+
+def contains_cleanspec(change_id, patch_set):
+    files = gerrit.get_files_for_revision(change_id, patch_set)
+    return 'CleanSpec.mk' in [os.path.basename(f) for f in files]
+
+
+def contains_bionicbb(change_id, patch_set):
+    files = gerrit.get_files_for_revision(change_id, patch_set)
+    return any('tools/bionicbb' in f for f in files)
+
+
+def should_skip_build(info):
+    if info['MessageType'] not in ('newchange', 'newpatchset', 'comment'):
+        raise ValueError('should_skip_build() is only valid for new '
+                         'changes, patch sets, and commits.')
+
+    change_id = info['Change-Id']
+    patch_set = info['PatchSet']
+
+    checks = [
+        is_untrusted_committer,
+        contains_cleanspec,
+        contains_bionicbb,
+    ]
+    for check in checks:
+        if check(change_id, patch_set):
+            return True
+    return False
+
+
+def clean_project(dry_run):
+    username = config.jenkins_credentials['username']
+    password = config.jenkins_credentials['password']
+    jenkins_url = config.jenkins_url
+    jenkins = jenkinsapi.api.Jenkins(jenkins_url, username, password)
+
+    build = 'clean-bionic-presubmit'
+    if build in jenkins:
+        if not dry_run:
+            job = jenkins[build].invoke()
+            url = job.get_build().baseurl
+        else:
+            url = 'DRY_RUN_URL'
+        logging.info('Cleaning: %s %s', build, url)
+    else:
+        logging.error('Failed to clean: could not find project %s', build)
+    return True
+
+
+def build_project(gerrit_info, dry_run, lunch_target=None):
+    project_to_jenkins_map = {
+        'platform/bionic': 'bionic-presubmit',
+        'platform/build': 'bionic-presubmit',
+        'platform/external/jemalloc': 'bionic-presubmit',
+        'platform/external/libcxx': 'bionic-presubmit',
+        'platform/external/libcxxabi': 'bionic-presubmit',
+        'platform/external/compiler-rt': 'bionic-presubmit',
+    }
+
+    username = config.jenkins_credentials['username']
+    password = config.jenkins_credentials['password']
+    jenkins_url = config.jenkins_url
+    jenkins = jenkinsapi.api.Jenkins(jenkins_url, username, password)
+
+    project = gerrit_info['Project']
+    change_id = gerrit_info['Change-Id']
+    if project in project_to_jenkins_map:
+        build = project_to_jenkins_map[project]
+    else:
+        build = 'bionic-presubmit'
+
+    if build in jenkins:
+        project_path = '/'.join(project.split('/')[1:])
+        if not project_path:
+            raise RuntimeError('bogus project: {}'.format(project))
+        if project_path.startswith('platform/'):
+            raise RuntimeError('Bad project mapping: {} => {}'.format(
+                project, project_path))
+        ref = gerrit.ref_for_change(change_id)
+        params = {
+            'REF': ref,
+            'CHANGE_ID': change_id,
+            'PROJECT': project_path
+        }
+        if lunch_target is not None:
+            params['LUNCH_TARGET'] = lunch_target
+        if not dry_run:
+            _ = jenkins[build].invoke(build_params=params)
+            # https://issues.jenkins-ci.org/browse/JENKINS-27256
+            # url = job.get_build().baseurl
+            url = 'URL UNAVAILABLE'
+        else:
+            url = 'DRY_RUN_URL'
+        logging.info('Building: %s => %s %s %s', project, build, url,
+                     change_id)
+    else:
+        logging.error('Unknown build: %s => %s %s', project, build, change_id)
+    return True
+
+
+def handle_change(gerrit_info, _, dry_run):
+    if should_skip_build(gerrit_info):
+        return True
+    return build_project(gerrit_info, dry_run)
+
+
+def drop_rejection(gerrit_info, dry_run):
+    request_data = {
+        'changeid': gerrit_info['Change-Id'],
+        'patchset': gerrit_info['PatchSet']
+    }
+    url = '{}/{}'.format(config.build_listener_url, 'drop-rejection')
+    headers = {'Content-Type': 'application/json;charset=UTF-8'}
+    if not dry_run:
+        try:
+            requests.post(url, headers=headers, data=json.dumps(request_data))
+        except requests.exceptions.ConnectionError as ex:
+            logging.error('Failed to drop rejection: %s', ex)
+            return False
+    logging.info('Dropped rejection: %s', gerrit_info['Change-Id'])
+    return True
+
+
+def handle_comment(gerrit_info, body, dry_run):
+    if 'Verified+1' in body:
+        drop_rejection(gerrit_info, dry_run)
+
+    if should_skip_build(gerrit_info):
+        return True
+
+    command_map = {
+        'clean': lambda: clean_project(dry_run),
+        'retry': lambda: build_project(gerrit_info, dry_run),
+
+        'arm': lambda: build_project(gerrit_info, dry_run,
+                                     lunch_target='aosp_arm-eng'),
+        'aarch64': lambda: build_project(gerrit_info, dry_run,
+                                         lunch_target='aosp_arm64-eng'),
+        'mips': lambda: build_project(gerrit_info, dry_run,
+                                      lunch_target='aosp_mips-eng'),
+        'mips64': lambda: build_project(gerrit_info, dry_run,
+                                        lunch_target='aosp_mips64-eng'),
+        'x86': lambda: build_project(gerrit_info, dry_run,
+                                     lunch_target='aosp_x86-eng'),
+        'x86_64': lambda: build_project(gerrit_info, dry_run,
+                                        lunch_target='aosp_x86_64-eng'),
+    }
+
+    def handle_unknown_command():
+        pass    # TODO(danalbert): should complain to the commenter.
+
+    commands = [match.group(1).strip() for match in
+                re.finditer(r'^bionicbb:\s*(.+)$', body, flags=re.MULTILINE)]
+
+    for command in commands:
+        if command in command_map:
+            command_map[command]()
+        else:
+            handle_unknown_command()
+
+    return True
+
+
+def skip_handler(gerrit_info, _, __):
+    logging.info('Skipping %s: %s', gerrit_info['MessageType'],
+                 gerrit_info['Change-Id'])
+    return True
diff --git a/tools/bionicbb/tasks.py b/tools/bionicbb/tasks.py
new file mode 100644
index 0000000..4c39a98
--- /dev/null
+++ b/tools/bionicbb/tasks.py
@@ -0,0 +1,108 @@
+#
+# Copyright (C) 2015 The Android Open Source Project
+#
+# 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.
+#
+import httplib
+import httplib2
+import logging
+import re
+import socket
+
+import apiclient.errors
+
+import gerrit
+import gmail
+import presubmit
+
+
+def get_gerrit_info(body):
+    info = {}
+    gerrit_pattern = r'^Gerrit-(\S+): (.+)$'
+    for match in re.finditer(gerrit_pattern, body, flags=re.MULTILINE):
+        info[match.group(1)] = match.group(2).strip()
+    return info
+
+
+def process_message(msg, dry_run):
+    try:
+        body = gmail.get_body(msg)
+        gerrit_info = get_gerrit_info(body)
+        if not gerrit_info:
+            logging.fatal('No Gerrit info found: %s', msg.subject)
+        msg_type = gerrit_info['MessageType']
+        handlers = {
+            'comment': presubmit.handle_comment,
+            'newchange': presubmit.handle_change,
+            'newpatchset': presubmit.handle_change,
+
+            'abandon': presubmit.skip_handler,
+            'merge-failed': presubmit.skip_handler,
+            'merged': presubmit.skip_handler,
+            'restore': presubmit.skip_handler,
+            'revert': presubmit.skip_handler,
+        }
+
+        message_type = gerrit_info['MessageType']
+        if message_type in handlers:
+            return handlers[message_type](gerrit_info, body, dry_run)
+        else:
+            logging.warning('MessageType %s unhandled.', msg_type)
+        return False
+    except NotImplementedError as ex:
+        logging.error("%s", ex)
+        return False
+    except gerrit.GerritError as ex:
+        change_id = gerrit_info['Change-Id']
+        logging.error('Gerrit error (%d): %s %s', ex.code, change_id, ex.url)
+        return ex.code == 404
+
+
+def get_and_process_jobs():
+    dry_run = False
+
+    gmail_service = gmail.build_service()
+    msg_service = gmail_service.users().messages()
+
+    # We run in a loop because some of the exceptions thrown here mean we just
+    # need to retry. For errors where we should back off (typically any gmail
+    # API exceptions), process_changes catches the error and returns normally.
+    while True:
+        try:
+            process_changes(gmail_service, msg_service, dry_run)
+            return
+        except httplib.BadStatusLine:
+            pass
+        except httplib2.ServerNotFoundError:
+            pass
+        except socket.error:
+            pass
+
+
+def process_changes(gmail_service, msg_service, dry_run):
+    try:
+        labels = gmail_service.users().labels().list(userId='me').execute()
+        if not labels['labels']:
+            logging.error('Could not retrieve Gmail labels')
+            return
+        label_id = gmail.get_gerrit_label(labels['labels'])
+        if not label_id:
+            logging.error('Could not find gerrit label')
+            return
+
+        for msg in gmail.get_all_messages(gmail_service, label_id):
+            msg = msg_service.get(userId='me', id=msg['id']).execute()
+            if process_message(msg, dry_run) and not dry_run:
+                msg_service.trash(userId='me', id=msg['id']).execute()
+    except apiclient.errors.HttpError as ex:
+        logging.error('API Client HTTP error: %s', ex)
diff --git a/tools/bionicbb/test_gmail_listener.py b/tools/bionicbb/test_tasks.py
similarity index 74%
rename from tools/bionicbb/test_gmail_listener.py
rename to tools/bionicbb/test_tasks.py
index f8b9ab6..b36cbad 100644
--- a/tools/bionicbb/test_gmail_listener.py
+++ b/tools/bionicbb/test_tasks.py
@@ -1,11 +1,12 @@
-import gmail_listener
 import mock
 import unittest
 
+import presubmit
+
 
 class TestShouldSkipBuild(unittest.TestCase):
-    @mock.patch('gmail_listener.contains_bionicbb')
-    @mock.patch('gmail_listener.contains_cleanspec')
+    @mock.patch('presubmit.contains_bionicbb')
+    @mock.patch('presubmit.contains_cleanspec')
     @mock.patch('gerrit.get_commit')
     def test_accepts_googlers(self, mock_commit, *other_checks):
         mock_commit.return_value = {
@@ -16,14 +17,14 @@
             other_check.return_value = False
 
         for message_type in ('newchange', 'newpatchset', 'comment'):
-            self.assertFalse(gmail_listener.should_skip_build({
+            self.assertFalse(presubmit.should_skip_build({
                 'MessageType': message_type,
                 'Change-Id': '',
                 'PatchSet': '',
             }))
 
-    @mock.patch('gmail_listener.contains_bionicbb')
-    @mock.patch('gmail_listener.contains_cleanspec')
+    @mock.patch('presubmit.contains_bionicbb')
+    @mock.patch('presubmit.contains_cleanspec')
     @mock.patch('gerrit.get_commit')
     def test_rejects_googlish_domains(self, mock_commit, *other_checks):
         mock_commit.return_value = {
@@ -34,14 +35,14 @@
             other_check.return_value = False
 
         for message_type in ('newchange', 'newpatchset', 'comment'):
-            self.assertTrue(gmail_listener.should_skip_build({
+            self.assertTrue(presubmit.should_skip_build({
                 'MessageType': message_type,
                 'Change-Id': '',
                 'PatchSet': '',
             }))
 
-    @mock.patch('gmail_listener.contains_bionicbb')
-    @mock.patch('gmail_listener.contains_cleanspec')
+    @mock.patch('presubmit.contains_bionicbb')
+    @mock.patch('presubmit.contains_cleanspec')
     @mock.patch('gerrit.get_commit')
     def test_rejects_non_googlers(self, mock_commit, *other_checks):
         mock_commit.return_value = {
@@ -52,14 +53,14 @@
             other_check.return_value = False
 
         for message_type in ('newchange', 'newpatchset', 'comment'):
-            self.assertTrue(gmail_listener.should_skip_build({
+            self.assertTrue(presubmit.should_skip_build({
                 'MessageType': message_type,
                 'Change-Id': '',
                 'PatchSet': '',
             }))
 
-    @mock.patch('gmail_listener.contains_bionicbb')
-    @mock.patch('gmail_listener.is_untrusted_committer')
+    @mock.patch('presubmit.contains_bionicbb')
+    @mock.patch('presubmit.is_untrusted_committer')
     @mock.patch('gerrit.get_files_for_revision')
     def test_skips_cleanspecs(self, mock_files, *other_checks):
         mock_files.return_value = ['foo/CleanSpec.mk']
@@ -67,14 +68,14 @@
             other_check.return_value = False
 
         for message_type in ('newchange', 'newpatchset', 'comment'):
-            self.assertTrue(gmail_listener.should_skip_build({
+            self.assertTrue(presubmit.should_skip_build({
                 'MessageType': message_type,
                 'Change-Id': '',
                 'PatchSet': '',
             }))
 
-    @mock.patch('gmail_listener.contains_cleanspec')
-    @mock.patch('gmail_listener.is_untrusted_committer')
+    @mock.patch('presubmit.contains_cleanspec')
+    @mock.patch('presubmit.is_untrusted_committer')
     @mock.patch('gerrit.get_files_for_revision')
     def test_skips_bionicbb(self, mock_files, *other_checks):
         mock_files.return_value = ['tools/bionicbb/common.sh']
@@ -82,7 +83,7 @@
             other_check.return_value = False
 
         for message_type in ('newchange', 'newpatchset', 'comment'):
-            self.assertTrue(gmail_listener.should_skip_build({
+            self.assertTrue(presubmit.should_skip_build({
                 'MessageType': message_type,
                 'Change-Id': '',
                 'PatchSet': '',
