diff --git a/import-layers/yocto-poky/bitbake/bin/bitbake b/import-layers/yocto-poky/bitbake/bin/bitbake
index b03683e..2a4fc72 100755
--- a/import-layers/yocto-poky/bitbake/bin/bitbake
+++ b/import-layers/yocto-poky/bitbake/bin/bitbake
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # ex:ts=4:sw=4:sts=4:et
 # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
 #
@@ -35,7 +35,10 @@
 from bb import cookerdata
 from bb.main import bitbake_main, BitBakeConfigParameters, BBMainException
 
-__version__ = "1.30.0"
+if sys.getfilesystemencoding() != "utf-8":
+    sys.exit("Please use a locale setting which supports utf-8.\nPython can't change the filesystem locale after loading so we need a utf-8 when python starts or things won't work.")
+
+__version__ = "1.32.0"
 
 if __name__ == "__main__":
     if __version__ != bb.__version__:
diff --git a/import-layers/yocto-poky/bitbake/bin/bitbake-diffsigs b/import-layers/yocto-poky/bitbake/bin/bitbake-diffsigs
index 196f0b7..527d2c7 100755
--- a/import-layers/yocto-poky/bitbake/bin/bitbake-diffsigs
+++ b/import-layers/yocto-poky/bitbake/bin/bitbake-diffsigs
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 # bitbake-diffsigs
 # BitBake task signature data comparison utility
@@ -24,6 +24,7 @@
 import fnmatch
 import optparse
 import logging
+import pickle
 
 sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib'))
 
@@ -95,7 +96,7 @@
         # Recurse into signature comparison
         output = bb.siggen.compare_sigfiles(latestfiles[0], latestfiles[1], recursecb)
         if output:
-            print '\n'.join(output)
+            print('\n'.join(output))
     sys.exit(0)
 
 
@@ -114,14 +115,13 @@
 options, args = parser.parse_args(sys.argv)
 
 if options.taskargs:
-    tinfoil = bb.tinfoil.Tinfoil()
-    tinfoil.prepare(config_only = True)
-    find_compare_task(tinfoil, options.taskargs[0], options.taskargs[1])
+    with bb.tinfoil.Tinfoil() as tinfoil:
+        tinfoil.prepare(config_only=True)
+        find_compare_task(tinfoil, options.taskargs[0], options.taskargs[1])
 else:
     if len(args) == 1:
         parser.print_help()
     else:
-        import cPickle
         try:
             if len(args) == 2:
                 output = bb.siggen.dump_sigfile(sys.argv[1])
@@ -130,9 +130,9 @@
         except IOError as e:
             logger.error(str(e))
             sys.exit(1)
-        except cPickle.UnpicklingError, EOFError:
+        except (pickle.UnpicklingError, EOFError):
             logger.error('Invalid signature data - ensure you are specifying sigdata/siginfo files')
             sys.exit(1)
 
         if output:
-            print '\n'.join(output)
+            print('\n'.join(output))
diff --git a/import-layers/yocto-poky/bitbake/bin/bitbake-dumpsig b/import-layers/yocto-poky/bitbake/bin/bitbake-dumpsig
index 656d93a..58ba1ca 100755
--- a/import-layers/yocto-poky/bitbake/bin/bitbake-dumpsig
+++ b/import-layers/yocto-poky/bitbake/bin/bitbake-dumpsig
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 # bitbake-dumpsig
 # BitBake task signature dump utility
@@ -23,6 +23,7 @@
 import warnings
 import optparse
 import logging
+import pickle
 
 sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib'))
 
@@ -51,15 +52,14 @@
 if len(args) == 1:
     parser.print_help()
 else:
-    import cPickle
     try:
         output = bb.siggen.dump_sigfile(args[1])
     except IOError as e:
         logger.error(str(e))
         sys.exit(1)
-    except cPickle.UnpicklingError, EOFError:
+    except (pickle.UnpicklingError, EOFError):
         logger.error('Invalid signature data - ensure you are specifying a sigdata/siginfo file')
         sys.exit(1)
 
     if output:
-        print '\n'.join(output)
+        print('\n'.join(output))
diff --git a/import-layers/yocto-poky/bitbake/bin/bitbake-layers b/import-layers/yocto-poky/bitbake/bin/bitbake-layers
index d47a669..946def2 100755
--- a/import-layers/yocto-poky/bitbake/bin/bitbake-layers
+++ b/import-layers/yocto-poky/bitbake/bin/bitbake-layers
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 # This script has subcommands which operate against your bitbake layers, either
 # displaying useful information, or acting against them.
@@ -23,1048 +23,105 @@
 import logging
 import os
 import sys
-import fnmatch
-from collections import defaultdict
 import argparse
-import re
-import httplib, urlparse, json
-import subprocess
 
 bindir = os.path.dirname(__file__)
 topdir = os.path.dirname(bindir)
 sys.path[0:0] = [os.path.join(topdir, 'lib')]
 
-import bb.cache
-import bb.cooker
-import bb.providers
-import bb.utils
 import bb.tinfoil
 
 
+def tinfoil_init(parserecipes):
+    import bb.tinfoil
+    tinfoil = bb.tinfoil.Tinfoil(tracking=True)
+    tinfoil.prepare(not parserecipes)
+    tinfoil.logger.setLevel(logger.getEffectiveLevel())
+    return tinfoil
+
+
 def logger_create(name, output=sys.stderr):
     logger = logging.getLogger(name)
-    console = logging.StreamHandler(output)
-    format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s")
-    if output.isatty():
-        format.enable_color()
-    console.setFormatter(format)
-    logger.addHandler(console)
+    loggerhandler = logging.StreamHandler(output)
+    loggerhandler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
+    logger.addHandler(loggerhandler)
     logger.setLevel(logging.INFO)
     return logger
 
+def logger_setup_color(logger, color='auto'):
+    from bb.msg import BBLogFormatter
+    console = logging.StreamHandler(sys.stdout)
+    formatter = BBLogFormatter("%(levelname)s: %(message)s")
+    console.setFormatter(formatter)
+    logger.handlers = [console]
+    if color == 'always' or (color == 'auto' and console.stream.isatty()):
+        formatter.enable_color()
+
+
 logger = logger_create('bitbake-layers', sys.stdout)
 
