diff --git a/tools/ci/common.py b/tools/ci/common.py
new file mode 100644
index 0000000..50ca860
--- /dev/null
+++ b/tools/ci/common.py
@@ -0,0 +1,878 @@
+#!/usr/bin/env python
+
+# Copyright Rene Rivera 2016
+#
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import sys
+import inspect
+import optparse
+import os.path
+import string
+import time
+import subprocess
+import codecs
+import shutil
+import threading
+
+toolset_info = {
+    'clang-3.4' : {
+        'ppa' : ["ppa:h-rayflood/llvm"],
+        'package' : 'clang-3.4',
+        'command' : 'clang++-3.4',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'clang-3.5' : {
+        'ppa' : ["ppa:h-rayflood/llvm"],
+        'package' : 'clang-3.5',
+        'command' : 'clang++-3.5',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'clang-3.6' : {
+        'ppa' : ["ppa:h-rayflood/llvm"],
+        'package' : 'clang-3.6',
+        'command' : 'clang++-3.6',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'clang-3.7' : {
+        'deb' : ["http://apt.llvm.org/trusty/","llvm-toolchain-trusty-3.7","main"],
+        'apt-key' : ['http://apt.llvm.org/llvm-snapshot.gpg.key'],
+        'package' : 'clang-3.7',
+        'command' : 'clang++-3.7',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'clang-3.8' : {
+        'deb' : ["http://apt.llvm.org/trusty/","llvm-toolchain-trusty-3.8","main"],
+        'apt-key' : ['http://apt.llvm.org/llvm-snapshot.gpg.key'],
+        'package' : 'clang-3.8',
+        'command' : 'clang++-3.8',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'clang-3.9' : {
+        'deb' : ["http://apt.llvm.org/trusty/","llvm-toolchain-trusty-3.9","main"],
+        'apt-key' : ['http://apt.llvm.org/llvm-snapshot.gpg.key'],
+        'package' : 'clang-3.9',
+        'command' : 'clang++-3.9',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'clang-4.0' : {
+        'deb' : ["http://apt.llvm.org/trusty/","llvm-toolchain-trusty-4.0","main"],
+        'apt-key' : ['http://apt.llvm.org/llvm-snapshot.gpg.key'],
+        'package' : 'clang-4.0',
+        'command' : 'clang++-4.0',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'clang-5.0' : {
+        'deb' : ["http://apt.llvm.org/trusty/","llvm-toolchain-trusty-5.0","main"],
+        'apt-key' : ['http://apt.llvm.org/llvm-snapshot.gpg.key'],
+        'package' : 'clang-5.0',
+        'command' : 'clang++-5.0',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'clang-6.0' : {
+        'deb' : ["http://apt.llvm.org/trusty/","llvm-toolchain-trusty-6.0","main"],
+        'apt-key' : ['http://apt.llvm.org/llvm-snapshot.gpg.key'],
+        'package' : 'clang-6.0',
+        'command' : 'clang++-6.0',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'gcc-4.7' : {
+        'ppa' : ["ppa:ubuntu-toolchain-r/test"],
+        'package' : 'g++-4.7',
+        'command' : 'g++-4.7',
+        'toolset' : 'gcc',
+        'version' : ''
+        },
+    'gcc-4.8' : {
+        'bin' : 'gcc-4.8',
+        'ppa' : ["ppa:ubuntu-toolchain-r/test"],
+        'package' : 'g++-4.8',
+        'command' : 'g++-4.8',
+        'toolset' : 'gcc',
+        'version' : ''
+        },
+    'gcc-4.9' : {
+        'ppa' : ["ppa:ubuntu-toolchain-r/test"],
+        'package' : 'g++-4.9',
+        'command' : 'g++-4.9',
+        'toolset' : 'gcc',
+        'version' : ''
+        },
+    'gcc-5.1' : {
+        'ppa' : ["ppa:ubuntu-toolchain-r/test"],
+        'package' : 'g++-5',
+        'command' : 'g++-5',
+        'toolset' : 'gcc',
+        'version' : ''
+        },
+    'gcc-5' : {
+        'ppa' : ["ppa:ubuntu-toolchain-r/test"],
+        'package' : 'g++-5',
+        'command' : 'g++-5',
+        'toolset' : 'gcc',
+        'version' : ''
+        },
+    'gcc-6' : {
+        'ppa' : ["ppa:ubuntu-toolchain-r/test"],
+        'package' : 'g++-6',
+        'command' : 'g++-6',
+        'toolset' : 'gcc',
+        'version' : ''
+        },
+    'gcc-7' : {
+        'ppa' : ["ppa:ubuntu-toolchain-r/test"],
+        'package' : 'g++-7',
+        'command' : 'g++-7',
+        'toolset' : 'gcc',
+        'version' : ''
+        },
+    'gcc-8' : {
+        'ppa' : ["ppa:ubuntu-toolchain-r/test"],
+        'package' : 'g++-8',
+        'command' : 'g++-8',
+        'toolset' : 'gcc',
+        'version' : ''
+        },
+    'mingw-5' : {
+        'toolset' : 'gcc',
+        'command' : 'C:\\\\MinGW\\\\bin\\\\g++.exe',
+        'version' : ''
+        },
+    'mingw64-6' : {
+        'toolset' : 'gcc',
+        'command' : 'C:\\\\mingw-w64\\\\x86_64-6.3.0-posix-seh-rt_v5-rev1\\\\mingw64\\\\bin\\\\g++.exe',
+        'version' : ''
+        },
+    'vs-2008' : {
+        'toolset' : 'msvc',
+        'command' : '',
+        'version' : '9.0'
+        },
+    'vs-2010' : {
+        'toolset' : 'msvc',
+        'command' : '',
+        'version' : '10.0'
+        },
+    'vs-2012' : {
+        'toolset' : 'msvc',
+        'command' : '',
+        'version' : '11.0'
+        },
+    'vs-2013' : {
+        'toolset' : 'msvc',
+        'command' : '',
+        'version' : '12.0'
+        },
+    'vs-2015' : {
+        'toolset' : 'msvc',
+        'command' : '',
+        'version' : '14.0'
+        },
+    'vs-2017' : {
+        'toolset' : 'msvc',
+        'command' : '',
+        'version' : '14.1'
+        },
+    'xcode-6.1' : {
+        'command' : 'clang++',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'xcode-6.2' : {
+        'command' : 'clang++',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'xcode-6.3' : {
+        'command' : 'clang++',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'xcode-6.4' : {
+        'command' : 'clang++',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'xcode-7.0' : {
+        'command' : 'clang++',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'xcode-7.1' : {
+        'command' : 'clang++',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'xcode-7.2' : {
+        'command' : 'clang++',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'xcode-7.3' : {
+        'command' : 'clang++',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'xcode-8.0' : {
+        'command' : 'clang++',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'xcode-8.1' : {
+        'command' : 'clang++',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'xcode-8.2' : {
+        'command' : 'clang++',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'xcode-8.3' : {
+        'command' : 'clang++',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'xcode-9.0' : {
+        'command' : 'clang++',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    'xcode-9.1' : {
+        'command' : 'clang++',
+        'toolset' : 'clang',
+        'version' : ''
+        },
+    }
+
+class SystemCallError(Exception):
+    def __init__(self, command, result):
+        self.command = command
+        self.result = result
+    def __str__(self, *args, **kwargs):
+        return "'%s' ==> %s"%("' '".join(self.command), self.result)
+
+class utils:
+    
+    call_stats = []
+    
+    @staticmethod
+    def call(*command, **kargs):
+        utils.log( "%s> '%s'"%(os.getcwd(), "' '".join(command)) )
+        t = time.time()
+        result = subprocess.call(command, **kargs)
+        t = time.time()-t
+        if result != 0:
+            print "Failed: '%s' ERROR = %s"%("' '".join(command), result)
+        utils.call_stats.append((t,os.getcwd(),command,result))
+        utils.log( "%s> '%s' execution time %s seconds"%(os.getcwd(), "' '".join(command), t) )
+        return result
+    
+    @staticmethod
+    def print_call_stats():
+        utils.log("================================================================================")
+        for j in sorted(utils.call_stats, reverse=True):
+            utils.log("{:>12.4f}\t{}> {} ==> {}".format(*j))
+        utils.log("================================================================================")
+    
+    @staticmethod
+    def check_call(*command, **kargs):
+        cwd = os.getcwd()
+        result = utils.call(*command, **kargs)
+        if result != 0:
+            raise(SystemCallError([cwd].extend(command), result))
+    
+    @staticmethod
+    def makedirs( path ):
+        if not os.path.exists( path ):
+            os.makedirs( path )
+    
+    @staticmethod
+    def log_level():
+        frames = inspect.stack()
+        level = 0
+        for i in frames[ 3: ]:
+            if i[0].f_locals.has_key( '__log__' ):
+                level = level + i[0].f_locals[ '__log__' ]
+        return level
+    
+    @staticmethod
+    def log( message ):
+        sys.stdout.flush()
+        sys.stderr.flush()
+        sys.stderr.write( '# ' + '    ' * utils.log_level() +  message + '\n' )
+        sys.stderr.flush()
+
+    @staticmethod
+    def rmtree(path):
+        if os.path.exists( path ):
+            #~ shutil.rmtree( unicode( path ) )
+            if sys.platform == 'win32':
+                os.system( 'del /f /s /q "%s" >nul 2>&1' % path )
+                shutil.rmtree( unicode( path ) )
+            else:
+                os.system( 'rm -f -r "%s"' % path )
+
+    @staticmethod
+    def retry( f, max_attempts=5, sleep_secs=10 ):
+        for attempts in range( max_attempts, -1, -1 ):
+            try:
+                return f()
+            except Exception, msg:
+                utils.log( '%s failed with message "%s"' % ( f.__name__, msg ) )
+                if attempts == 0:
+                    utils.log( 'Giving up.' )
+                    raise
+
+                utils.log( 'Retrying (%d more attempts).' % attempts )
+                time.sleep( sleep_secs )
+
+    @staticmethod
+    def web_get( source_url, destination_file, proxy = None ):
+        import urllib
+
+        proxies = None
+        if proxy is not None:
+            proxies = {
+                'https' : proxy,
+                'http' : proxy
+                }
+
+        src = urllib.urlopen( source_url, proxies = proxies )
+
+        f = open( destination_file, 'wb' )
+        while True:
+            data = src.read( 16*1024 )
+            if len( data ) == 0: break
+            f.write( data )
+
+        f.close()
+        src.close()
+
+    @staticmethod
+    def unpack_archive( archive_path ):
+        utils.log( 'Unpacking archive ("%s")...' % archive_path )
+
+        archive_name = os.path.basename( archive_path )
+        extension = archive_name[ archive_name.find( '.' ) : ]
+
+        if extension in ( ".tar.gz", ".tar.bz2" ):
+            import tarfile
+            import stat
+
+            mode = os.path.splitext( extension )[1][1:]
+            tar = tarfile.open( archive_path, 'r:%s' % mode )
+            for tarinfo in tar:
+                tar.extract( tarinfo )
+                if sys.platform == 'win32' and not tarinfo.isdir():
+                    # workaround what appears to be a Win32-specific bug in 'tarfile'
+                    # (modification times for extracted files are not set properly)
+                    f = os.path.join( os.curdir, tarinfo.name )
+                    os.chmod( f, stat.S_IWRITE )
+                    os.utime( f, ( tarinfo.mtime, tarinfo.mtime ) )
+            tar.close()
+        elif extension in ( ".zip" ):
+            import zipfile
+
+            z = zipfile.ZipFile( archive_path, 'r', zipfile.ZIP_DEFLATED )
+            for f in z.infolist():
+                destination_file_path = os.path.join( os.curdir, f.filename )
+                if destination_file_path[-1] == "/": # directory
+                    if not os.path.exists( destination_file_path  ):
+                        os.makedirs( destination_file_path  )
+                else: # file
+                    result = open( destination_file_path, 'wb' )
+                    result.write( z.read( f.filename ) )
+                    result.close()
+            z.close()
+        else:
+            raise 'Do not know how to unpack archives with extension \"%s\"' % extension
+    
+    @staticmethod
+    def make_file(filename, *text):
+        text = string.join( text, '\n' )
+        with codecs.open( filename, 'w', 'utf-8' ) as f:
+            f.write( text )
+    
+    @staticmethod
+    def append_file(filename, *text):
+        with codecs.open( filename, 'a', 'utf-8' ) as f:
+            f.write( string.join( text, '\n' ) )
+    
+    @staticmethod
+    def mem_info():
+        if sys.platform == "darwin":
+            utils.call("top","-l","1","-s","0","-n","0")
+        elif sys.platform.startswith("linux"):
+            utils.call("free","-m","-l")
+    
+    @staticmethod
+    def query_boost_version(boost_root):
+        '''
+        Read in the Boost version from a given boost_root.
+        '''
+        boost_version = None
+        if os.path.exists(os.path.join(boost_root,'Jamroot')):
+            with codecs.open(os.path.join(boost_root,'Jamroot'), 'r', 'utf-8') as f:
+                for line in f.readlines():
+                    parts = line.split()
+                    if len(parts) >= 5 and parts[1] == 'BOOST_VERSION':
+                        boost_version = parts[3]
+                        break
+        if not boost_version:
+            boost_version = 'default'
+        return boost_version
+    
+    @staticmethod
+    def git_clone(sub_repo, branch, commit = None, cwd = None, no_submodules = False):
+        '''
+        This clone mimicks the way Travis-CI clones a project's repo. So far
+        Travis-CI is the most limiting in the sense of only fetching partial
+        history of the repo.
+        '''
+        if not cwd:
+            cwd = cwd = os.getcwd()
+        root_dir = os.path.join(cwd,'boostorg',sub_repo)
+        if not os.path.exists(os.path.join(root_dir,'.git')):
+            utils.check_call("git","clone",
+                "--depth=1",
+                "--branch=%s"%(branch),
+                "https://github.com/boostorg/%s.git"%(sub_repo),
+                root_dir)
+            os.chdir(root_dir)
+        else:
+            os.chdir(root_dir)
+            utils.check_call("git","pull",
+                # "--depth=1", # Can't do depth as we get merge errors.
+                "--quiet","--no-recurse-submodules")
+        if commit:
+            utils.check_call("git","checkout","-qf",commit)
+        if os.path.exists(os.path.join('.git','modules')):
+            if sys.platform == 'win32':
+                utils.check_call('dir',os.path.join('.git','modules'))
+            else:
+                utils.check_call('ls','-la',os.path.join('.git','modules'))
+        if not no_submodules:
+            utils.check_call("git","submodule","--quiet","update",
+                "--quiet","--init","--recursive",
+                )
+            utils.check_call("git","submodule","--quiet","foreach","git","fetch")
+        return root_dir
+
+class parallel_call(threading.Thread):
+    '''
+    Runs a synchronous command in a thread waiting for it to complete.
+    '''
+    
+    def __init__(self, *command, **kargs):
+        super(parallel_call,self).__init__()
+        self.command = command
+        self.command_kargs = kargs
+        self.start()
+    
+    def run(self):
+        self.result = utils.call(*self.command, **self.command_kargs)
+    
+    def join(self):
+        super(parallel_call,self).join()
+        if self.result != 0:
+            raise(SystemCallError(self.command, self.result))
+
+def set_arg(args, k, v = None):
+    if not args.get(k):
+        args[k] = v
+    return args[k]
+
+class script_common(object):
+    '''
+    Main script to run Boost C++ Libraries continuous integration.
+    '''
+
+    def __init__(self, ci_klass, **kargs):
+        self.ci = ci_klass(self)
+
+        opt = optparse.OptionParser(
+            usage="%prog [options] [commands]")
+
+        #~ Debug Options:
+        opt.add_option( '--debug-level',
+            help="debugging level; controls the amount of debugging output printed",
+            type='int' )
+        opt.add_option( '-j',
+            help="maximum number of parallel jobs to use for building with b2",
+            type='int', dest='jobs')
+        opt.add_option('--branch')
+        opt.add_option('--commit')
+        kargs = self.init(opt,kargs)
+        kargs = self.ci.init(opt, kargs)
+        set_arg(kargs,'debug_level',0)
+        set_arg(kargs,'jobs',2)
+        set_arg(kargs,'branch',None)
+        set_arg(kargs,'commit',None)
+        set_arg(kargs,'repo',None)
+        set_arg(kargs,'root_dir',None)
+        set_arg(kargs,'actions',None)
+        set_arg(kargs,'pull_request', None)
+
+        #~ Defaults
+        for (k,v) in kargs.iteritems():
+            setattr(self,k,v)
+        ( _opt_, self.actions ) = opt.parse_args(None,self)
+        if not self.actions or self.actions == []:
+            self.actions = kargs.get('actions',None)
+        if not self.actions or self.actions == []:
+            self.actions = [ 'info' ]
+        if not self.root_dir:
+            self.root_dir = os.getcwd()
+        self.build_dir = os.path.join(os.path.dirname(self.root_dir), "build")
+        
+        # API keys.
+        self.bintray_key = os.getenv('BINTRAY_KEY')
+
+        try:
+            self.start()
+            self.command_info()
+            self.main()
+            utils.print_call_stats()
+        except:
+            utils.print_call_stats()
+            raise
+    
+    def init(self, opt, kargs):
+        return kargs
+    
+    def start(self):
+        pass
+
+    def main(self):
+        for action in self.actions:
+            action_m = "command_"+action.replace('-','_')
+            ci_command = getattr(self.ci, action_m, None)
+            ci_script = getattr(self, action_m, None)
+            if ci_command or ci_script:
+                utils.log( "### %s.."%(action) )
+                if os.path.exists(self.root_dir):
+                    os.chdir(self.root_dir)
+                if ci_command:
+                    ci_command()
+                elif ci_script:
+                    ci_script()
+        
+    def b2( self, *args, **kargs ):
+        cmd = ['b2','--debug-configuration', '-j%s'%(self.jobs)]
+        cmd.extend(args)
+
+        if 'toolset' in kargs:
+            cmd.append('toolset=' + kargs['toolset'])
+
+        if 'parallel' in kargs:
+            return parallel_call(*cmd)
+        else:
+            return utils.check_call(*cmd)
+
+    # Common test commands in the order they should be executed..
+    
+    def command_info(self):
+        pass
+    
+    def command_install(self):
+        utils.makedirs(self.build_dir)
+        os.chdir(self.build_dir)
+    
+    def command_install_toolset(self, toolset):
+        if self.ci and hasattr(self.ci,'install_toolset'):
+            self.ci.install_toolset(toolset)
+    
+    def command_before_build(self):
+        pass
+
+    def command_build(self):
+        pass
+
+    def command_before_cache(self):
+        pass
+
+    def command_after_success(self):
+        pass
+
+class ci_cli(object):
+    '''
+    This version of the script provides a way to do manual building. It sets up
+    additional environment and adds fetching of the git repos that would
+    normally be done by the CI system.
+    
+    The common way to use this variant is to invoke something like:
+    
+        mkdir boost-ci
+        cd boost-ci
+        python path-to/ci_boost_<script>.py --branch=develop [--repo=mylib] ...
+    
+    Status: In working order.
+    '''
+    
+    def __init__(self,script):
+        if sys.platform == 'darwin':
+            # Requirements for running on OSX:
+            # https://www.stack.nl/~dimitri/doxygen/download.html#srcbin
+            # https://tug.org/mactex/morepackages.html
+            doxygen_path = "/Applications/Doxygen.app/Contents/Resources"
+            if os.path.isdir(doxygen_path):
+                os.environ["PATH"] = doxygen_path+':'+os.environ['PATH']
+        self.script = script
+        self.work_dir = os.getcwd()
+        self.exit_result = 0
+    
+    def init(self, opt, kargs):
+        kargs['actions'] = [
+            'clone',
+            'install',
+            'before_build',
+            'build',
+            'before_cache',
+            'finish'
+            ]
+        opt.add_option( '--repo',
+            help="Boost repo short name we are testing with, and hence the repo we clone.")
+        set_arg(kargs,'repo','boost')
+        return kargs
+    
+    def finish(self, result):
+        self.exit_result = result
+    
+    def command_clone(self):
+        self.script.root_dir = os.path.join(self.work_dir,'boostorg',self.script.repo)
+        self.script.build_dir = os.path.join(os.path.dirname(self.script.root_dir), "build")
+        utils.git_clone(self.script.repo, self.script.branch, self.script.commit, self.work_dir)
+    
+    def command_finish(self):
+        exit(self.exit_result)
+
+class ci_travis(object):
+    '''
+    This variant build releases in the context of the Travis-CI service.
+    '''
+    
+    def __init__(self,script):
+        self.script = script
+        self.work_dir = os.getenv("HOME")
+    
+    def init(self, opt, kargs):
+        set_arg(kargs,'root_dir', os.getenv("TRAVIS_BUILD_DIR"))
+        set_arg(kargs,'branch', os.getenv("TRAVIS_BRANCH"))
+        set_arg(kargs,'commit', os.getenv("TRAVIS_COMMIT"))
+        set_arg(kargs,'repo', os.getenv("TRAVIS_REPO_SLUG").split("/")[1])
+        set_arg(kargs,'pull_request',
+            os.getenv('TRAVIS_PULL_REQUEST') \
+                if os.getenv('TRAVIS_PULL_REQUEST') != 'false' else None)
+        return kargs
+    
+    def finish(self, result):
+        exit(result)
+    
+    def install_toolset(self, toolset):
+        '''
+        Installs specific toolset on CI system.
+        '''
+        info = toolset_info[toolset]
+        if sys.platform.startswith('linux'):
+            os.chdir(self.work_dir)
+            if 'ppa' in info:
+                for ppa in info['ppa']:
+                    utils.check_call(
+                        'sudo','add-apt-repository','--yes',ppa)
+            if 'deb' in info:
+                utils.make_file('sources.list',
+                    "deb %s"%(' '.join(info['deb'])),
+                    "deb-src %s"%(' '.join(info['deb'])))
+                utils.check_call('sudo','bash','-c','cat sources.list >> /etc/apt/sources.list')
+            if 'apt-key' in info:
+                for key in info['apt-key']:
+                    utils.check_call('wget',key,'-O','apt.key')
+                    utils.check_call('sudo','apt-key','add','apt.key')
+            utils.check_call(
+                'sudo','apt-get','update','-qq')
+            utils.check_call(
+                'sudo','apt-get','install','-qq',info['package'])
+            if 'debugpackage' in info and info['debugpackage']:
+                utils.check_call(
+                    'sudo','apt-get','install','-qq',info['debugpackage'])
+
+    # Travis-CI commands in the order they are executed. We need
+    # these to forward to our common commands, if they are different.
+    
+    def command_before_install(self):
+        pass
+    
+    def command_install(self):
+        self.script.command_install()
+
+    def command_before_script(self):
+        self.script.command_before_build()
+
+    def command_script(self):
+        self.script.command_build()
+
+    def command_before_cache(self):
+        self.script.command_before_cache()
+
+    def command_after_success(self):
+        self.script.command_after_success()
+
+    def command_after_failure(self):
+        pass
+
+    def command_before_deploy(self):
+        pass
+
+    def command_after_deploy(self):
+        pass
+
+    def command_after_script(self):
+        pass
+
+class ci_circleci(object):
+    '''
+    This variant build releases in the context of the CircleCI service.
+    '''
+    
+    def __init__(self,script):
+        self.script = script
+        self.work_dir = os.getenv("HOME")
+    
+    def init(self, opt, kargs):
+        set_arg(kargs,'root_dir', os.path.join(os.getenv("HOME"),os.getenv("CIRCLE_PROJECT_REPONAME")))
+        set_arg(kargs,'branch', os.getenv("CIRCLE_BRANCH"))
+        set_arg(kargs,'commit', os.getenv("CIRCLE_SHA1"))
+        set_arg(kargs,'repo', os.getenv("CIRCLE_PROJECT_REPONAME").split("/")[1])
+        set_arg(kargs,'pull_request', os.getenv('CIRCLE_PR_NUMBER'))
+        return kargs
+    
+    def finish(self, result):
+        exit(result)
+    
+    def command_machine_post(self):
+        # Apt update for the pckages installs we'll do later.
+        utils.check_call('sudo','apt-get','-qq','update')
+        # Need PyYAML to read Travis yaml in a later step.
+        utils.check_call("pip","install","--user","PyYAML")
+    
+    def command_checkout_post(self):
+        os.chdir(self.script.root_dir)
+        utils.check_call("git","submodule","update","--quiet","--init","--recursive")
+    
+    def command_dependencies_pre(self):
+        # Read in .travis.yml for list of packages to install
+        # as CircleCI doesn't have a convenient apt install method.
+        import yaml
+        utils.check_call('sudo','-E','apt-get','-yqq','update')
+        utils.check_call('sudo','apt-get','-yqq','purge','texlive*')
+        with open(os.path.join(self.script.root_dir,'.travis.yml')) as yml:
+            travis_yml = yaml.load(yml)
+            utils.check_call('sudo','apt-get','-yqq',
+                '--no-install-suggests','--no-install-recommends','--force-yes','install',
+                *travis_yml['addons']['apt']['packages'])
+    
+    def command_dependencies_override(self):
+        self.script.command_install()
+    
+    def command_dependencies_post(self):
+        pass
+    
+    def command_database_pre(self):
+        pass
+    
+    def command_database_override(self):
+        pass
+    
+    def command_database_post(self):
+        pass
+    
+    def command_test_pre(self):
+        self.script.command_install()
+        self.script.command_before_build()
+    
+    def command_test_override(self):
+        # CircleCI runs all the test subsets. So in order to avoid
+        # running the after_success we do it here as the build step
+        # will halt accordingly.
+        self.script.command_build()
+        self.script.command_before_cache()
+        self.script.command_after_success()
+    
+    def command_test_post(self):
+        pass
+
+class ci_appveyor(object):
+    
+    def __init__(self,script):
+        self.script = script
+        self.work_dir = os.path.dirname(os.getenv("APPVEYOR_BUILD_FOLDER"))
+    
+    def init(self, opt, kargs):
+        set_arg(kargs,'root_dir',os.getenv("APPVEYOR_BUILD_FOLDER"))
+        set_arg(kargs,'branch',os.getenv("APPVEYOR_REPO_BRANCH"))
+        set_arg(kargs,'commit',os.getenv("APPVEYOR_REPO_COMMIT"))
+        set_arg(kargs,'repo',os.getenv("APPVEYOR_REPO_NAME").split("/")[1])
+        set_arg(kargs,'address_model',os.getenv("PLATFORM",None))
+        set_arg(kargs,'variant',os.getenv("CONFIGURATION","debug"))
+        set_arg(kargs,'pull_request', os.getenv('APPVEYOR_PULL_REQUEST_NUMBER'))
+        return kargs
+    
+    def finish(self, result):
+        exit(result)
+    
+    # Appveyor commands in the order they are executed. We need
+    # these to forward to our common commands, if they are different.
+    
+    def command_install(self):
+        self.script.command_install()
+    
+    def command_before_build(self):
+        os.chdir(self.script.root_dir)
+        utils.check_call("git","submodule","update","--quiet","--init","--recursive")
+        self.script.command_before_build()
+    
+    def command_build_script(self):
+        self.script.command_build()
+    
+    def command_after_build(self):
+        self.script.command_before_cache()
+    
+    def command_before_test(self):
+        pass
+    
+    def command_test_script(self):
+        pass
+    
+    def command_after_test(self):
+        pass
+    
+    def command_on_success(self):
+        self.script.command_after_success()
+    
+    def command_on_failure(self):
+        pass
+    
+    def command_on_finish(self):
+        pass
+
+def main(script_klass):
+    if os.getenv('TRAVIS', False):
+        script_klass(ci_travis)
+    elif os.getenv('CIRCLECI', False):
+        script_klass(ci_circleci)
+    elif os.getenv('APPVEYOR', False):
+        script_klass(ci_appveyor)
+    else:
+        script_klass(ci_cli)