-class UserError(Exception):
-    pass
-
-class Commands():
-    def __init__(self):
-        self.bbhandler = None
-        self.bblayers = []
-
-    def init_bbhandler(self, config_only = False):
-        if not self.bbhandler:
-            self.bbhandler = bb.tinfoil.Tinfoil(tracking=True)
-            self.bblayers = (self.bbhandler.config_data.getVar('BBLAYERS', True) or "").split()
-            self.bbhandler.prepare(config_only)
-            layerconfs = self.bbhandler.config_data.varhistory.get_variable_items_files('BBFILE_COLLECTIONS', self.bbhandler.config_data)
-            self.bbfile_collections = {layer: os.path.dirname(os.path.dirname(path)) for layer, path in layerconfs.iteritems()}
-
-
-    def do_show_layers(self, args):
-        """show current configured layers"""
-        self.init_bbhandler(config_only = True)
-        logger.plain("%s  %s  %s" % ("layer".ljust(20), "path".ljust(40), "priority"))
-        logger.plain('=' * 74)
-        for layer, _, regex, pri in self.bbhandler.cooker.recipecache.bbfile_config_priorities:
-            layerdir = self.bbfile_collections.get(layer, None)
-            layername = self.get_layer_name(layerdir)
-            logger.plain("%s  %s  %d" % (layername.ljust(20), layerdir.ljust(40), pri))
-
-
-    def do_add_layer(self, args):
-        """Add a layer to bblayers.conf
-
-Adds the specified layer to bblayers.conf
-"""
-        layerdir = os.path.abspath(args.layerdir)
-        if not os.path.exists(layerdir):
-            sys.stderr.write("Specified layer directory doesn't exist\n")
-            return 1
-
-        layer_conf = os.path.join(layerdir, 'conf', 'layer.conf')
-        if not os.path.exists(layer_conf):
-            sys.stderr.write("Specified layer directory doesn't contain a conf/layer.conf file\n")
-            return 1
-
-        bblayers_conf = os.path.join('conf', 'bblayers.conf')
-        if not os.path.exists(bblayers_conf):
-            sys.stderr.write("Unable to find bblayers.conf\n")
-            return 1
-
-        (notadded, _) = bb.utils.edit_bblayers_conf(bblayers_conf, layerdir, None)
-        if notadded:
-            for item in notadded:
-                sys.stderr.write("Specified layer %s is already in BBLAYERS\n" % item)
-
-
-    def do_remove_layer(self, args):
-        """Remove a layer from bblayers.conf
-
-Removes the specified layer from bblayers.conf
-"""
-        bblayers_conf = os.path.join('conf', 'bblayers.conf')
-        if not os.path.exists(bblayers_conf):
-            sys.stderr.write("Unable to find bblayers.conf\n")
-            return 1
-
-        if args.layerdir.startswith('*'):
-            layerdir = args.layerdir
-        elif not '/' in args.layerdir:
-            layerdir = '*/%s' % args.layerdir
-        else:
-            layerdir = os.path.abspath(args.layerdir)
-        (_, notremoved) = bb.utils.edit_bblayers_conf(bblayers_conf, None, layerdir)
-        if notremoved:
-            for item in notremoved:
-                sys.stderr.write("No layers matching %s found in BBLAYERS\n" % item)
-            return 1
-
-
-    def get_json_data(self, apiurl):
-        proxy_settings = os.environ.get("http_proxy", None)
-        conn = None
-        _parsedurl = urlparse.urlparse(apiurl)
-        path = _parsedurl.path
-        query = _parsedurl.query
-        def parse_url(url):
-            parsedurl = urlparse.urlparse(url)
-            if parsedurl.netloc[0] == '[':
-                host, port = parsedurl.netloc[1:].split(']', 1)
-                if ':' in port:
-                    port = port.rsplit(':', 1)[1]
-                else:
-                    port = None
-            else:
-                if parsedurl.netloc.count(':') == 1:
-                    (host, port) = parsedurl.netloc.split(":")
-                else:
-                    host = parsedurl.netloc
-                    port = None
-            return (host, 80 if port is None else int(port))
-
-        if proxy_settings is None:
-            host, port = parse_url(apiurl)
-            conn = httplib.HTTPConnection(host, port)
-            conn.request("GET", path + "?" + query)
-        else:
-            host, port = parse_url(proxy_settings)
-            conn = httplib.HTTPConnection(host, port)
-            conn.request("GET", apiurl)
-
-        r = conn.getresponse()
-        if r.status != 200:
-            raise Exception("Failed to read " + path + ": %d %s" % (r.status, r.reason))
-        return json.loads(r.read())
-
-
-    def get_layer_deps(self, layername, layeritems, layerbranches, layerdependencies, branchnum, selfname=False):
-        def layeritems_info_id(items_name, layeritems):
-            litems_id = None
-            for li in layeritems:
-                if li['name'] == items_name:
-                    litems_id = li['id']
-                    break
-            return litems_id
-
-        def layerbranches_info(items_id, layerbranches):
-            lbranch = {}
-            for lb in layerbranches:
-                if lb['layer'] == items_id and lb['branch'] == branchnum:
-                    lbranch['id'] = lb['id']
-                    lbranch['vcs_subdir'] = lb['vcs_subdir']
-                    break
-            return lbranch
-
-        def layerdependencies_info(lb_id, layerdependencies):
-            ld_deps = []
-            for ld in layerdependencies:
-                if ld['layerbranch'] == lb_id and not ld['dependency'] in ld_deps:
-                    ld_deps.append(ld['dependency'])
-            if not ld_deps:
-                logger.error("The dependency of layerDependencies is not found.")
-            return ld_deps
-
-        def layeritems_info_name_subdir(items_id, layeritems):
-            litems = {}
-            for li in layeritems:
-                if li['id'] == items_id:
-                    litems['vcs_url'] = li['vcs_url']
-                    litems['name'] = li['name']
-                    break
-            return litems
-
-        if selfname:
-            selfid = layeritems_info_id(layername, layeritems)
-            lbinfo = layerbranches_info(selfid, layerbranches)
-            if lbinfo:
-                selfsubdir = lbinfo['vcs_subdir']
-            else:
-                logger.error("%s is not found in the specified branch" % layername)
-                return
-            selfurl = layeritems_info_name_subdir(selfid, layeritems)['vcs_url']
-            if selfurl:
-                return selfurl, selfsubdir
-            else:
-                logger.error("Cannot get layer %s git repo and subdir" % layername)
-                return
-        ldict = {}
-        itemsid = layeritems_info_id(layername, layeritems)
-        if not itemsid:
-            return layername, None
-        lbid = layerbranches_info(itemsid, layerbranches)
-        if lbid:
-            lbid = layerbranches_info(itemsid, layerbranches)['id']
-        else:
-            logger.error("%s is not found in the specified branch" % layername)
-            return None, None
-        for dependency in layerdependencies_info(lbid, layerdependencies):
-            lname = layeritems_info_name_subdir(dependency, layeritems)['name']
-            lurl = layeritems_info_name_subdir(dependency, layeritems)['vcs_url']
-            lsubdir = layerbranches_info(dependency, layerbranches)['vcs_subdir']
-            ldict[lname] = lurl, lsubdir
-        return None, ldict
-
-
-    def get_fetch_layer(self, fetchdir, url, subdir, fetch_layer):
-        layername = self.get_layer_name(url)
-        if os.path.splitext(layername)[1] == '.git':
-            layername = os.path.splitext(layername)[0]
-        repodir = os.path.join(fetchdir, layername)
-        layerdir = os.path.join(repodir, subdir)
-        if not os.path.exists(repodir):
-            if fetch_layer:
-                result = subprocess.call('git clone %s %s' % (url, repodir), shell = True)
-                if result:
-                    logger.error("Failed to download %s" % url)
-                    return None, None
-                else:
-                    return layername, layerdir
-            else:
-                logger.plain("Repository %s needs to be fetched" % url)
-                return layername, layerdir
-        elif os.path.exists(layerdir):
-            return layername, layerdir
-        else:
-            logger.error("%s is not in %s" % (url, subdir))
-        return None, None
-
-
-    def do_layerindex_fetch(self, args):
-        """Fetches a layer from a layer index along with its dependent layers, and adds them to conf/bblayers.conf.
-"""
-        self.init_bbhandler(config_only = True)
-        apiurl = self.bbhandler.config_data.getVar('BBLAYERS_LAYERINDEX_URL', True)
-        if not apiurl:
-            logger.error("Cannot get BBLAYERS_LAYERINDEX_URL")
-            return 1
-        else:
-            if apiurl[-1] != '/':
-                apiurl += '/'
-            apiurl += "api/"
-        apilinks = self.get_json_data(apiurl)
-        branches = self.get_json_data(apilinks['branches'])
-
-        branchnum = 0
-        for branch in branches:
-            if branch['name'] == args.branch:
-                branchnum = branch['id']
-                break
-        if branchnum == 0:
-            validbranches = ', '.join([branch['name'] for branch in branches])
-            logger.error('Invalid layer branch name "%s". Valid branches: %s' % (args.branch, validbranches))
-            return 1
-
-        ignore_layers = []
-        for collection in self.bbhandler.config_data.getVar('BBFILE_COLLECTIONS', True).split():
-            lname = self.bbhandler.config_data.getVar('BBLAYERS_LAYERINDEX_NAME_%s' % collection, True)
-            if lname:
-                ignore_layers.append(lname)
-
-        if args.ignore:
-            ignore_layers.extend(args.ignore.split(','))
-
-        layeritems = self.get_json_data(apilinks['layerItems'])
-        layerbranches = self.get_json_data(apilinks['layerBranches'])
-        layerdependencies = self.get_json_data(apilinks['layerDependencies'])
-        invaluenames = []
-        repourls = {}
-        printlayers = []
-        def query_dependencies(layers, layeritems, layerbranches, layerdependencies, branchnum):
-            depslayer = []
-            for layername in layers:
-                invaluename, layerdict = self.get_layer_deps(layername, layeritems, layerbranches, layerdependencies, branchnum)
-                if layerdict:
-                    repourls[layername] = self.get_layer_deps(layername, layeritems, layerbranches, layerdependencies, branchnum, selfname=True)
-                    for layer in layerdict:
-                        if not layer in ignore_layers:
-                            depslayer.append(layer)
-                        printlayers.append((layername, layer, layerdict[layer][0], layerdict[layer][1]))
-                        if not layer in ignore_layers and not layer in repourls:
-                            repourls[layer] = (layerdict[layer][0], layerdict[layer][1])
-                if invaluename and not invaluename in invaluenames:
-                    invaluenames.append(invaluename)
-            return depslayer
-
-        depslayers = query_dependencies(args.layername, layeritems, layerbranches, layerdependencies, branchnum)
-        while depslayers:
-            depslayer = query_dependencies(depslayers, layeritems, layerbranches, layerdependencies, branchnum)
-            depslayers = depslayer
-        if invaluenames:
-            for invaluename in invaluenames:
-                logger.error('Layer "%s" not found in layer index' % invaluename)
-            return 1
-        logger.plain("%s  %s  %s  %s" % ("Layer".ljust(19), "Required by".ljust(19), "Git repository".ljust(54), "Subdirectory"))
-        logger.plain('=' * 115)
-        for layername in args.layername:
-            layerurl = repourls[layername]
-            logger.plain("%s %s %s %s" % (layername.ljust(20), '-'.ljust(20), layerurl[0].ljust(55), layerurl[1]))
-        printedlayers = []
-        for layer, dependency, gitrepo, subdirectory in printlayers:
-            if dependency in printedlayers:
-                continue
-            logger.plain("%s %s %s %s" % (dependency.ljust(20), layer.ljust(20), gitrepo.ljust(55), subdirectory))
-            printedlayers.append(dependency)
-
-        if repourls:
-            fetchdir = self.bbhandler.config_data.getVar('BBLAYERS_FETCH_DIR', True)
-            if not fetchdir:
-                logger.error("Cannot get BBLAYERS_FETCH_DIR")
-                return 1
-            if not os.path.exists(fetchdir):
-                os.makedirs(fetchdir)
-            addlayers = []
-            for repourl, subdir in repourls.values():
-                name, layerdir = self.get_fetch_layer(fetchdir, repourl, subdir, not args.show_only)
-                if not name:
-                    # Error already shown
-                    return 1
-                addlayers.append((subdir, name, layerdir))
-        if not args.show_only:
-            for subdir, name, layerdir in set(addlayers):
-                if os.path.exists(layerdir):
-                    if subdir:
-                        logger.plain("Adding layer \"%s\" to conf/bblayers.conf" % subdir)
-                    else:
-                        logger.plain("Adding layer \"%s\" to conf/bblayers.conf" % name)
-                    localargs = argparse.Namespace()
-                    localargs.layerdir = layerdir
-                    self.do_add_layer(localargs)
-                else:
-                    break
-
-
-    def do_layerindex_show_depends(self, args):
-        """Find layer dependencies from layer index.
-"""
-        args.show_only = True
-        args.ignore = []
-        self.do_layerindex_fetch(args)
-
-
-    def version_str(self, pe, pv, pr = None):
-        verstr = "%s" % pv
-        if pr:
-            verstr = "%s-%s" % (verstr, pr)
-        if pe:
-            verstr = "%s:%s" % (pe, verstr)
-        return verstr
-
-
-    def do_show_overlayed(self, args):
-        """list overlayed recipes (where the same recipe exists in another layer)
-
-Lists the names of overlayed recipes and the available versions in each
-layer, with the preferred version first. Note that skipped recipes that
-are overlayed will also be listed, with a " (skipped)" suffix.
-"""
-        self.init_bbhandler()
-
-        items_listed = self.list_recipes('Overlayed recipes', None, True, args.same_version, args.filenames, True, None)
-
-        # Check for overlayed .bbclass files
-        classes = defaultdict(list)
-        for layerdir in self.bblayers:
-            classdir = os.path.join(layerdir, 'classes')
-            if os.path.exists(classdir):
-                for classfile in os.listdir(classdir):
-                    if os.path.splitext(classfile)[1] == '.bbclass':
-                        classes[classfile].append(classdir)
-
-        # Locating classes and other files is a bit more complicated than recipes -
-        # layer priority is not a factor; instead BitBake uses the first matching
-        # file in BBPATH, which is manipulated directly by each layer's
-        # conf/layer.conf in turn, thus the order of layers in bblayers.conf is a
-        # factor - however, each layer.conf is free to either prepend or append to
-        # BBPATH (or indeed do crazy stuff with it). Thus the order in BBPATH might
-        # not be exactly the order present in bblayers.conf either.
-        bbpath = str(self.bbhandler.config_data.getVar('BBPATH', True))
-        overlayed_class_found = False
-        for (classfile, classdirs) in classes.items():
-            if len(classdirs) > 1:
-                if not overlayed_class_found:
-                    logger.plain('=== Overlayed classes ===')
-                    overlayed_class_found = True
-
-                mainfile = bb.utils.which(bbpath, os.path.join('classes', classfile))
-                if args.filenames:
-                    logger.plain('%s' % mainfile)
-                else:
-                    # We effectively have to guess the layer here
-                    logger.plain('%s:' % classfile)
-                    mainlayername = '?'
-                    for layerdir in self.bblayers:
-                        classdir = os.path.join(layerdir, 'classes')
-                        if mainfile.startswith(classdir):
-                            mainlayername = self.get_layer_name(layerdir)
-                    logger.plain('  %s' % mainlayername)
-                for classdir in classdirs:
-                    fullpath = os.path.join(classdir, classfile)
-                    if fullpath != mainfile:
-                        if args.filenames:
-                            print('  %s' % fullpath)
-                        else:
-                            print('  %s' % self.get_layer_name(os.path.dirname(classdir)))
-
-        if overlayed_class_found:
-            items_listed = True;
-
-        if not items_listed:
-            logger.plain('No overlayed files found.')
-
-
-    def do_show_recipes(self, args):
-        """list available recipes, showing the layer they are provided by
-
-Lists the names of recipes and the available versions in each
-layer, with the preferred version first. Optionally you may specify
-pnspec to match a specified recipe name (supports wildcards). Note that
-skipped recipes will also be listed, with a " (skipped)" suffix.
-"""
-        self.init_bbhandler()
-
-        inheritlist = args.inherits.split(',') if args.inherits else []
-        if inheritlist or args.pnspec or args.multiple:
-            title = 'Matching recipes:'
-        else:
-            title = 'Available recipes:'
-        self.list_recipes(title, args.pnspec, False, False, args.filenames, args.multiple, inheritlist)
-
-
-    def list_recipes(self, title, pnspec, show_overlayed_only, show_same_ver_only, show_filenames, show_multi_provider_only, inherits):
-        if inherits:
-            bbpath = str(self.bbhandler.config_data.getVar('BBPATH', True))
-            for classname in inherits:
-                classfile = 'classes/%s.bbclass' % classname
-                if not bb.utils.which(bbpath, classfile, history=False):
-                    raise UserError('No class named %s found in BBPATH' % classfile)
-
-        pkg_pn = self.bbhandler.cooker.recipecache.pkg_pn
-        (latest_versions, preferred_versions) = bb.providers.findProviders(self.bbhandler.config_data, self.bbhandler.cooker.recipecache, pkg_pn)
-        allproviders = bb.providers.allProviders(self.bbhandler.cooker.recipecache)
-
-        # Ensure we list skipped recipes
-        # We are largely guessing about PN, PV and the preferred version here,
-        # but we have no choice since skipped recipes are not fully parsed
-        skiplist = self.bbhandler.cooker.skiplist.keys()
-        skiplist.sort( key=lambda fileitem: self.bbhandler.cooker.collection.calc_bbfile_priority(fileitem) )
-        skiplist.reverse()
-        for fn in skiplist:
-            recipe_parts = os.path.splitext(os.path.basename(fn))[0].split('_')
-            p = recipe_parts[0]
-            if len(recipe_parts) > 1:
-                ver = (None, recipe_parts[1], None)
-            else:
-                ver = (None, 'unknown', None)
-            allproviders[p].append((ver, fn))
-            if not p in pkg_pn:
-                pkg_pn[p] = 'dummy'
-                preferred_versions[p] = (ver, fn)
-
-        def print_item(f, pn, ver, layer, ispref):
-            if f in skiplist:
-                skipped = ' (skipped)'
-            else:
-                skipped = ''
-            if show_filenames:
-                if ispref:
-                    logger.plain("%s%s", f, skipped)
-                else:
-                    logger.plain("  %s%s", f, skipped)
-            else:
-                if ispref:
-                    logger.plain("%s:", pn)
-                logger.plain("  %s %s%s", layer.ljust(20), ver, skipped)
-
-        global_inherit = (self.bbhandler.config_data.getVar('INHERIT', True) or "").split()
-        cls_re = re.compile('classes/')
-
-        preffiles = []
-        items_listed = False
-        for p in sorted(pkg_pn):
-            if pnspec:
-                if not fnmatch.fnmatch(p, pnspec):
-                    continue
-
-            if len(allproviders[p]) > 1 or not show_multi_provider_only:
-                pref = preferred_versions[p]
-                realfn = bb.cache.Cache.virtualfn2realfn(pref[1])
-                preffile = realfn[0]
-
-                # We only display once per recipe, we should prefer non extended versions of the
-                # recipe if present (so e.g. in OpenEmbedded, openssl rather than nativesdk-openssl
-                # which would otherwise sort first).
-                if realfn[1] and realfn[0] in self.bbhandler.cooker.recipecache.pkg_fn:
-                    continue
-
-                if inherits:
-                    matchcount = 0
-                    recipe_inherits = self.bbhandler.cooker_data.inherits.get(preffile, [])
-                    for cls in recipe_inherits:
-                        if cls_re.match(cls):
-                            continue
-                        classname = os.path.splitext(os.path.basename(cls))[0]
-                        if classname in global_inherit:
-                            continue
-                        elif classname in inherits:
-                            matchcount += 1
-                    if matchcount != len(inherits):
-                        # No match - skip this recipe
-                        continue
-
-                if preffile not in preffiles:
-                    preflayer = self.get_file_layer(preffile)
-                    multilayer = False
-                    same_ver = True
-                    provs = []
-                    for prov in allproviders[p]:
-                        provfile = bb.cache.Cache.virtualfn2realfn(prov[1])[0]
-                        provlayer = self.get_file_layer(provfile)
-                        provs.append((provfile, provlayer, prov[0]))
-                        if provlayer != preflayer:
-                            multilayer = True
-                        if prov[0] != pref[0]:
-                            same_ver = False
-
-                    if (multilayer or not show_overlayed_only) and (same_ver or not show_same_ver_only):
-                        if not items_listed:
-                            logger.plain('=== %s ===' % title)
-                            items_listed = True
-                        print_item(preffile, p, self.version_str(pref[0][0], pref[0][1]), preflayer, True)
-                        for (provfile, provlayer, provver) in provs:
-                            if provfile != preffile:
-                                print_item(provfile, p, self.version_str(provver[0], provver[1]), provlayer, False)
-                        # Ensure we don't show two entries for BBCLASSEXTENDed recipes
-                        preffiles.append(preffile)
-
-        return items_listed
-
-
-    def do_flatten(self, args):
-        """flatten layer configuration into a separate output directory.
-
-Takes the specified layers (or all layers in the current layer
-configuration if none are specified) and builds a "flattened" directory
-containing the contents of all layers, with any overlayed recipes removed
-and bbappends appended to the corresponding recipes. Note that some manual
-cleanup may still be necessary afterwards, in particular:
-
-* where non-recipe files (such as patches) are overwritten (the flatten
-  command will show a warning for these)
-* where anything beyond the normal layer setup has been added to
-  layer.conf (only the lowest priority number layer's layer.conf is used)
-* overridden/appended items from bbappends will need to be tidied up
-* when the flattened layers do not have the same directory structure (the
-  flatten command should show a warning when this will cause a problem)
-
-Warning: if you flatten several layers where another layer is intended to
-be used "inbetween" them (in layer priority order) such that recipes /
-bbappends in the layers interact, and then attempt to use the new output
-layer together with that other layer, you may no longer get the same
-build results (as the layer priority order has effectively changed).
-"""
-        if len(args.layer) == 1:
-            logger.error('If you specify layers to flatten you must specify at least two')
-            return 1
-
-        outputdir = args.outputdir
-        if os.path.exists(outputdir) and os.listdir(outputdir):
-            logger.error('Directory %s exists and is non-empty, please clear it out first' % outputdir)
-            return 1
-
-        self.init_bbhandler()
-        layers = self.bblayers
-        if len(args.layer) > 2:
-            layernames = args.layer
-            found_layernames = []
-            found_layerdirs = []
-            for layerdir in layers:
-                layername = self.get_layer_name(layerdir)
-                if layername in layernames:
-                    found_layerdirs.append(layerdir)
-                    found_layernames.append(layername)
-
-            for layername in layernames:
-                if not layername in found_layernames:
-                    logger.error('Unable to find layer %s in current configuration, please run "%s show-layers" to list configured layers' % (layername, os.path.basename(sys.argv[0])))
-                    return
-            layers = found_layerdirs
-        else:
-            layernames = []
-
-        # Ensure a specified path matches our list of layers
-        def layer_path_match(path):
-            for layerdir in layers:
-                if path.startswith(os.path.join(layerdir, '')):
-                    return layerdir
-            return None
-
-        applied_appends = []
-        for layer in layers:
-            overlayed = []
-            for f in self.bbhandler.cooker.collection.overlayed.iterkeys():
-                for of in self.bbhandler.cooker.collection.overlayed[f]:
-                    if of.startswith(layer):
-                        overlayed.append(of)
-
-            logger.plain('Copying files from %s...' % layer )
-            for root, dirs, files in os.walk(layer):
-                for f1 in files:
-                    f1full = os.sep.join([root, f1])
-                    if f1full in overlayed:
-                        logger.plain('  Skipping overlayed file %s' % f1full )
-                    else:
-                        ext = os.path.splitext(f1)[1]
-                        if ext != '.bbappend':
-                            fdest = f1full[len(layer):]
-                            fdest = os.path.normpath(os.sep.join([outputdir,fdest]))
-                            bb.utils.mkdirhier(os.path.dirname(fdest))
-                            if os.path.exists(fdest):
-                                if f1 == 'layer.conf' and root.endswith('/conf'):
-                                    logger.plain('  Skipping layer config file %s' % f1full )
-                                    continue
-                                else:
-                                    logger.warn('Overwriting file %s', fdest)
-                            bb.utils.copyfile(f1full, fdest)
-                            if ext == '.bb':
-                                for append in self.bbhandler.cooker.collection.get_file_appends(f1full):
-                                    if layer_path_match(append):
-                                        logger.plain('  Applying append %s to %s' % (append, fdest))
-                                        self.apply_append(append, fdest)
-                                        applied_appends.append(append)
-
-        # Take care of when some layers are excluded and yet we have included bbappends for those recipes
-        for b in self.bbhandler.cooker.collection.bbappends:
-            (recipename, appendname) = b
-            if appendname not in applied_appends:
-                first_append = None
-                layer = layer_path_match(appendname)
-                if layer:
-                    if first_append:
-                        self.apply_append(appendname, first_append)
-                    else:
-                        fdest = appendname[len(layer):]
-                        fdest = os.path.normpath(os.sep.join([outputdir,fdest]))
-                        bb.utils.mkdirhier(os.path.dirname(fdest))
-                        bb.utils.copyfile(appendname, fdest)
-                        first_append = fdest
-
-        # Get the regex for the first layer in our list (which is where the conf/layer.conf file will
-        # have come from)
-        first_regex = None
-        layerdir = layers[0]
-        for layername, pattern, regex, _ in self.bbhandler.cooker.recipecache.bbfile_config_priorities:
-            if regex.match(os.path.join(layerdir, 'test')):
-                first_regex = regex
-                break
-
-        if first_regex:
-            # Find the BBFILES entries that match (which will have come from this conf/layer.conf file)
-            bbfiles = str(self.bbhandler.config_data.getVar('BBFILES', True)).split()
-            bbfiles_layer = []
-            for item in bbfiles:
-                if first_regex.match(item):
-                    newpath = os.path.join(outputdir, item[len(layerdir)+1:])
-                    bbfiles_layer.append(newpath)
-
-            if bbfiles_layer:
-                # Check that all important layer files match BBFILES
-                for root, dirs, files in os.walk(outputdir):
-                    for f1 in files:
-                        ext = os.path.splitext(f1)[1]
-                        if ext in ['.bb', '.bbappend']:
-                            f1full = os.sep.join([root, f1])
-                            entry_found = False
-                            for item in bbfiles_layer:
-                                if fnmatch.fnmatch(f1full, item):
-                                    entry_found = True
-                                    break
-                            if not entry_found:
-                                logger.warning("File %s does not match the flattened layer's BBFILES setting, you may need to edit conf/layer.conf or move the file elsewhere" % f1full)
-
-    def get_file_layer(self, filename):
-        layerdir = self.get_file_layerdir(filename)
-        if layerdir:
-            return self.get_layer_name(layerdir)
-        else:
-            return '?'
-
-    def get_file_layerdir(self, filename):
-        layer = bb.utils.get_file_layer(filename, self.bbhandler.config_data)
-        return self.bbfile_collections.get(layer, None)
-
-    def remove_layer_prefix(self, f):
-        """Remove the layer_dir prefix, e.g., f = /path/to/layer_dir/foo/blah, the
-           return value will be: layer_dir/foo/blah"""
-        f_layerdir = self.get_file_layerdir(f)
-        if not f_layerdir:
-            return f
-        prefix = os.path.join(os.path.dirname(f_layerdir), '')
-        return f[len(prefix):] if f.startswith(prefix) else f
-
-    def get_layer_name(self, layerdir):
-        return os.path.basename(layerdir.rstrip(os.sep))
-
-    def apply_append(self, appendname, recipename):
-        with open(appendname, 'r') as appendfile:
-            with open(recipename, 'a') as recipefile:
-                recipefile.write('\n')
-                recipefile.write('##### bbappended from %s #####\n' % self.get_file_layer(appendname))
-                recipefile.writelines(appendfile.readlines())
-
-    def do_show_appends(self, args):
-        """list bbappend files and recipe files they apply to
-
-Lists recipes with the bbappends that apply to them as subitems.
-"""
-        self.init_bbhandler()
-
-        logger.plain('=== Appended recipes ===')
-
-        pnlist = list(self.bbhandler.cooker_data.pkg_pn.keys())
-        pnlist.sort()
-        appends = False
-        for pn in pnlist:
-            if self.show_appends_for_pn(pn):
-                appends = True
-
-        if self.show_appends_for_skipped():
-            appends = True
-
-        if not appends:
-            logger.plain('No append files found')
-
-    def show_appends_for_pn(self, pn):
-        filenames = self.bbhandler.cooker_data.pkg_pn[pn]
-
-        best = bb.providers.findBestProvider(pn,
-                                             self.bbhandler.config_data,
-                                             self.bbhandler.cooker_data,
-                                             self.bbhandler.cooker_data.pkg_pn)
-        best_filename = os.path.basename(best[3])
-
-        return self.show_appends_output(filenames, best_filename)
-
-    def show_appends_for_skipped(self):
-        filenames = [os.path.basename(f)
-                    for f in self.bbhandler.cooker.skiplist.iterkeys()]
-        return self.show_appends_output(filenames, None, " (skipped)")
-
-    def show_appends_output(self, filenames, best_filename, name_suffix = ''):
-        appended, missing = self.get_appends_for_files(filenames)
-        if appended:
-            for basename, appends in appended:
-                logger.plain('%s%s:', basename, name_suffix)
-                for append in appends:
-                    logger.plain('  %s', append)
-
-            if best_filename:
-                if best_filename in missing:
-                    logger.warn('%s: missing append for preferred version',
-                                best_filename)
-            return True
-        else:
-            return False
-
-    def get_appends_for_files(self, filenames):
-        appended, notappended = [], []
-        for filename in filenames:
-            _, cls = bb.cache.Cache.virtualfn2realfn(filename)
-            if cls:
-                continue
-
-            basename = os.path.basename(filename)
-            appends = self.bbhandler.cooker.collection.get_file_appends(basename)
-            if appends:
-                appended.append((basename, list(appends)))
-            else:
-                notappended.append(basename)
-        return appended, notappended
-
-    def do_show_cross_depends(self, args):
-        """Show dependencies between recipes that cross layer boundaries.
-
-Figure out the dependencies between recipes that cross layer boundaries.
-
-NOTE: .bbappend files can impact the dependencies.
-"""
-        ignore_layers = (args.ignore or '').split(',')
-
-        self.init_bbhandler()
-
-        pkg_fn = self.bbhandler.cooker_data.pkg_fn
-        bbpath = str(self.bbhandler.config_data.getVar('BBPATH', True))
-        self.require_re = re.compile(r"require\s+(.+)")
-        self.include_re = re.compile(r"include\s+(.+)")
-        self.inherit_re = re.compile(r"inherit\s+(.+)")
-
-        global_inherit = (self.bbhandler.config_data.getVar('INHERIT', True) or "").split()
-
-        # The bb's DEPENDS and RDEPENDS
-        for f in pkg_fn:
-            f = bb.cache.Cache.virtualfn2realfn(f)[0]
-            # Get the layername that the file is in
-            layername = self.get_file_layer(f)
-
-            # The DEPENDS
-            deps = self.bbhandler.cooker_data.deps[f]
-            for pn in deps:
-                if pn in self.bbhandler.cooker_data.pkg_pn:
-                    best = bb.providers.findBestProvider(pn,
-                            self.bbhandler.config_data,
-                            self.bbhandler.cooker_data,
-                            self.bbhandler.cooker_data.pkg_pn)
-                    self.check_cross_depends("DEPENDS", layername, f, best[3], args.filenames, ignore_layers)
-
-            # The RDPENDS
-            all_rdeps = self.bbhandler.cooker_data.rundeps[f].values()
-            # Remove the duplicated or null one.
-            sorted_rdeps = {}
-            # The all_rdeps is the list in list, so we need two for loops
-            for k1 in all_rdeps:
-                for k2 in k1:
-                    sorted_rdeps[k2] = 1
-            all_rdeps = sorted_rdeps.keys()
-            for rdep in all_rdeps:
-                all_p = bb.providers.getRuntimeProviders(self.bbhandler.cooker_data, rdep)
-                if all_p:
-                    if f in all_p:
-                        # The recipe provides this one itself, ignore
-                        continue
-                    best = bb.providers.filterProvidersRunTime(all_p, rdep,
-                                    self.bbhandler.config_data,
-                                    self.bbhandler.cooker_data)[0][0]
-                    self.check_cross_depends("RDEPENDS", layername, f, best, args.filenames, ignore_layers)
-
-            # The RRECOMMENDS
-            all_rrecs = self.bbhandler.cooker_data.runrecs[f].values()
-            # Remove the duplicated or null one.
-            sorted_rrecs = {}
-            # The all_rrecs is the list in list, so we need two for loops
-            for k1 in all_rrecs:
-                for k2 in k1:
-                    sorted_rrecs[k2] = 1
-            all_rrecs = sorted_rrecs.keys()
-            for rrec in all_rrecs:
-                all_p = bb.providers.getRuntimeProviders(self.bbhandler.cooker_data, rrec)
-                if all_p:
-                    if f in all_p:
-                        # The recipe provides this one itself, ignore
-                        continue
-                    best = bb.providers.filterProvidersRunTime(all_p, rrec,
-                                    self.bbhandler.config_data,
-                                    self.bbhandler.cooker_data)[0][0]
-                    self.check_cross_depends("RRECOMMENDS", layername, f, best, args.filenames, ignore_layers)
-
-            # The inherit class
-            cls_re = re.compile('classes/')
-            if f in self.bbhandler.cooker_data.inherits:
-                inherits = self.bbhandler.cooker_data.inherits[f]
-                for cls in inherits:
-                    # The inherits' format is [classes/cls, /path/to/classes/cls]
-                    # ignore the classes/cls.
-                    if not cls_re.match(cls):
-                        classname = os.path.splitext(os.path.basename(cls))[0]
-                        if classname in global_inherit:
-                            continue
-                        inherit_layername = self.get_file_layer(cls)
-                        if inherit_layername != layername and not inherit_layername in ignore_layers:
-                            if not args.filenames:
-                                f_short = self.remove_layer_prefix(f)
-                                cls = self.remove_layer_prefix(cls)
-                            else:
-                                f_short = f
-                            logger.plain("%s inherits %s" % (f_short, cls))
-
-            # The 'require/include xxx' in the bb file
-            pv_re = re.compile(r"\${PV}")
-            with open(f, 'r') as fnfile:
-                line = fnfile.readline()
-                while line:
-                    m, keyword = self.match_require_include(line)
-                    # Found the 'require/include xxxx'
-                    if m:
-                        needed_file = m.group(1)
-                        # Replace the ${PV} with the real PV
-                        if pv_re.search(needed_file) and f in self.bbhandler.cooker_data.pkg_pepvpr:
-                            pv = self.bbhandler.cooker_data.pkg_pepvpr[f][1]
-                            needed_file = re.sub(r"\${PV}", pv, needed_file)
-                        self.print_cross_files(bbpath, keyword, layername, f, needed_file, args.filenames, ignore_layers)
-                    line = fnfile.readline()
-
-        # The "require/include xxx" in conf/machine/*.conf, .inc and .bbclass
-        conf_re = re.compile(".*/conf/machine/[^\/]*\.conf$")
-        inc_re = re.compile(".*\.inc$")
-        # The "inherit xxx" in .bbclass
-        bbclass_re = re.compile(".*\.bbclass$")
-        for layerdir in self.bblayers:
-            layername = self.get_layer_name(layerdir)
-            for dirpath, dirnames, filenames in os.walk(layerdir):
-                for name in filenames:
-                    f = os.path.join(dirpath, name)
-                    s = conf_re.match(f) or inc_re.match(f) or bbclass_re.match(f)
-                    if s:
-                        with open(f, 'r') as ffile:
-                            line = ffile.readline()
-                            while line:
-                                m, keyword = self.match_require_include(line)
-                                # Only bbclass has the "inherit xxx" here.
-                                bbclass=""
-                                if not m and f.endswith(".bbclass"):
-                                    m, keyword = self.match_inherit(line)
-                                    bbclass=".bbclass"
-                                # Find a 'require/include xxxx'
-                                if m:
-                                    self.print_cross_files(bbpath, keyword, layername, f, m.group(1) + bbclass, args.filenames, ignore_layers)
-                                line = ffile.readline()
-
-    def print_cross_files(self, bbpath, keyword, layername, f, needed_filename, show_filenames, ignore_layers):
-        """Print the depends that crosses a layer boundary"""
-        needed_file = bb.utils.which(bbpath, needed_filename)
-        if needed_file:
-            # Which layer is this file from
-            needed_layername = self.get_file_layer(needed_file)
-            if needed_layername != layername and not needed_layername in ignore_layers:
-                if not show_filenames:
-                    f = self.remove_layer_prefix(f)
-                    needed_file = self.remove_layer_prefix(needed_file)
-                logger.plain("%s %s %s" %(f, keyword, needed_file))
-
-    def match_inherit(self, line):
-        """Match the inherit xxx line"""
-        return (self.inherit_re.match(line), "inherits")
-
-    def match_require_include(self, line):
-        """Match the require/include xxx line"""
-        m = self.require_re.match(line)
-        keyword = "requires"
-        if not m:
-            m = self.include_re.match(line)
-            keyword = "includes"
-        return (m, keyword)
-
-    def check_cross_depends(self, keyword, layername, f, needed_file, show_filenames, ignore_layers):
-        """Print the DEPENDS/RDEPENDS file that crosses a layer boundary"""
-        best_realfn = bb.cache.Cache.virtualfn2realfn(needed_file)[0]
-        needed_layername = self.get_file_layer(best_realfn)
-        if needed_layername != layername and not needed_layername in ignore_layers:
-            if not show_filenames:
-                f = self.remove_layer_prefix(f)
-                best_realfn = self.remove_layer_prefix(best_realfn)
-
-            logger.plain("%s %s %s" % (f, keyword, best_realfn))
-
-
 def main():
-
-    cmds = Commands()
-
-    def add_command(cmdname, function, *args, **kwargs):
-        # Convert docstring for function to help (one-liner shown in main --help) and description (shown in subcommand --help)
-        docsplit = function.__doc__.splitlines()
-        help = docsplit[0]
-        if len(docsplit) > 1:
-            desc = '\n'.join(docsplit[1:])
-        else:
-            desc = help
-        subparser = subparsers.add_parser(cmdname, *args, help=help, description=desc, formatter_class=argparse.RawTextHelpFormatter, **kwargs)
-        subparser.set_defaults(func=function)
-        return subparser
-
-    parser = argparse.ArgumentParser(description="BitBake layers utility",
-                                     epilog="Use %(prog)s <subcommand> --help to get help on a specific command")
+    parser = argparse.ArgumentParser(
+        description="BitBake layers utility",
+        epilog="Use %(prog)s <subcommand> --help to get help on a specific command",
+        add_help=False)
     parser.add_argument('-d', '--debug', help='Enable debug output', action='store_true')
     parser.add_argument('-q', '--quiet', help='Print only errors', action='store_true')
+    parser.add_argument('--color', choices=['auto', 'always', 'never'], default='auto', help='Colorize output (where %(metavar)s is %(choices)s)', metavar='COLOR')
+
+    global_args, unparsed_args = parser.parse_known_args()
+
+    # Help is added here rather than via add_help=True, as we don't want it to
+    # be handled by parse_known_args()
+    parser.add_argument('-h', '--help', action='help', default=argparse.SUPPRESS,
+                        help='show this help message and exit')
     subparsers = parser.add_subparsers(title='subcommands', metavar='<subcommand>')
+    subparsers.required = True
 
-    parser_show_layers = add_command('show-layers', cmds.do_show_layers)
-
-    parser_add_layer = add_command('add-layer', cmds.do_add_layer)
-    parser_add_layer.add_argument('layerdir', help='Layer directory to add')
-
-    parser_remove_layer = add_command('remove-layer', cmds.do_remove_layer)
-    parser_remove_layer.add_argument('layerdir', help='Layer directory to remove (wildcards allowed, enclose in quotes to avoid shell expansion)')
-    parser_remove_layer.set_defaults(func=cmds.do_remove_layer)
-
-    parser_show_overlayed = add_command('show-overlayed', cmds.do_show_overlayed)
-    parser_show_overlayed.add_argument('-f', '--filenames', help='instead of the default formatting, list filenames of higher priority recipes with the ones they overlay indented underneath', action='store_true')
-    parser_show_overlayed.add_argument('-s', '--same-version', help='only list overlayed recipes where the version is the same', action='store_true')
-
-    parser_show_recipes = add_command('show-recipes', cmds.do_show_recipes)
-    parser_show_recipes.add_argument('-f', '--filenames', help='instead of the default formatting, list filenames of higher priority recipes with the ones they overlay indented underneath', action='store_true')
-    parser_show_recipes.add_argument('-m', '--multiple', help='only list where multiple recipes (in the same layer or different layers) exist for the same recipe name', action='store_true')
-    parser_show_recipes.add_argument('-i', '--inherits', help='only list recipes that inherit the named class', metavar='CLASS', default='')
-    parser_show_recipes.add_argument('pnspec', nargs='?', help='optional recipe name specification (wildcards allowed, enclose in quotes to avoid shell expansion)')
-
-    parser_show_appends = add_command('show-appends', cmds.do_show_appends)
-
-    parser_flatten = add_command('flatten', cmds.do_flatten)
-    parser_flatten.add_argument('layer', nargs='*', help='Optional layer(s) to flatten (otherwise all are flattened)')
-    parser_flatten.add_argument('outputdir', help='Output directory')
-
-    parser_show_cross_depends = add_command('show-cross-depends', cmds.do_show_cross_depends)
-    parser_show_cross_depends.add_argument('-f', '--filenames', help='show full file path', action='store_true')
-    parser_show_cross_depends.add_argument('-i', '--ignore', help='ignore dependencies on items in the specified layer(s) (split multiple layer names with commas, no spaces)', metavar='LAYERNAME')
-
-    parser_layerindex_fetch = add_command('layerindex-fetch', cmds.do_layerindex_fetch)
-    parser_layerindex_fetch.add_argument('-n', '--show-only', help='show dependencies and do nothing else', action='store_true')
-    parser_layerindex_fetch.add_argument('-b', '--branch', help='branch name to fetch (default %(default)s)', default='master')
-    parser_layerindex_fetch.add_argument('-i', '--ignore', help='assume the specified layers do not need to be fetched/added (separate multiple layers with commas, no spaces)', metavar='LAYER')
-    parser_layerindex_fetch.add_argument('layername', nargs='+', help='layer to fetch')
-
-    parser_layerindex_show_depends = add_command('layerindex-show-depends', cmds.do_layerindex_show_depends)
-    parser_layerindex_show_depends.add_argument('-b', '--branch', help='branch name to fetch (default %(default)s)', default='master')
-    parser_layerindex_show_depends.add_argument('layername', nargs='+', help='layer to query')
-
-    args = parser.parse_args()
-
-    if args.debug:
+    if global_args.debug:
         logger.setLevel(logging.DEBUG)
-    elif args.quiet:
+    elif global_args.quiet:
         logger.setLevel(logging.ERROR)
 
-    try:
-        ret = args.func(args)
-    except UserError as err:
-        logger.error(str(err))
-        ret = 1
+    logger_setup_color(logger, global_args.color)
 
-    return ret
+    plugins = []
+    tinfoil = tinfoil_init(False)
+    try:
+        for path in ([topdir] +
+                    tinfoil.config_data.getVar('BBPATH', True).split(':')):
+            pluginpath = os.path.join(path, 'lib', 'bblayers')
+            bb.utils.load_plugins(logger, plugins, pluginpath)
+
+        registered = False
+        for plugin in plugins:
+            if hasattr(plugin, 'register_commands'):
+                registered = True
+                plugin.register_commands(subparsers)
+            if hasattr(plugin, 'tinfoil_init'):
+                plugin.tinfoil_init(tinfoil)
+
+        if not registered:
+            logger.error("No commands registered - missing plugins?")
+            sys.exit(1)
+
+        args = parser.parse_args(unparsed_args, namespace=global_args)
+
+        if getattr(args, 'parserecipes', False):
+            tinfoil.config_data.disableTracking()
+            tinfoil.parseRecipes()
+            tinfoil.config_data.enableTracking()
+
+        return args.func(args)
+    finally:
+        tinfoil.shutdown()
 
 
 if __name__ == "__main__":
     try:
         ret = main()
+    except bb.BBHandledException:
+        ret = 1
     except Exception:
         ret = 1
         import traceback
diff --git a/import-layers/yocto-poky/bitbake/bin/bitbake-prserv b/import-layers/yocto-poky/bitbake/bin/bitbake-prserv
index 0382144..f38d2dd 100755
--- a/import-layers/yocto-poky/bitbake/bin/bitbake-prserv
+++ b/import-layers/yocto-poky/bitbake/bin/bitbake-prserv
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 import os
 import sys,logging
 import optparse
diff --git a/import-layers/yocto-poky/bitbake/bin/bitbake-selftest b/import-layers/yocto-poky/bitbake/bin/bitbake-selftest
index 462eb1b..380e003 100755
--- a/import-layers/yocto-poky/bitbake/bin/bitbake-selftest
+++ b/import-layers/yocto-poky/bitbake/bin/bitbake-selftest
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Copyright (C) 2012 Richard Purdie
 #
@@ -25,31 +25,48 @@
 except RuntimeError as exc:
     sys.exit(str(exc))
 
-def usage():
-    print('usage: [BB_SKIP_NETTESTS=yes] %s [-v] [testname1 [testname2]...]' % os.path.basename(sys.argv[0]))
-
-verbosity = 1
-
-tests = sys.argv[1:]
-if '-v' in sys.argv:
-    tests.remove('-v')
-    verbosity = 2
-
-if tests:
-    if '--help' in sys.argv[1:]:
-        usage()
-        sys.exit(0)
-else:
-    tests = ["bb.tests.codeparser",
-             "bb.tests.cow",
-             "bb.tests.data",
-             "bb.tests.fetch",
-             "bb.tests.parse",
-             "bb.tests.utils"]
+tests = ["bb.tests.codeparser",
+         "bb.tests.cow",
+         "bb.tests.data",
+         "bb.tests.fetch",
+         "bb.tests.parse",
+         "bb.tests.utils"]
 
 for t in tests:
     t = '.'.join(t.split('.')[:3])
     __import__(t)
 
-unittest.main(argv=["bitbake-selftest"] + tests, verbosity=verbosity)
 
+# Set-up logging
+class StdoutStreamHandler(logging.StreamHandler):
+    """Special handler so that unittest is able to capture stdout"""
+    def __init__(self):
+        # Override __init__() because we don't want to set self.stream here
+        logging.Handler.__init__(self)
+
+    @property
+    def stream(self):
+        # We want to dynamically write wherever sys.stdout is pointing to
+        return sys.stdout
+
+
+handler = StdoutStreamHandler()
+bb.logger.addHandler(handler)
+bb.logger.setLevel(logging.DEBUG)
+
+
+ENV_HELP = """\
+Environment variables:
+  BB_SKIP_NETTESTS      set to 'yes' in order to skip tests using network
+                        connection
+  BB_TMPDIR_NOCLEAN     set to 'yes' to preserve test tmp directories
+"""
+
+class main(unittest.main):
+    def _print_help(self, *args, **kwargs):
+        super(main, self)._print_help(*args, **kwargs)
+        print(ENV_HELP)
+
+
+if __name__ == '__main__':
+        main(defaultTest=tests, buffer=True)
diff --git a/import-layers/yocto-poky/bitbake/bin/bitbake-worker b/import-layers/yocto-poky/bitbake/bin/bitbake-worker
index 767a1c0..500f2ad 100755
--- a/import-layers/yocto-poky/bitbake/bin/bitbake-worker
+++ b/import-layers/yocto-poky/bitbake/bin/bitbake-worker
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 import os
 import sys
@@ -10,8 +10,12 @@
 import select
 import errno
 import signal
+import pickle
 from multiprocessing import Lock
 
+if sys.getfilesystemencoding() != "utf-8":
+    sys.exit("Please use a locale setting which supports utf-8.\nPython can't change the filesystem locale after loading so we need a utf-8 when python starts or things won't work.")
+
 # Users shouldn't be running this code directly
 if len(sys.argv) != 2 or not sys.argv[1].startswith("decafbad"):
     print("bitbake-worker is meant for internal execution by bitbake itself, please don't use it standalone.")
@@ -30,19 +34,16 @@
 # updates to log files for use with tail
 try:
     if sys.stdout.name == '<stdout>':
-        sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
+        import fcntl
+        fl = fcntl.fcntl(sys.stdout.fileno(), fcntl.F_GETFL)
+        fl |= os.O_SYNC 
+        fcntl.fcntl(sys.stdout.fileno(), fcntl.F_SETFL, fl)
+        #sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
 except:
     pass
 
 logger = logging.getLogger("BitBake")
 
-try:
-    import cPickle as pickle
-except ImportError:
-    import pickle
-    bb.msg.note(1, bb.msg.domain.Cache, "Importing cPickle failed. Falling back to a very slow implementation.")
-
-
 worker_pipe = sys.stdout.fileno()
 bb.utils.nonblockingfd(worker_pipe)
 # Need to guard against multiprocessing being used in child processes
@@ -62,10 +63,10 @@
     consolelog.setFormatter(conlogformat)
     logger.addHandler(consolelog)
 
-worker_queue = ""
+worker_queue = b""
 
 def worker_fire(event, d):
-    data = "<event>" + pickle.dumps(event) + "</event>"
+    data = b"<event>" + pickle.dumps(event) + b"</event>"
     worker_fire_prepickled(data)
 
 def worker_fire_prepickled(event):
@@ -91,7 +92,7 @@
     global worker_pipe
     global worker_pipe_lock
 
-    data = "<event>" + pickle.dumps(event) + "</event>"
+    data = b"<event>" + pickle.dumps(event) + b"</event>"
     try:
         worker_pipe_lock.acquire()
         worker_pipe.write(data)
@@ -114,7 +115,7 @@
     os.killpg(0, signal.SIGTERM)
     sys.exit()
 
-def fork_off_task(cfg, data, workerdata, fn, task, taskname, appends, taskdepdata, quieterrors=False):
+def fork_off_task(cfg, data, databuilder, workerdata, fn, task, taskname, appends, taskdepdata, quieterrors=False):
     # We need to setup the environment BEFORE the fork, since
     # a fork() or exec*() activates PSEUDO...
 
@@ -159,7 +160,8 @@
         pipeout = os.fdopen(pipeout, 'wb', 0)
         pid = os.fork()
     except OSError as e:
-        bb.msg.fatal("RunQueue", "fork failed: %d (%s)" % (e.errno, e.strerror))
+        logger.critical("fork failed: %d (%s)" % (e.errno, e.strerror))
+        sys.exit(1)
 
     if pid == 0:
         def child():
@@ -191,15 +193,19 @@
             if umask:
                 os.umask(umask)
 
-            data.setVar("BB_WORKERCONTEXT", "1")
-            data.setVar("BB_TASKDEPDATA", taskdepdata)
-            data.setVar("BUILDNAME", workerdata["buildname"])
-            data.setVar("DATE", workerdata["date"])
-            data.setVar("TIME", workerdata["time"])
-            bb.parse.siggen.set_taskdata(workerdata["sigdata"])
-            ret = 0
             try:
-                the_data = bb.cache.Cache.loadDataFull(fn, appends, data)
+                bb_cache = bb.cache.NoCache(databuilder)
+                (realfn, virtual, mc) = bb.cache.virtualfn2realfn(fn)
+                the_data = databuilder.mcdata[mc]
+                the_data.setVar("BB_WORKERCONTEXT", "1")
+                the_data.setVar("BB_TASKDEPDATA", taskdepdata)
+                the_data.setVar("BUILDNAME", workerdata["buildname"])
+                the_data.setVar("DATE", workerdata["date"])
+                the_data.setVar("TIME", workerdata["time"])
+                bb.parse.siggen.set_taskdata(workerdata["sigdata"])
+                ret = 0
+
+                the_data = bb_cache.loadDataFull(fn, appends)
                 the_data.setVar('BB_TASKHASH', workerdata["runq_hash"][task])
 
                 bb.utils.set_process_name("%s:%s" % (the_data.getVar("PN", True), taskname.replace("do_", "")))
@@ -207,14 +213,24 @@
                 # exported_vars() returns a generator which *cannot* be passed to os.environ.update() 
                 # successfully. We also need to unset anything from the environment which shouldn't be there 
                 exports = bb.data.exported_vars(the_data)
+
                 bb.utils.empty_environment()
                 for e, v in exports:
                     os.environ[e] = v
+
                 for e in fakeenv:
                     os.environ[e] = fakeenv[e]
                     the_data.setVar(e, fakeenv[e])
                     the_data.setVarFlag(e, 'export', "1")
 
+                task_exports = the_data.getVarFlag(taskname, 'exports', True)
+                if task_exports:
+                    for e in task_exports.split():
+                        the_data.setVarFlag(e, 'export', '1')
+                        v = the_data.getVar(e, True)
+                        if v is not None:
+                            os.environ[e] = v
+
                 if quieterrors:
                     the_data.setVarFlag(taskname, "quieterrors", "1")
 
@@ -240,7 +256,7 @@
                 bb.utils.process_profilelog(profname)
                 os._exit(ret)
     else:
-        for key, value in envbackup.iteritems():
+        for key, value in iter(envbackup.items()):
             if value is None:
                 del os.environ[key]
             else:
@@ -257,22 +273,22 @@
         if pipeout:
             pipeout.close()
         bb.utils.nonblockingfd(self.input)
-        self.queue = ""
+        self.queue = b""
 
     def read(self):
         start = len(self.queue)
         try:
-            self.queue = self.queue + self.input.read(102400)
+            self.queue = self.queue + (self.input.read(102400) or b"")
         except (OSError, IOError) as e:
             if e.errno != errno.EAGAIN:
                 raise
 
         end = len(self.queue)
-        index = self.queue.find("</event>")
+        index = self.queue.find(b"</event>")
         while index != -1:
             worker_fire_prepickled(self.queue[:index+8])
             self.queue = self.queue[index+8:]
-            index = self.queue.find("</event>")
+            index = self.queue.find(b"</event>")
         return (end > start)
 
     def close(self):
@@ -288,7 +304,7 @@
     def __init__(self, din):
         self.input = din
         bb.utils.nonblockingfd(self.input)
-        self.queue = ""
+        self.queue = b""
         self.cookercfg = None
         self.databuilder = None
         self.data = None
@@ -325,12 +341,12 @@
                 except (OSError, IOError):
                     pass
             if len(self.queue):
-                self.handle_item("cookerconfig", self.handle_cookercfg)
-                self.handle_item("workerdata", self.handle_workerdata)
-                self.handle_item("runtask", self.handle_runtask)
-                self.handle_item("finishnow", self.handle_finishnow)
-                self.handle_item("ping", self.handle_ping)
-                self.handle_item("quit", self.handle_quit)
+                self.handle_item(b"cookerconfig", self.handle_cookercfg)
+                self.handle_item(b"workerdata", self.handle_workerdata)
+                self.handle_item(b"runtask", self.handle_runtask)
+                self.handle_item(b"finishnow", self.handle_finishnow)
+                self.handle_item(b"ping", self.handle_ping)
+                self.handle_item(b"quit", self.handle_quit)
 
             for pipe in self.build_pipes:
                 self.build_pipes[pipe].read()
@@ -340,12 +356,12 @@
 
 
     def handle_item(self, item, func):
-        if self.queue.startswith("<" + item + ">"):
-            index = self.queue.find("</" + item + ">")
+        if self.queue.startswith(b"<" + item + b">"):
+            index = self.queue.find(b"</" + item + b">")
             while index != -1:
                 func(self.queue[(len(item) + 2):index])
                 self.queue = self.queue[(index + len(item) + 3):]
-                index = self.queue.find("</" + item + ">")
+                index = self.queue.find(b"</" + item + b">")
 
     def handle_cookercfg(self, data):
         self.cookercfg = pickle.loads(data)
@@ -359,12 +375,13 @@
         bb.msg.loggerDefaultVerbose = self.workerdata["logdefaultverbose"]
         bb.msg.loggerVerboseLogs = self.workerdata["logdefaultverboselogs"]
         bb.msg.loggerDefaultDomains = self.workerdata["logdefaultdomain"]
-        self.data.setVar("PRSERV_HOST", self.workerdata["prhost"])
+        for mc in self.databuilder.mcdata:
+            self.databuilder.mcdata[mc].setVar("PRSERV_HOST", self.workerdata["prhost"])
 
     def handle_ping(self, _):
         workerlog_write("Handling ping\n")
 
-        logger.warn("Pong from bitbake-worker!")
+        logger.warning("Pong from bitbake-worker!")
 
     def handle_quit(self, data):
         workerlog_write("Handling quit\n")
@@ -377,7 +394,7 @@
         fn, task, taskname, quieterrors, appends, taskdepdata = pickle.loads(data)
         workerlog_write("Handling runtask %s %s %s\n" % (task, fn, taskname))
 
-        pid, pipein, pipeout = fork_off_task(self.cookercfg, self.data, self.workerdata, fn, task, taskname, appends, taskdepdata, quieterrors)
+        pid, pipein, pipeout = fork_off_task(self.cookercfg, self.data, self.databuilder, self.workerdata, fn, task, taskname, appends, taskdepdata, quieterrors)
 
         self.build_pids[pid] = task
         self.build_pipes[pid] = runQueueWorkerPipe(pipein, pipeout)
@@ -409,12 +426,12 @@
         self.build_pipes[pid].close()
         del self.build_pipes[pid]
 
-        worker_fire_prepickled("<exitcode>" + pickle.dumps((task, status)) + "</exitcode>")
+        worker_fire_prepickled(b"<exitcode>" + pickle.dumps((task, status)) + b"</exitcode>")
 
     def handle_finishnow(self, _):
         if self.build_pids:
             logger.info("Sending SIGTERM to remaining %s tasks", len(self.build_pids))
-            for k, v in self.build_pids.iteritems():
+            for k, v in iter(self.build_pids.items()):
                 try:
                     os.kill(-k, signal.SIGTERM)
                     os.waitpid(-1, 0)
@@ -424,7 +441,7 @@
             self.build_pipes[pipe].read()
 
 try:
-    worker = BitbakeWorker(sys.stdin)
+    worker = BitbakeWorker(os.fdopen(sys.stdin.fileno(), 'rb'))
     if not profiling:
         worker.serve()
     else:
diff --git a/import-layers/yocto-poky/bitbake/bin/bitdoc b/import-layers/yocto-poky/bitbake/bin/bitdoc
index defb3dd..2744678 100755
--- a/import-layers/yocto-poky/bitbake/bin/bitdoc
+++ b/import-layers/yocto-poky/bitbake/bin/bitdoc
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # ex:ts=4:sw=4:sts=4:et
 # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
 #
diff --git a/import-layers/yocto-poky/bitbake/bin/image-writer b/import-layers/yocto-poky/bitbake/bin/image-writer
deleted file mode 100755
index e30ab45..0000000
--- a/import-layers/yocto-poky/bitbake/bin/image-writer
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2012 Wind River Systems, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-import os
-import sys
-sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname( \
-                                    os.path.abspath(__file__))), 'lib'))
-try:
-    import bb
-except RuntimeError as exc:
-    sys.exit(str(exc))
-
-import gtk
-import optparse
-import pygtk
-
-from bb.ui.crumbs.hobwidget import HobAltButton, HobButton
-from bb.ui.crumbs.hig.crumbsmessagedialog import CrumbsMessageDialog
-from bb.ui.crumbs.hig.deployimagedialog import DeployImageDialog
-from bb.ui.crumbs.hig.imageselectiondialog import ImageSelectionDialog
-
-# I put all the fs bitbake supported here. Need more test.
-DEPLOYABLE_IMAGE_TYPES = ["jffs2", "cramfs", "ext2", "ext3", "ext4", "btrfs", "squashfs", "ubi", "vmdk"]
-Title = "USB Image Writer"
-
-class DeployWindow(gtk.Window):
-    def __init__(self, image_path=''):
-        super(DeployWindow, self).__init__()
-
-        if len(image_path) > 0:
-            valid = True
-            if not os.path.exists(image_path):
-                valid = False
-                lbl = "<b>Invalid image file path: %s.</b>\nPress <b>Select Image</b> to select an image." % image_path
-            else:
-                image_path = os.path.abspath(image_path)
-                extend_name = os.path.splitext(image_path)[1][1:]
-                if extend_name not in DEPLOYABLE_IMAGE_TYPES:
-                    valid = False
-                    lbl = "<b>Undeployable imge type: %s</b>\nPress <b>Select Image</b> to select an image." % extend_name
-
-            if not valid:
-                image_path = ''
-                crumbs_dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
-                button = crumbs_dialog.add_button("Close", gtk.RESPONSE_OK)
-                HobButton.style_button(button)
-                crumbs_dialog.run()
-                crumbs_dialog.destroy()
-
-        self.deploy_dialog = DeployImageDialog(Title, image_path, self,
-                                        gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT
-                                        | gtk.DIALOG_NO_SEPARATOR, None, standalone=True)
-        close_button = self.deploy_dialog.add_button("Close", gtk.RESPONSE_NO)
-        HobAltButton.style_button(close_button)
-        close_button.connect('clicked', gtk.main_quit)
-
-        write_button = self.deploy_dialog.add_button("Write USB image", gtk.RESPONSE_YES)
-        HobAltButton.style_button(write_button)
-
-        self.deploy_dialog.connect('select_image_clicked', self.select_image_clicked_cb)
-        self.deploy_dialog.connect('destroy', gtk.main_quit)
-        response = self.deploy_dialog.show()
-
-    def select_image_clicked_cb(self, dialog):
-        cwd = os.getcwd()
-        dialog = ImageSelectionDialog(cwd, DEPLOYABLE_IMAGE_TYPES, Title, self, gtk.FILE_CHOOSER_ACTION_SAVE )
-        button = dialog.add_button("Cancel", gtk.RESPONSE_NO)
-        HobAltButton.style_button(button)
-        button = dialog.add_button("Open", gtk.RESPONSE_YES)
-        HobAltButton.style_button(button)
-        response = dialog.run()
-
-        if response == gtk.RESPONSE_YES:
-            if not dialog.image_names:
-                lbl = "<b>No selections made</b>\nClicked the radio button to select a image."
-                crumbs_dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
-                button = crumbs_dialog.add_button("Close", gtk.RESPONSE_OK)
-                HobButton.style_button(button)
-                crumbs_dialog.run()
-                crumbs_dialog.destroy()
-                dialog.destroy()
-                return
-
-            # get the full path of image
-            image_path = os.path.join(dialog.image_folder, dialog.image_names[0])
-            self.deploy_dialog.set_image_text_buffer(image_path)
-            self.deploy_dialog.set_image_path(image_path)
-
-        dialog.destroy()
-
-def main():
-    parser = optparse.OptionParser(
-                usage = """%prog [-h] [image_file]
-
-%prog writes bootable images to USB devices. You can
-provide the image file on the command line or select it using the GUI.""")
-
-    options, args = parser.parse_args(sys.argv)
-    image_file = args[1] if len(args) > 1 else ''
-    dw = DeployWindow(image_file)
-
-if __name__ == '__main__':
-    try:
-        main()
-        gtk.main()
-    except Exception:
-        import traceback
-        traceback.print_exc()
diff --git a/import-layers/yocto-poky/bitbake/bin/toaster b/import-layers/yocto-poky/bitbake/bin/toaster
index 70c66d2..f92d38e 100755
--- a/import-layers/yocto-poky/bitbake/bin/toaster
+++ b/import-layers/yocto-poky/bitbake/bin/toaster
@@ -17,10 +17,12 @@
 # You should have received a copy of the GNU General Public License
 # along with this program. If not, see http://www.gnu.org/licenses/.
 
-# Usage: source toaster [start|stop]
-#                       [webport=<port>] [noui] [noweb]
-
-# Helper function to kill a background toaster development server
+HELP="
+Usage: source toaster start|stop [webport=<address:port>] [noweb]
+    Optional arguments:
+        [noweb] Setup the environment for building with toaster but don't start the development server
+        [webport] Set the development server (default: localhost:8000)
+"
 
 webserverKillAll()
 {
@@ -31,9 +33,6 @@
             while kill -0 $pid 2>/dev/null; do
                 kill -SIGTERM -$pid 2>/dev/null
                 sleep 1
-                # Kill processes if they are still running - may happen
-                # in interactive shells
-                ps fux | grep "python.*manage.py runserver" | awk '{print $2}' | xargs kill
             done
             rm  ${pidfile}
         fi
@@ -57,7 +56,8 @@
         echo "Failed migrations, aborting system start" 1>&2
         return $retval
     fi
-
+    # Make sure that checksettings can pick up any value for TEMPLATECONF
+    export TEMPLATECONF
     $MANAGE checksettings --traceback || retval=1
 
     if [ $retval -eq 1 ]; then
@@ -67,7 +67,7 @@
 
     echo "Starting webserver..."
 
-    $MANAGE runserver "0.0.0.0:$WEB_PORT" \
+    $MANAGE runserver "$ADDR_PORT" \
            </dev/null >>${BUILDDIR}/toaster_web.log 2>&1 \
            & echo $! >${BUILDDIR}/.toastermain.pid
 
@@ -77,7 +77,8 @@
         retval=1
         rm "${BUILDDIR}/.toastermain.pid"
     else
-        echo "Webserver address:  http://0.0.0.0:$WEB_PORT/"
+        echo "Toaster development webserver started at http://$ADDR_PORT"
+        echo -e "\nYou can now run 'bitbake <target>' on the command line and monitor your build in Toaster.\nYou can also use a Toaster project to configure and run a build.\n"
     fi
 
     return $retval
@@ -91,14 +92,8 @@
     # prevent reentry
     if [ $INSTOPSYSTEM -eq 1 ]; then return; fi
     INSTOPSYSTEM=1
-    if [ -f ${BUILDDIR}/.toasterui.pid ]; then
-        kill `cat ${BUILDDIR}/.toasterui.pid` 2>/dev/null
-        rm ${BUILDDIR}/.toasterui.pid
-    fi
     webserverKillAll
     # unset exported variables
-    unset DATABASE_URL
-    unset TOASTER_CONF
     unset TOASTER_DIR
     unset BITBAKE_UI
     unset BBBASEDIR
@@ -109,11 +104,11 @@
 
 verify_prereq() {
     # Verify Django version
-    reqfile=$(python -c "import os; print os.path.realpath('$BBBASEDIR/toaster-requirements.txt')")
+    reqfile=$(python3 -c "import os; print(os.path.realpath('$BBBASEDIR/toaster-requirements.txt'))")
     exp='s/Django\([><=]\+\)\([^,]\+\),\([><=]\+\)\(.\+\)/'
     exp=$exp'import sys,django;version=django.get_version().split(".");'
     exp=$exp'sys.exit(not (version \1 "\2".split(".") and version \3 "\4".split(".")))/p'
-    if ! sed -n "$exp" $reqfile | python - ; then
+    if ! sed -n "$exp" $reqfile | python3 - ; then
         req=`grep ^Django $reqfile`
         echo "This program needs $req"
         echo "Please install with pip install -r $reqfile"
@@ -133,8 +128,8 @@
 fi
 
 export BBBASEDIR=`dirname $TOASTER`/..
-MANAGE=$BBBASEDIR/lib/toaster/manage.py
-OEROOT=`dirname $TOASTER`/../..
+MANAGE="python3 $BBBASEDIR/lib/toaster/manage.py"
+OE_ROOT=`dirname $TOASTER`/../..
 
 # this is the configuraton file we are using for toaster
 # we are using the same logic that oe-setup-builddir uses
@@ -144,29 +139,17 @@
 # in the local layers that currently make using an arbitrary
 # toasterconf.json difficult.
 
-. $OEROOT/.templateconf
+. $OE_ROOT/.templateconf
 if [ -n "$TEMPLATECONF" ]; then
     if [ ! -d "$TEMPLATECONF" ]; then
         # Allow TEMPLATECONF=meta-xyz/conf as a shortcut
-        if [ -d "$OEROOT/$TEMPLATECONF" ]; then
-            TEMPLATECONF="$OEROOT/$TEMPLATECONF"
-        fi
-        if [ ! -d "$TEMPLATECONF" ]; then
-            echo >&2 "Error: '$TEMPLATECONF' must be a directory containing toasterconf.json"
-            return 1
+        if [ -d "$OE_ROOT/$TEMPLATECONF" ]; then
+            TEMPLATECONF="$OE_ROOT/$TEMPLATECONF"
         fi
     fi
 fi
 
-if [ "$TOASTER_CONF" = "" ]; then
-    TOASTER_CONF="$TEMPLATECONF/toasterconf.json"
-    export TOASTER_CONF=$(python -c "import os; print os.path.realpath('$TOASTER_CONF')")
-fi
-
-if [ ! -f $TOASTER_CONF ]; then
-    echo "$TOASTER_CONF configuration file not found. Set TOASTER_CONF to specify file or fix .templateconf"
-    return 1
-fi
+unset OE_ROOT
 
 # this defines the dir toaster will use for
 # 1) clones of layers (in _toaster_clones )
@@ -178,7 +161,7 @@
 export TOASTER_DIR=`pwd`
 
 WEBSERVER=1
-WEB_PORT="8000"
+ADDR_PORT="localhost:8000"
 unset CMD
 for param in $*; do
     case $param in
@@ -192,7 +175,24 @@
             CMD=$param
     ;;
     webport=*)
-            WEB_PORT="${param#*=}"
+            ADDR_PORT="${param#*=}"
+            # Split the addr:port string
+            ADDR=`echo $ADDR_PORT | cut -f 1 -d ':'`
+            PORT=`echo $ADDR_PORT | cut -f 2 -d ':'`
+            # If only a port has been speified then set address to localhost.
+            if [ $ADDR = $PORT ] ; then
+                ADDR_PORT="localhost:$PORT"
+            fi
+    ;;
+    --help)
+            echo "$HELP"
+            return 0
+    ;;
+    *)
+            echo "$HELP"
+            return 1
+    ;;
+
     esac
 done
 
@@ -226,11 +226,9 @@
 	return 1
 fi
 elif [ "$CMD" = "" ]; then
-    if [ -z "$BBSERVER" ]; then
-        CMD="start"
-    else
-        CMD="stop"
-    fi
+    echo "No command specified"
+    echo "$HELP"
+    return 1
 fi
 
 echo "The system will $CMD."
@@ -241,15 +239,9 @@
     start )
         # check if addr:port is not in use
         if [ "$CMD" == 'start' ]; then
-             $MANAGE checksocket "0.0.0.0:$WEB_PORT" || return 1
-        fi
-
-        # kill Toaster web server if it's alive
-        if [ -e $BUILDDIR/.toastermain.pid ] && kill -0 `cat $BUILDDIR/.toastermain.pid`; then
-            echo "Warning: bitbake appears to be dead, but the Toaster web server is running." 1>&2
-            echo " Something fishy is going on." 1>&2
-            echo "Cleaning up the web server to start from a clean slate."
-            webserverKillAll
+            if [ $WEBSERVER -gt 0 ]; then
+                $MANAGE checksocket "$ADDR_PORT" || return 1
+            fi
         fi
 
         # Create configuration file
@@ -262,7 +254,6 @@
             return 4
         fi
         export BITBAKE_UI='toasterui'
-        export DATABASE_URL=`$MANAGE get-dburl`
         $MANAGE runbuilds & echo $! >${BUILDDIR}/.runbuilds.pid
         # set fail safe stop system on terminal exit
         trap stop_system SIGHUP
diff --git a/import-layers/yocto-poky/bitbake/bin/toaster-eventreplay b/import-layers/yocto-poky/bitbake/bin/toaster-eventreplay
index 615a7ae..80967a0 100755
--- a/import-layers/yocto-poky/bitbake/bin/toaster-eventreplay
+++ b/import-layers/yocto-poky/bitbake/bin/toaster-eventreplay
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # ex:ts=4:sw=4:sts=4:et
 # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
 #
@@ -21,154 +21,106 @@
 # with this program; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
+"""
+This command takes a filename as a single parameter. The filename is read
+as a build eventlog, and the ToasterUI is used to process events in the file
+and log data in the database
+"""
 
-# This command takes a filename as a single parameter. The filename is read
-# as a build eventlog, and the ToasterUI is used to process events in the file
-# and log data in the database
-
-from __future__ import print_function
 import os
-import sys, logging
+import sys
+import json
+import pickle
+import codecs
+
+from collections import namedtuple
 
 # mangle syspath to allow easy import of modules
-sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
-                                'lib'))
-
+from os.path import join, dirname, abspath
+sys.path.insert(0, join(dirname(dirname(abspath(__file__))), 'lib'))
 
 import bb.cooker
 from bb.ui import toasterui
-import sys
-import logging
 
-import json, pickle
+class EventPlayer:
+    """Emulate a connection to a bitbake server."""
 
+    def __init__(self, eventfile, variables):
+        self.eventfile = eventfile
+        self.variables = variables
+        self.eventmask = []
 
-class FileReadEventsServerConnection():
-    """  Emulates a connection to a bitbake server that feeds
-        events coming actually read from a saved log file.
-    """
+    def waitEvent(self, _timeout):
+        """Read event from the file."""
+        line = self.eventfile.readline().strip()
+        if not line:
+            return
+        try:
+            event_str = json.loads(line)['vars'].encode('utf-8')
+            event = pickle.loads(codecs.decode(event_str, 'base64'))
+            event_name = "%s.%s" % (event.__module__, event.__class__.__name__)
+            if event_name not in self.eventmask:
+                return
+            return event
+        except ValueError as err:
+            print("Failed loading ", line)
+            raise err
 
-    class MockConnection():
-        """ fill-in for the proxy to the server. we just return generic data
+    def runCommand(self, command_line):
+        """Emulate running a command on the server."""
+        name = command_line[0]
+
+        if name == "getVariable":
+            var_name = command_line[1]
+            variable = self.variables.get(var_name)
+            if variable:
+                return variable['v'], None
+            return None, "Missing variable %s" % var_name
+
+        elif name == "getAllKeysWithFlags":
+            dump = {}
+            flaglist = command_line[1]
+            for key, val in self.variables.items():
+                try:
+                    if not key.startswith("__"):
+                        dump[key] = {
+                            'v': val['v'],
+                            'history' : val['history'],
+                        }
+                        for flag in flaglist:
+                            dump[key][flag] = val[flag]
+                except Exception as err:
+                    print(err)
+            return (dump, None)
+
+        elif name == 'setEventMask':
+            self.eventmask = command_line[-1]
+            return True, None
+
+        else:
+            raise Exception("Command %s not implemented" % command_line[0])
+
+    def getEventHandle(self):
         """
-        def __init__(self, sc):
-            self._sc = sc
+        This method is called by toasterui.
+        The return value is passed to self.runCommand but not used there.
+        """
+        pass
 
-        def runCommand(self, commandArray):
-            """ emulates running a command on the server; only read-only commands are accepted """
-            command_name = commandArray[0]
+def main(argv):
+    with open(argv[-1]) as eventfile:
+        # load variables from the first line
+        variables = json.loads(eventfile.readline().strip())['allvariables']
 
-            if command_name == "getVariable":
-                if commandArray[1] in self._sc._variables:
-                    return (self._sc._variables[commandArray[1]]['v'], None)
-                return (None, "Missing variable")
+        params = namedtuple('ConfigParams', ['observe_only'])(True)
+        player = EventPlayer(eventfile, variables)
 
-            elif command_name == "getAllKeysWithFlags":
-                dump = {}
-                flaglist = commandArray[1]
-                for k in self._sc._variables.keys():
-                    try:
-                        if not k.startswith("__"):
-                            v = self._sc._variables[k]['v']
-                            dump[k] = {
-                                'v' : v ,
-                                'history' : self._sc._variables[k]['history'],
-                            }
-                            for d in flaglist:
-                                dump[k][d] = self._sc._variables[k][d]
-                    except Exception as e:
-                        print(e)
-                return (dump, None)
-            else:
-                raise Exception("Command %s not implemented" % commandArray[0])
-
-        def terminateServer(self):
-            """ do not do anything """
-            pass
-
-
-
-    class EventReader():
-        def __init__(self, sc):
-            self._sc = sc
-            self.firstraise = 0
-
-        def _create_event(self, line):
-            def _import_class(name):
-                assert len(name) > 0
-                assert "." in name, name
-
-                components = name.strip().split(".")
-                modulename = ".".join(components[:-1])
-                moduleklass = components[-1]
-
-                module = __import__(modulename, fromlist=[str(moduleklass)])
-                return getattr(module, moduleklass)
-
-            # we build a toaster event out of current event log line
-            try:
-                event_data = json.loads(line.strip())
-                event_class = _import_class(event_data['class'])
-                event_object = pickle.loads(json.loads(event_data['vars']))
-            except ValueError as e:
-                print("Failed loading ", line)
-                raise e
-
-            if not isinstance(event_object, event_class):
-                raise Exception("Error loading objects %s class %s ", event_object, event_class)
-
-            return event_object
-
-        def waitEvent(self, timeout):
-
-            nextline = self._sc._eventfile.readline()
-            if len(nextline) == 0:
-                # the build data ended, while toasterui still waits for events.
-                # this happens when the server was abruptly stopped, so we simulate this
-                self.firstraise += 1
-                if self.firstraise == 1:
-                    raise KeyboardInterrupt()
-                else:
-                    return None
-            else:
-                self._sc.lineno += 1
-            return self._create_event(nextline)
-
-
-    def _readVariables(self, variableline):
-        self._variables = json.loads(variableline.strip())['allvariables']
-
-
-    def __init__(self, file_name):
-        self.connection = FileReadEventsServerConnection.MockConnection(self)
-        self._eventfile = open(file_name, "r")
-
-        # we expect to have the variable dump at the start of the file
-        self.lineno = 1
-        self._readVariables(self._eventfile.readline())
-
-        self.events = FileReadEventsServerConnection.EventReader(self)
-
-
-
-
-
-class MockConfigParameters():
-    """ stand-in for cookerdata.ConfigParameters; as we don't really config a cooker, this
-        serves just to supply needed interfaces for the toaster ui to work """
-    def __init__(self):
-        self.observe_only = True            # we can only read files
-
+        return toasterui.main(player, player, params)
 
 # run toaster ui on our mock bitbake class
 if __name__ == "__main__":
-    if len(sys.argv) < 2:
-        print("Usage: %s event.log " % sys.argv[0])
+    if len(sys.argv) != 2:
+        print("Usage: %s <event file>" % os.path.basename(sys.argv[0]))
         sys.exit(1)
 
-    file_name = sys.argv[-1]
-    mock_connection = FileReadEventsServerConnection(file_name)
-    configParams = MockConfigParameters()
-
-    # run the main program and set exit code to the returned value
-    sys.exit(toasterui.main(mock_connection.connection, mock_connection.events, configParams))
+    sys.exit(main(sys.argv))
